Config Server và Vault: 1 tháng trả nợ tech debt nhiều năm

8 min read 164

Chuẩn hóa cấu hình Config Server và Vault cho service backend

Tháng vừa rồi, team mình hoàn thành go-live lên môi trường PROD cho các service backend đang dùng tiêu chuẩn cấu hình cũ, chuyển sang sử dụng hệ thống Config Server và Vault theo tiêu chuẩn mới. Khá mệt nhưng trộm vía là go-live thành công.

Quá trình từ khi lên giải pháp, kế hoạch đến triển khai cũng gặp không ít khó khăn. Tuy nhiên, cái khó khăn hơn nằm ở quá trình phía sau.

Trong quá trình làm thì mình luôn cần phải giải quyết được câu hỏi lớn là: “Làm thế nào để chuyển đổi cấu hình mà không ảnh hưởng đến bất kỳ nghiệp vụ nào đang chạy“, đồng thời đây là bài toán dành cho kỹ thuật, vậy nên mong muốn rằng QC không cần phải tham gia ở bất kỳ giai đoạn nào của việc chuyển đổi.

Nguyên nhân để thay đổi

Có nhiều lần anh em dev check lỗi nhưng tù mù về thông tin, tù mù về cấu hình của service mình đang làm owner, debug hết sức khó khăn, phụ thuộc vào Devops kiểm tra lấy thông tin cùng.

Pain point trước khi chuẩn hóa: dev debug mù thông tin, go-live copy YAML lẫn lộn

Lúc go-live thì copy cấu hình yaml tùm lum lẫn lộn, khổ cho cả devops, khổ cho cả dev phải chỉ đúng nơi đúng chỗ, phải dò xem devops có copy sai không, có đặt nhầm block không.

Trên Vault thì lưu toàn bộ thông tin của file yaml, dẫn tới việc theo dõi các cấu hình non-sensitive trên môi trường PROD rất khó khăn.

Đỉnh điểm là đợt chuyển đổi môi trường DCN vừa rồi ở công ty mình, khi cần kiểm tra xem những service nào đang cấu hình gì, đang dùng chung database nào, ảnh hưởng ra sao thì thực sự dev không kiểm tra được kỹ càng, vì đội dev có được quản lý cấu hình do mình là owner đâu?

Config Server và Vault trước đây được triển khai như thế nào

Hiện trạng cũ: dev-config và prod-config trước 2024, thêm Vault UAT và Vault PROD lưu full YAML từ nửa cuối 2024

Ở giai đoạn trước năm 2024, thì việc cấu hình bao gồm hai thành phần chính:

  • 1 service dev-config làm nhiệm vụ lưu trữ cấu hình trên môi trường develop và uat, service này các bạn dev làm chủ và tự do push cấu hình.
  • 1 service prod-config làm nhiệm vụ lưu trữ cấu hình trên môi trường prod, service này chỉ có DevOps quản lý.

Tới giai đoạn đầu năm 2024, thì việc cấu hình bổ sung thêm một thành phần mới song song với Config Server phía trên là Vault, tuy nhiên lại dùng sai mục đích:

  • 1 con Vault UAT cấu hình dành cho team dev triển khai trên môi trường develop/uat, anh em dev vẫn làm chủ con Vault này. Tuy nhiên, ở đây lại lưu full cấu hình yaml của backend service.
  • Tương tự, có thêm 1 con Vault Prod để lưu full cấu hình YAML của các service backend trên môi trường prod, con Vault này chỉ có Devops làm chủ.

Việc tồn tại song song cả 4 hệ thống này khiến việc triển khai lên môi trường PROD/STG những lúc cao điểm cực kỳ phức tạp và vất vả, vậy nên team mình tiến hành chuẩn hóa lại rõ ràng phạm vi trách nhiệm của Config Server/Vault.

Việc chuẩn hóa này sẽ làm cơ sở để mở đường cho một chiến dịch mạnh mẽ hơn ở phía sau (mình chưa thể public chiến dịch này).

Tiêu chí bắt buộc của giải pháp

Vấn đề thì quá rõ ràng rồi, vậy giải pháp cho việc này sẽ cần phải triển khai như thế nào?

Để trả lời được câu hỏi này thì lúc thiết kế mình khá đau đầu, sau đó đã đặt ra những tiêu chí bắt buộc mà toàn bộ team sẽ không được phá vỡ, mình tạm gọi là 6 luật cứng.

6 tiêu chí cứng khi tách vai trò Config Server và Vault giữa team dev và DevOps
6 hard constraints
  1. Cấu hình non-sensitive phải được đặt ở Config Server, secret key phải được lưu ở Vault.
  2. Vault tuyệt đối không lưu cấu hình non-sensitive.
  3. Chỉ Devops mới nắm được dữ liệu secret key nhạy cảm trên môi trường PROD/STG, team dev tuyệt đối không được biết.
  4. Dev phải quản lý được cấu hình liên quan đến service mà mình là owner trên toàn bộ các môi trường, nhưng không được phép biết thông tin key nhạy cảm.
  5. Việc chuyển đổi phải diễn ra gọn gàng, dễ dàng, dễ tiếp cận, tránh phát sinh thêm quá nhiều việc cho cả dev, cả lead và devops.
  6. Cần đảm bảo việc quản lý thay đổi cấu hình phải tuân theo Git Flow chuẩn mà team đang triển khai ở các dự án.

