Hôm nay chia sẻ một phần kiến thức cũng rất cơ bản mà anh em làm kubernetes hay gặp vì nó rất đơn giản đó chính là khi sửa ConfigMap/Secret, apply lên cluster, dashboard báo updated, nhưng app thì y hệt như version cũ.
Và lúc đó rất đơn giản anh em sẽ restart deployment/pod: Restart pod thủ công => Đã chạy đúng cấu hình mới. Lúc này nếu không hiểu cơ chế thì câu nói bạn có thể nghe là “Kubernetes lúc đó lag thôi”

Đây không phải bug. Đây là anti-pattern trong cách hiểu ConfigMap/Secret.
Anti-pattern nằm ở đâu?
Anti-pattern:
Sửa ConfigMap/Secret rồi mặc định rằng pod đang chạy sẽ tự động dùng config mới, đặc biệt khi:
- Mount bằng
subPath - Hoặc application chỉ đọc config lúc startup và giữ trong memory
Hậu quả:
- Production chạy hành vi cũ dù config đã đổi
- “Fix” bằng tay: rollout restart
- Lần sau lại dính y hệt
Vì sao anti-pattern này rất dễ dính?
ConfigMap/Secret là object dynamic, update được. Kubernetes cũng có cơ chế update volume, nên có bạn kỳ vọng sai rằng app sẽ tự nhận config mới.
Thực tế:
- Kubernetes không restart container
- Kubernetes không notify application
- Reload config là trách nhiệm của application
Hai nguyên nhân phổ biến nhất
1. Application không reload config
Dù file config có thay đổi, nếu app:
- đọc config lúc startup
- giữ config trong memory
- không watch file
- không có reload signal hoặc endpoint
app vẫn chạy config cũ cho đến khi container restart.
2. Mount bằng subPath
Nếu mount kiểu:
volumeMounts:
- name: config
mountPath: /app/config.yaml
subPath: config.yaml
Thì Kubernetes bind file tại thời điểm container start. ConfigMap update không cập nhật lại file này.
Đây là behavior đã được document, không phải bug.
Triệu chứng rất quen
- Feature flag ON/OFF không đúng
- Endpoint vẫn trỏ host cũ
- Timeout, retry, credential không đổi
- Pod không restart
- Không có event bất thường
- ConfigMap đã đổi nhưng app vẫn dùng giá trị cũ
Cách chẩn đoán nhanh
Bước 1: Xác nhận ConfigMap/Secret đã đổi
kubectl get configmap my-config -o yaml
kubectl get secret my-secret -o yaml
Bước 2: Kiểm tra file trong pod
kubectl exec -it -- sh
cat /app/config.yaml
- ConfigMap đổi, file không đổi => dính
subPath - File đổi, app không đổi => app không reload
Bước 3: Check manifest
kubectl get deploy -o yaml | grep -n subPath
Quick fix
kubectl rollout restart deploy/
Hoặc patch annotation dummy để trigger rollout.
Cách này OK trong incident, nhưng không phải giải pháp dài hạn.
Fix đúng cách
1. Tránh subPath nếu muốn config auto-update
Mount cả directory:
volumeMounts:
- name: config
mountPath: /app/config
File sẽ nằm tại:
/app/config/config.yaml
2. Rollout tự động khi ConfigMap/Secret đổi
Dùng checksum annotation để gắn config vào Pod template.
Ví dụ (Helm):
metadata:
annotations:
checksum/config: "{{ include (print $.Template.BasePath \"/configmap.yaml\") . | sha256sum }}"
Config đổi => checksum đổi => Pod template đổi => Kubernetes tự rollout.
Đây là giải pháp cân bằng nhất cho đa số team.
3. Live reload
- App watch file
- Nhận SIGHUP
- Reload qua internal endpoint
- Sidecar hoặc reloader pattern
Cần cẩn thận race condition, reload giữa request, memory leak.
Một vài lưu ý
Khi đổi ConfigMap/Secret nên xác nhận đúng là:
- Có dùng
subPathkhông? - App reload runtime hay chỉ đọc lúc startup?
- Có auto-rollout khi config đổi chưa?
- Log có in config version hoặc hash lúc startup không?
- Với Secret rotation, đã có plan restart đồng bộ chưa?
Kết luận
Điều này thì rất cơ bản rồi, sửa config restart pod. Anh em mình vẫn hay làm không có gì to tát cả. Đây mình đào sâu một chút để bạn nào chưa biết thì có thể biến nó thành một quy trình rõ ràng, có chủ đích.







