Pipeline GitLab đầu tiên ở chỗ khách có thể hỏng dù YAML không sai
Trên bản self-managed, thủ phạm thường là registry chưa bật hoặc runner không được chạy privileged, nên hãy hỏi trước khi viết.
Tóm tắt nhanh
- Pipeline nằm trong .gitlab-ci.yml. Thứ tự các stage quyết định job nào chạy trước, còn rules quyết định pipeline và job có được tạo hay không.
- Trên bản self-managed, registry chỉ tự bật khi dùng tích hợp Let's Encrypt có sẵn. Ngoài trường hợp đó, admin của khách phải tự cấu hình.
- Docker-in-Docker cần privileged mode, nên hãy hỏi đội bảo mật trước khi viết job build image.
Một FDE đến chỗ khách hiếm khi được chọn công cụ CI. Doanh nghiệp đã tự host GitLab thường muốn mọi thứ chạy trong hạ tầng của họ: code, pipeline, image.
Vì thế, kỹ năng đáng giá là đọc nhanh GitLab của khách rồi viết pipeline chạy được ngay trong tuần đầu. Có ba mảnh bạn sẽ đụng vào: file pipeline, runner và registry. Mảnh nào cũng có chỗ hay vướng trên bản self-managed.
Pipeline là một file, nhưng thứ tự mới là điều cốt lõi
Pipeline được khai báo trong .gitlab-ci.yml. Nếu không khai báo stages, GitLab dùng bộ mặc định .pre, build, test, deploy, .post. Thứ tự các mục trong stages quyết định job nào chạy trước.
Có hai tầng điều kiện. workflow:rules quyết định cả pipeline có được tạo ra không, và khi không rule nào đúng thì pipeline không chạy. Rules ở cấp job thì quyết định từng job có được tạo hay không.
Thử hình dung bạn đang deploy một API RAG cho đội dữ liệu của khách. Bạn chỉ muốn pipeline chạy trên nhánh main, test chạy trước, image được build và đẩy lên registry, cuối cùng mới đến deploy:
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "main"
stages: [test, build, deploy]
unit-test:
stage: test
image: python:3.12
script:
- pip install -r requirements.txt
- pytest -q
build-image:
stage: build
image: docker:27.3
services:
- docker:27.3-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- echo "$CI_JOB_TOKEN" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
deploy:
stage: deploy
image: alpine:3.20
script:
- ./deploy.sh "$CI_COMMIT_SHORT_SHA"
Hãy chạy thử trong đầu. Một commit lên nhánh feature/chunking sẽ không tạo pipeline nào, vì rule duy nhất không đúng. Nếu bạn ngồi chờ pipeline xuất hiện mà nó không đến, chỗ đầu tiên cần nhìn là workflow:rules, không phải runner.
Job build dùng các biến có sẵn của GitLab để đăng nhập, thay vì gõ cứng một địa chỉ như gitlab.khach.local:5050. Cổng 5050 chỉ là mặc định khi registry tự bật nhờ tích hợp Let’s Encrypt. Nếu admin của khách tự cấu hình registry, host và cổng rất có thể khác.
Tên image vẫn đi theo mẫu registry/namespace/project, nên nhìn tên là biết image thuộc project nào. Phiên bản image docker được ghim cố định và có bật TLS, đúng như GitLab khuyên khi dùng Docker-in-Docker.
Runner nào sẽ chạy job của bạn?
File YAML tự nó không chạy được gì. Job được thực thi bởi runner, tức các agent chạy ứng dụng GitLab Runner. Phần mềm này mã nguồn mở, cấp phép MIT, phát triển công khai trong project gitlab-org/gitlab-runner.
Runner có ba phạm vi: instance, group và project. Project runner hợp khi một project cần cấu hình, credentials và lớp kiểm soát bảo mật riêng. Với FDE đang xử lý dữ liệu nhạy cảm của khách, đó thường là loại nên xin. Runner tự quản lý hỗ trợ ba executor: Shell, Docker và Kubernetes.
Docker executor chạy mỗi job trong một container riêng, tách biệt với các job khác. Image được pull theo pull policy khai báo trong config.toml, và mặc định là always.
Hãy đếm trên pipeline mẫu. Ba job dùng ba image, cộng thêm service docker:27.3-dind của job build, tức bốn image. Với policy always, mỗi lần push lên main là bốn lượt pull, và con số đó nhân lên nhanh khi cả đội cùng commit. Dependency proxy của GitLab có thể giảm áp lực giới hạn từ Docker Hub.
Khi khối lượng job lớn, Kubernetes executor là lựa chọn đáng cân nhắc, và hai trường hợp công khai cho thấy lý do. CERN chuyển runner từ Docker machine, công cụ đã bị Docker ngừng phát triển, sang Kubernetes và co giãn từ 0 đến 100 pod theo nhu cầu trên hơn 20 node.
SeatGeek thay các runner quy mô cố định chạy trên Nomad bằng Kubernetes executor, mỗi job một pod dùng xong bỏ. Họ chuyển hơn 600 repo, số job chạy đồng thời tăng gấp đôi và thời gian chờ trung bình giảm từ 16 giây xuống 2 giây.
Ba cái bẫy trên bản self-managed
Bẫy đầu tiên là registry. Trên bản cài Omnibus, registry chỉ tự bật ở cổng 5050 khi dùng tích hợp Let’s Encrypt có sẵn. Ngoài trường hợp đó, admin phải tự cấu hình và bật nó lên. Đừng viết job docker push trước khi biết registry đã chạy hay chưa.
Bẫy thứ hai là privileged mode. Job build-image ở trên dùng Docker-in-Docker, và cách này bắt runner chạy ở chế độ privileged. GitLab cảnh báo chế độ này gần như vô hiệu hóa các cơ chế bảo mật của container, khiến host có nguy cơ bị leo thang đặc quyền.
Ở một ngân hàng hay bệnh viện, câu trả lời rất có thể là không. Khi đó job build image phải được thiết kế lại cùng đội hạ tầng của khách, và bạn nên biết điều này trước khi hứa ngày giao hàng.
Bẫy thứ ba là tính năng phụ thuộc vào gói. Bảng so sánh của GitLab ghi một số tính năng, như Dependency Proxy cho Container Registry, Geo và khôi phục sau thảm họa, chỉ có trên các gói Self-Managed. Hãy hỏi khách đang dùng gói gì trước khi dựa vào chúng.
Các Solutions Architect của GitLab cảnh báo rằng tối ưu tài nguyên runner cho một đội có thể chuyển việc vặt lặp lại sang lập trình viên. Câu hỏi họ đề xuất rất đáng mang theo: cách giải quyết này có tạo ra việc lặp lại cho ai không?
Với FDE, câu hỏi này còn nặng ký hơn. Sau khi bạn rời đi, khách là người phải sống chung với pipeline đó.
Nên học gì trước?
Hãy học theo thứ tự bạn sẽ gặp ở chỗ khách. Đầu tiên là cú pháp stages và rules, vì như ví dụ nhánh feature/chunking cho thấy, lỗi “pipeline không chạy” thường bắt đầu từ đây. Sau đó là cách đăng ký một project runner với Docker executor. Cuối cùng là đọc config.toml và đặt tên image theo đúng mẫu của registry.
Khi phỏng vấn cho một vị trí FDE, hãy hỏi thẳng khách của công ty thường tự host công cụ đến mức nào. Câu trả lời cho bạn biết mình sẽ làm việc trong hạ tầng của ai, và cũng cho người phỏng vấn thấy bạn hiểu công việc thật.
Trên CV, một dòng cụ thể có sức nặng hơn danh sách công cụ, chẳng hạn: “viết pipeline GitLab ba stage chạy trên project runner riêng, thống nhất với đội bảo mật của khách về privileged mode trước khi build image”.
Ở chỗ khách, pipeline đầu tiên còn là bài kiểm tra xem bạn có hiểu hạ tầng của họ hay không. Hãy hỏi kỹ về registry, runner và privileged mode trước khi viết dòng YAML đầu tiên.
Bài này có hữu ích không?
Cảm ơn bạn đã góp ý!
11 nguồn
- Runners | GitLab Docs
- CI/CD YAML syntax reference | GitLab Docs
- GitLab container registry administration | GitLab Docs
- GitLab container registry | GitLab Docs
- Docker executor | GitLab Runner docs
- Use Docker-in-Docker | GitLab Docs
- GitLab Runner project (gitlab-org/gitlab-runner)
- Self-Managed Feature Comparison | GitLab
- GitLab Runners and Kubernetes: A Powerful Duo for CI/CD · 2023-12-06
- CI Runner Re-architecture (SeatGeek Chairnerd) · 2024-11-26
- A story of runner scaling | GitLab Blog · 2022-06-29