Giải pháp: tách vai trò Config Server và Vault

Bên mình dựng mới 1 con service dùng để lưu cấu hình Config Server, sẽ na ná con service cấu hình cũ, tuy nhiên, con mới này có 1 cái đặc biệt là sẽ lưu hết profile của các môi trường: uat, prod, staging vào chung thư mục của từng service, và sẽ được quản lý bằng Git Flow.

Cấu trúc thư mục abc-configurations: mỗi service backend một thư mục chứa profile uat, stg, prod
abc-configurations

Ở trong repo Config Server, mỗi service backend sẽ có một thư mục riêng và chứa đầy đủ cấu hình cho các môi trường uat, stg, prod.

Service backend sẽ kết nối đồng thời tới Config Server và Vault để seed giá trị nhạy cảm từ Vault, kết hợp với Config Server trong quá trình khởi chạy ứng dụng.

Quy trình quản lý thì bên mình dùng Git Flow để đảm bảo chạy được nhiều team, nhiều dự án đồng thời. Các bạn có thể xem qua bài viết này để hiểu tư tưởng áp dụng nhé: Git Flow ở công ty nghìn người sẽ như thế nào.

Khó khăn và thách thức

Khó khăn đầu tiên phải kể đến đó là làm thế nào để team phát triển và team hạ tầng cùng chung góc nhìn, chung cách hiểu, để khi triển khai dễ làm việc nhất. Cái này thì mình và sếp cũng như đội SRE phải họp mấy lần thì mới đả thông được tư tưởng và có cùng quan điểm.

Ba bước migrate cấu hình: thống nhất góc nhìn dev và SRE, migrate cùng verify bằng AI, go-live theo ba wave

Tiếp theo là làm thế nào để chuyển đổi và verify cấu hình nhanh mà không bị sót? Đơn giản thôi, mình áp dụng AI ở toàn bộ các bước:

Bước migrate cấu hình từ service config server cũ (dev-config) sang service config server(abc-configurations) mới, điều chỉnh lại thứ tự trong file cấu hình, bổ sung các placeholder thay thế cho giá trị secret key.

Chạy 9 background agent song song để migrate cấu hình YAML sang Config Server mới

Điều chỉnh xong cấu hình Config Server thì sẽ cần chỉnh lại cấu hình bootstrap trong project để load được cùng lúc cả Config Server và Vault.

Sau khi xong bước kết nối trên uat ngon nghẻ thì mình sẽ tiến hành phối hợp với Devops để lấy cấu hình stagingproduction về để compare ngược với uat, tất nhiên, khi lấy cấu hình về thì Devops đã loại bỏ hết các key nhạy cảm rồi.

Trong quá trình compare, mình spawn hàng chục agent để xử lý cùng lúc, sort lại thứ tự file yaml cho chuẩn Spring Boot, bổ sung placeholder cho các secret key, sau đó agent làm nhiệm vụ team lead sẽ tổng hợp lại cho mình về kết quả compare cuối cùng.

10 agent verify chạy song song để compare cấu hình staging và production với UAT

Compare xong cấu hình thì chuẩn bị làm công tác go-live thôi. Mình chia đợt go-live thành ba giai đoạn: có mỗi giai đoạn đầu là gian nan và cần điều chỉnh nhiều nhất, còn lại hai giai đoạn sau thì đã vào guồng nên việc chuyển cấu hình rất nhanh và không có lỗi lầm gì mấy.

Trong quá trình hỗ trợ anh em trong phòng triển khai thì mình có lập một nhóm nội bộ để share cho anh em các prompt AI mà mình dùng, cấu hình chuẩn cần follow, danh sách các lưu ý và điều kiện cần để nghiệm thu, các bài học kinh nghiệm sau một vài lượt go-live cũng như báo cáo tiến độ hàng tuần để lãnh đạo nắm được tiến độ.

Note: Về chi tiết cách cấu hình, prompt cụ thể, bài học kinh nghiệm thực tế tại mỗi lượt go-live thì nó thuộc phạm vi nội bộ, vậy nên những thông tin này mình không thể chia sẻ với các bạn được.

Kết quả: gần 100 service đã chạy chuẩn cấu hình mới

Ở thời điểm mình viết bài này, hiện tại phòng đã go-live được 97 service chuyển sang sử dụng tiêu chuẩn cấu hình mới, vẫn còn một cơ số service nữa chưa được đưa lên.

Danh sách service backend đã go-live sang tiêu chuẩn cấu hình Config Server và Vault

Toàn bộ các backend service do team mình phụ trách đã hoàn tất việc chuyển sang cấu hình mới trên môi trường PROD. Trong vài ngày tới, team sẽ tiếp tục triển khai cấu hình lên môi trường STG để sẵn sàng phục vụ các hạng mục quan trọng chuẩn bị được đưa vào kiểm thử.

Tháng này coi như đã hoàn thành một nhiệm vụ quan trọng, chuẩn bị chiến tiếp các nhiệm vụ chiến lược khác thôi.

Xem thêm các bài viết nổi bật bên dưới: