0

[Microservices Series] Bài 13: Centralized Configuration – Chấm dứt "ác mộng" quản lý file .env

Quản lý 20 cái microservices đồng nghĩa với việc bạn đang ôm 20 cái file .env rải rác khắp các server. Sẽ ra sao nếu bộ phận Security yêu cầu đổi mật khẩu Database ngay lập tức?

Nếu dùng cách truyền thống, anh em sẽ phải mò vào 20 cái kho lưu trữ code, sửa lại mật khẩu trong từng file .env, commit, push, và ngồi nhìn CI/CD chạy 20 lần để deploy lại toàn bộ hệ thống. Trong quá trình đó, nếu sót một service chưa kịp đổi, nó sẽ gọi vào Database với mật khẩu cũ và bị văng lỗi kết nối, kéo theo hàng loạt giao dịch thất bại.

Đó là lúc chúng ta phải từ bỏ file .env cục bộ và chuyển sang Centralized Configuration (Cấu hình tập trung).

1. Cấu hình tập trung là gì?

Thay vì nhét cấu hình (Database URL, Redis port, API Key đối tác, v.v.) vào file text đặt trên ổ cứng của từng container, chúng ta gom tất cả bỏ vào một Máy chủ cấu hình (Configuration Server) duy nhất.

Các công cụ "quốc dân" cho việc này thường là HashiCorp Consul, etcd, hoặc chuyên biệt cho bảo mật như HashiCorp Vault.

Nguyên lý hoạt động rất đơn giản:

  1. Khi container của Service Bán Vé vừa khởi động lên, nó chưa hề biết mật khẩu DB là gì.

  2. Việc đầu tiên nó làm là gọi một API tới Máy chủ cấu hình.

  3. Máy chủ cấu hình kiểm tra quyền, sau đó trả về cục JSON chứa toàn bộ thông số cấu hình dành riêng cho Service Bán Vé.

  4. Service nạp cấu hình đó vào RAM và bắt đầu chạy bình thường.

2. Siêu năng lực: Live Reload (Đổi cấu hình không cần restart)

Điểm "ăn tiền" nhất của Cấu hình tập trung không chỉ là gom về một chỗ, mà là khả năng thay đổi cấu hình "nóng".

Giả sử hệ thống đang có một biến DISCOUNT_RATE = 10%. Đột nhiên sếp yêu cầu tăng lên 20% ngay lập tức.

  • Với Monolith/File .env cũ: Bạn sửa file, sau đó bắt buộc phải restart ứng dụng hoặc web server để nó đọc lại file.

  • Với Centralized Config: Bạn mở giao diện UI của Consul lên, sửa giá trị thành 20%. Consul lập tức bắn một event xuống tất cả các container đang chạy. Ứng dụng của bạn (đặc biệt là các service viết bằng Go) sẽ tự động lắng nghe thay đổi và cập nhật biến này trong RAM ngay tắp lự. Giá trị mới được áp dụng cho request tiếp theo mà không một container nào bị rớt mạng hay phải khởi động lại.

3. Thực chiến tại hệ thống AFC (Metro Line 1)

Trong hệ thống thu phí tự động (AFC), mình chia cấu hình làm 2 loại cực kỳ rõ rệt để trị:

  • Cấu hình phi nhạy cảm (Non-sensitive): URL của các service nội bộ, cờ bật tắt tính năng (Feature Toggle), thời gian chờ timeout. Mình ném tất cả vào Consul. Quản trị viên hệ thống có thể vào xem và tinh chỉnh cấu hình vận hành theo thời gian thực.

  • Cấu hình nhạy cảm (Secrets): Mật khẩu Database, Private Key mã hóa Token, API Key kết nối cổng thanh toán. Mình tuyệt đối không để ở file text hay Consul, mà ném vào HashiCorp Vault.

  • Luồng hoạt động: Khi Service Wallet (viết bằng Go hoặc C++) boot lên, nó xin Vault mật khẩu Database. Thay vì cấp một mật khẩu cố định, Vault tự động sinh ra một mật khẩu DB động (Dynamic Secrets) chỉ có hạn sử dụng 1 tiếng, rồi cấp cho Wallet. Sau 1 tiếng, mật khẩu đó tự hủy trên PostgreSQL và sinh mật khẩu mới. Dù hacker có chui được vào server lấy được cấu hình thì 1 tiếng sau cũng phế võ công.

Lời khuyên "xương máu"

  • Tránh "Điểm chết tập trung" (Single Point of Failure): Chết một vài service nghiệp vụ thì hệ thống chạy chậm, nhưng chết Máy chủ cấu hình là toàn bộ hệ thống lúc scale up sẽ không container nào boot lên được vì không biết kết nối DB vào đâu. Phải luôn cài đặt Consul/Vault ở chế độ Cluster (như 3 hoặc 5 node chạy song song).

  • Cơ chế Fallback (Dự phòng): Luôn code thêm một đoạn logic bảo vệ: Nếu gọi lên Consul bị timeout do nghẽn mạng, ứng dụng hãy tự động lấy cấu hình cache từ một file .env.backup được mã hóa lưu tạm trên ổ đĩa nội bộ, hoặc dùng lại cấu hình cũ đang lưu trong RAM để tiếp tục sống sót.

Từ bỏ .env để lên Cấu hình tập trung là bước trưởng thành bắt buộc khi kiến trúc của bạn phình to.

Đến đây, hệ thống của chúng ta đã khá "cứng cựa": deploy tự động, giao tiếp mượt mà, cấu hình bảo mật. Nhưng lỡ 3 giờ sáng, RAM server bất ngờ bị tràn do một vòng lặp vô hạn, làm sao chúng ta biết trước khi hành khách xếp hàng dài ở nhà ga báo lỗi?

Ở bài tiếp theo (Bài 14), chúng ta sẽ bàn về Monitoring & Alerting – Xây dựng hệ thống "gọi điện dựng đầu" DevOps lúc nửa đêm (Prometheus & Grafana).

Dự án anh em đang dùng file .env thuần hay đã chuyển lên các hệ thống quản lý cấu hình rồi? Đã bao giờ anh em lỡ tay commit file .env chứa mật khẩu Production lên Github chưa? Cùng thú tội dưới phần comment nhé!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí