Tác giả: Minh Hiếu

Thông tin liên hệ:

Chào anh em mình là Hiếu. Tiếp tục issue thực tế mà mình đã gặp (chia sẻ kiểu này cuốn quá nhiều anh em hưởng ứng học ra nhiều cái hay) mình có đăng trong 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 (intro quen thuộc😀)

Hệ thống CI/CD bị nghẽn toàn bộ do lỗi trong cơ chế pipeline orchestration và quản lý metadata

Bài toán

Hệ thống CI/CD trên nền Kubernetes có khoảng 100 pipelines chạy song song trong giờ cao điểm. Dữ liệu build metadata của từng pipeline được lưu trên một PostgreSQL cluster và mỗi pipeline sử dụng các GitLab Runners trên cluster để build và deploy.

Biểu hiện

  • Các pipelines bị treo khi chạy các stage build Docker image hoặc deploy Helm charts.
  • PostgreSQL gặp deadlock liên tục, CPU load lên đến 90% (Tí ngỏm), không thể xử lý được các truy vấn từ GitLab Runners.
  • Các pods của GitLab Runner bị crashloop do memory leak trong container runtime.
  • API server của Kubernetes bắt đầu timeout khi chạy các lệnh kubectl.

Nguyên nhân

  • Pipeline orchestration overload, các GitLab Runners liên tục ghi metadata build (trạng thái, logs) vào PostgreSQL, gây ra contention cao trên bảng lưu trạng thái pipeline.
  • Metadata bloat, một số pipelines chạy các job với output log lớn (~1GB/job), và toàn bộ dữ liệu được lưu trên PostgreSQL mà không có cơ chế cleanup hiệu quả.
  • Memory leak trong container runtime, Runner containers sử dụng một phiên bản lỗi của containerd, khiến memory không được giải phóng sau khi job kết thúc.
  • Kubernetes control plane bị nghẽn: Số lượng requests từ kubelet (do crashloop) và runners gây quá tải trên API server.

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ách metadata pipeline ra khỏi PostgreSQL, chuyển sang lưu trên Redis với TTL (time-to-live) để giảm tải truy vấn.
  • Dùng cơ chế log aggregation riêng (ELK stack) để lưu logs thay vì lưu logs trong metadata pipeline.
  • Tạo health check script giám sát Runners, tự động xoá và restart nếu memory usage vượt quá threshold.
  • Thay vì lưu metadata ngay lập tức, cấu hình batch writing để PostgreSQL xử lý truy vấn một cách tuần tự thay vì tranh chấp.
  • Dùng tool như kube-burner để test giới hạn control plane, đảm bảo hệ thống chịu được peak load.

Giải pháp của anh em góp ý:

Bác Meme Nguyen

“Mình thấy nguyên nhân chính là do con gitlab server IO bound cao dẫn đến bottleneck impact đến pipeline task runner. Mình thấy gitlab nó có bài gitlab scalability https://docs.gitlab.com/ee/development/scalability.html

Bác Ciscocert Conquer

“Theo kinh nghiệm của mình RDS MySQL, RDS Aurora , Postgre không hiệu quả để sử dụng cho những ứng dụng realtime , cho dù hệ thống lúc nào cũng có Redis cache kè kè chống đỡ .
Nó thường dính đến issues
– Giới hạn database connection, dùng database proxy cũng không cải thiện
– Connection không giải phóng RAM/CPU của những xử lý không tốt từ backend từ đó tải của database cao , hệ thống trì trệ
– Giải pháp của mình cũng tách thành nhiều database để xử lý, tuy nhiên database đọc ghi realtime cũng bị những issue , do phần backend viết không tốt và phải tinh chỉnh, thêm cache phía client side . Hệ thống của mình không nhiều lắm tầm 150-200 ec2, docker trên nền AWS cloud .
KL:
– Đối với những data cần realtime , MongoDB là một lựa chọn phù hợp nhất
– Kiến trúc là vô cùng quan trọng , đối với những hệ thống từ 25k CCU

– Lead dev phải review sát sao những api , chứ giao junior/fresher code thì sau này thế nào cũng dính chưởng.”

Kết quả

  • ostgreSQL CPU giảm từ 90% xuống còn dưới 20% ngay cả trong giờ cao điểm.
  • Thời gian chạy pipeline giảm từ khoảng 30 phút xuống còn khoảng 10 phút nhờ cơ chế batch writing và Redis caching.
  • Crashloop GitLab Runner giảm hoàn toàn.