Config theo 12-factor: một artifact, nhiều môi trường, fail fast Trung cấp
Cần đọc trước
Cụm này trả lời: config đặt ở đâu, nạp và kiểm tra thế nào để một image chạy đúng ở mọi môi trường, và thiếu config thì chết ngay lúc start thay vì chết lúc có request.
Vấn đề
Phần tiêu đề “Vấn đề”Service thanh toán deploy lúc 17h. Pod start, health check 200, traffic vào. 17h20, mọi request refund lỗi 401: PAYMENT_API_SECRET_KEY bị đặt nhầm tên trong Secret, code đọc process.env.PAYMENT_API_SECRET_KEY ?? '' và gửi key rỗng.
Lỗi config không làm process chết. Nó làm process sống và sai. Mục tiêu của cụm: mọi lỗi config thành lỗi lúc khởi động, trước request đầu tiên, với thông báo liệt kê đủ mọi key sai.
Đọc theo thứ tự nào
Phần tiêu đề “Đọc theo thứ tự nào”Đang tải diagram…
Trong cụm này
Phần tiêu đề “Trong cụm này”| Phần | Câu hỏi nó trả lời |
|---|---|
| 12-factor và build once | Config là gì theo 12-factor? Vì sao không build image riêng cho production? |
| Parse và validate env | Viết module config typed thế nào? Key nào được có default? Đặt tên, .env local ra sao? |
| Kubernetes và runtime | ConfigMap/Secret có an toàn không? Sửa config có cần restart? Rotation, feature flag, drift? |
| Lỗi hay gặp | Những dòng code đọc env nào hay gây bug, và sửa thế nào? Kèm checklist production. |
Bảng quyết định: loại cấu hình → để ở đâu
Phần tiêu đề “Bảng quyết định: loại cấu hình → để ở đâu”| Loại giá trị | Ví dụ | Để ở đâu | Vì sao |
|---|---|---|---|
| Hằng số nghiệp vụ, giống nhau mọi môi trường | MAX_ITEMS_PER_ORDER = 50, regex mã đơn |
Code (constant) | Đổi nó là đổi hành vi, cần review và test như code |
| Khác nhau theo môi trường, không bí mật | DATABASE_POOL_MAX, PAYMENT_API_BASE_URL, LOG_LEVEL |
Env var (từ ConfigMap) | Đúng định nghĩa config của 12-factor |
| Bí mật | password DB, API key, signing key | Secret manager → inject thành env var hoặc file | Phân quyền, audit, rotate; xem Secure coding |
| Bật/tắt khi đang chạy, theo user hoặc theo % | checkout mới cho 5% user, kill switch | Feature flag service | Đổi không cần deploy, có targeting và audit |
| Dữ liệu nghiệp vụ do người vận hành sửa | phí ship theo tỉnh, danh sách ngân hàng | Database (có màn hình admin) | Đây là dữ liệu, không phải config; cần lịch sử và quyền sửa |
Quy tắc ngón tay cái:
- Giống nhau ở mọi môi trường → code.
- Đổi theo deploy → config.
- Đổi theo user hoặc theo giờ → flag hoặc dữ liệu.
Khi nào áp dụng, ngoại lệ
Phần tiêu đề “Khi nào áp dụng, ngoại lệ”Áp dụng cho mọi service chạy ở nhiều hơn một môi trường: typed config module, validate lúc start, không default cho secret và URL production.
Ngoại lệ hợp lý:
- Script một lần, CLI nội bộ: đọc
process.envtrực tiếp kèm kiểm tra tối thiểu là đủ. - Config lớn có cấu trúc (rule routing, danh sách tenant): file mount từ ConfigMap hoặc database, vẫn validate lúc load. Env var không hợp với cấu trúc lồng sâu.
- Secret nhạy cảm cao: đọc từ file mount hoặc gọi secret manager trực tiếp thay cho env var. OWASP lưu ý env var có thể bị process khác đọc hoặc lọt vào log, dump.
Tóm tắt
Phần tiêu đề “Tóm tắt”Tự kiểm tra:
- Vì sao build lại image riêng cho production là vi phạm “build once, deploy many”, dù code y hệt?
loadConfigbáo lỗi từng key một thì có hại gì khi deploy?- Sửa ConfigMap mà Pod vẫn chạy giá trị cũ: hai nguyên nhân có thể là gì?
- Rotation webhook secret cần app hỗ trợ điều gì để không có khoảng thời gian chữ ký bị từ chối?
Tiếp theo: 12-factor và build once.