Chào anh em mình là Hiếu. Gần đây mới nảy ra ý tưởng khi theo dõi anh Mạnh lâu là mình sẽ làm các usecase, issue thực tế mà mình gặp phải và cách khắc phục lên devopsedu.vn và đăng tương ứng đăng bài lên group DevOps VietNam để hỏi ý kiến anh em rồi học hỏi thêm các cách fix tối ưu hơn nữa và cập nhật lại bài viết vừa có một nơi lưu trữ tập trung vừa có thể giúp được anh em vì không phải ai cũng có thể trải qua hết các usecase giúp người, giúp ta cả nhà đều vui 😀
Và usecase đầu tiên mình chia sẻ cũng là usecase đầu tiên mình gặp phải khi bắt đầu care sâu hơn hệ thống cách đây cũng khá lâu lúc ý chắc junior+ middle- 😅
Nội dung
Hệ thống CI/CD bị chậm khi chạy pipeline trong môi trường Kubernetes
Bài toán
Mình gặp vấn đề này trên hệ thống CI/CD được thiết lập trên Jenkins và chạy các pipeline trong một cụm Kubernetes. Khi team phát triển tăng số lượng build lên, pipeline CI/CD bắt đầu chậm lại, kéo dài từ 10 phút lên tới 40 phút hoặc hơn.
Biểu hiện
Biểu hiện này là mình thấy ngay và nghiên cứu theo dõi ra được.
- Build job bị pending lâu trên Jenkins
- Pod của job không được tạo kịp hoặc bị stuck ở trạng thái ContainerCreating
- Khi job chạy việc download dependency (Maven, NPM) bị chậm bất thường.
Nguyên nhân
Nguyên nhân thì đến từ kinh nghiệm cá nhân thôi (nếu các bác gặp tương tự có thể trao đổi với em nha)
- Hạn chế tài nguyên: Cluster Kubernetes không đủ tài nguyên để xử lý số lượng build tăng đột biến. Node thiếu CPU và RAM, dẫn đến scheduling bị trì hoãn.
- DNS Slowness: CoreDNS trong cluster bị nghẽn vì quá nhiều request từ các pod, đặc biệt khi mỗi job tải về các dependency từ internet.
- Shared storage bottleneck: Các job lưu trữ build artifact trên một Persistent Volume (PV) được mount từ một NFS, gây ra IOPS contention khi nhiều job truy cập cùng lúc.
Biện pháp
Các giải pháp fix cũng là kinh nghiệm cá nhân nha (update: mình đã thêm các giải pháp dựa trên ý kiến đóng góp của anh em trên group DevOps VietNam ở bài viết: tại đây nha)
- Tăng cường tài nguyên cho cluster: thêm các node vào cluster, thiết lập limit và request tài nguyên chuẩn cho từng job để tránh lãng phí tài nguyên trên cluster
- Tối ưu hóa CoreDNS: Tăng số lượng replica của CoreDNS từ 2 lên 5, sử dụng cache để giảm tải cho CoreDNS bằng cách thêm plugin cache trong config, chuyển đổi một số job để sử dụng IP trực tiếp cho các dependency nội bộ thay vì rely vào DNS.
- Giảm tải shared storage: Chuyển từ NFS sang S3-compatible storage (dùng MinIO) để tăng tốc độ lưu trữ artifact và loại bỏ tình trạng contention IOPS, Đối với job chỉ cần artifact tạm thời, dùng EmptyDir (disk ephemeral) để tăng tốc.
- Tối ưu hóa caching trong pipeline: Thêm caching trên từng stage của pipeline (Maven/NPM cache được lưu trữ trên workspace riêng của Jenkins hoặc trong S3).
Giải pháp của anh em góp ý:
Bác Nguyễn Tuấn Hưng:
Kết quả
Thời gian chạy pipeline giảm từ 40 phút xuống còn 8-10 phút.