Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là DevOps engineer tại một công ty fintech ở TP.HCM. 3 giờ chiều thứ Sáu, một bạn dev cần hotfix gấp lên production. Bạn mở terminal, gõ kubectl apply -f deployment.yaml, mọi thứ chạy ổn. Nhưng đến thứ Hai, một đồng nghiệp khác lại chạy kubectl edit để chỉnh một tham số. Rồi có người khác nữa sửa qua Lens. Sau ba tuần, không ai còn biết chính xác cluster đang chạy đúng cấu hình gì. File YAML trong Git nói một đằng, cluster thực tế chạy một nẻo. Khi có sự cố, bạn không thể rollback vì không biết "trạng thái đúng" trông ra sao.
Đây chính là bài toán mà GitOps ra đời để giải quyết. Ở các bài trước, bạn đã học Kubernetes, Helm, và cách deploy thủ công. Nhưng cách deploy đó có ba vấn đề nghiêm trọng: (1) không có nguồn sự thật duy nhất, (2) thao tác thủ công dễ sai và khó audit, (3) khó rollback và khó tái tạo môi trường.
GitOps đảo ngược toàn bộ mô hình vận hành: thay vì con người đẩy (push) thay đổi vào cluster, ta để một controller trong cluster tự kéo (pull) trạng thái mong muốn từ Git và tự động đồng bộ. Git trở thành "bảng thiết kế" duy nhất, còn cluster chỉ là "hình chiếu" của Git. Đây là nền tảng cho cách các đội ngũ hiện đại — từ startup đến ngân hàng — vận hành hạ tầng ở quy mô lớn một cách an toàn và có kiểm soát. Nắm vững GitOps là bước chuyển từ "người bấm lệnh" sang "người thiết kế hệ thống tự vận hành".
Khái niệm cốt lõi
Định nghĩa: Git là source of truth
GitOps là một mô hình vận hành trong đó Git repository là nguồn sự thật duy nhất (single source of truth) cho cả cấu hình hạ tầng lẫn trạng thái ứng dụng. Mọi thứ mô tả "hệ thống nên trông như thế nào" — số lượng replica, image version, config, secret reference, network policy — đều được viết dưới dạng file khai báo (declarative, thường là YAML) và lưu trong Git.
Điểm mấu chốt: bạn không bao giờ thay đổi cluster trực tiếp. Muốn tăng từ 3 lên 5 replica? Bạn sửa file YAML, tạo commit, mở pull request, merge. Một controller sẽ phát hiện thay đổi và tự áp dụng. Cluster luôn "phản chiếu" đúng những gì Git nói.
Bốn nguyên tắc của GitOps (4 principles)
Tổ chức OpenGitOps (thuộc CNCF) định nghĩa GitOps qua bốn nguyên tắc nền tảng:
- Declarative (Khai báo) — Toàn bộ hệ thống được mô tả bằng cách khai báo trạng thái mong muốn, không phải chuỗi lệnh thực thi. Bạn nói "tôi muốn 5 pod", không phải "hãy tạo thêm 2 pod". Kubernetes vốn đã declarative nên rất hợp với GitOps.
- Versioned & Immutable (Có phiên bản & bất biến) — Trạng thái mong muốn được lưu trong một kho có version (Git), nơi mọi thay đổi đều được ghi lại, không thể sửa lịch sử, và có thể rollback về bất kỳ commit nào. Git history chính là audit log của hạ tầng.
- Pulled automatically (Tự động kéo) — Các "software agent" (controller) tự động kéo trạng thái mong muốn từ nguồn. Đây là điểm khác biệt lớn nhất so với CI/CD truyền thống, sẽ nói kỹ bên dưới.
- Continuously reconciled (Đối soát liên tục) — Agent liên tục quan sát trạng thái thực tế của hệ thống và tự động điều chỉnh để nó khớp với trạng thái mong muốn. Nếu ai đó sửa tay trên cluster, agent sẽ phát hiện "drift" và kéo về đúng như Git.
Pull-based vs Push-based — trái tim của GitOps
Trong CI/CD truyền thống (push-based), pipeline chạy trên GitLab CI / GitHub Actions sẽ đẩy thay đổi vào cluster: nó cầm sẵn kubeconfig với quyền admin và gọi kubectl apply. Vấn đề: credential production nằm trong hệ thống CI (rủi ro bảo mật lớn), và pipeline chỉ apply một lần rồi thôi — nếu sau đó cluster bị drift, không ai biết.
Trong GitOps (pull-based), một controller sống bên trong cluster chủ động kéo manifest từ Git về và reconcile. Ưu điểm:
- Bảo mật hơn: Credential cluster không rời khỏi cluster. Hệ thống CI bên ngoài không cần quyền truy cập production.
- Chống drift: Controller reconcile theo chu kỳ (ví dụ mỗi 3 phút), nên mọi thay đổi thủ công sẽ bị "sửa lại" tự động.
- Tự phục hồi (self-healing): Ai đó lỡ xóa một Deployment? Controller phát hiện thiếu và tạo lại ngay.
Vòng lặp Reconciliation
Cơ chế cốt lõi là một vòng lặp: Observe → Diff → Act. Controller quan sát trạng thái thực (actual state) trong cluster, so sánh với trạng thái mong muốn (desired state) trong Git, tính ra khác biệt (diff), rồi hành động để triệt tiêu khác biệt đó. Vòng lặp này chạy mãi mãi, đảm bảo hệ thống luôn hội tụ về đúng những gì Git mô tả.
Argo CD vs Flux — hai công cụ chủ lực
Hai công cụ GitOps phổ biến nhất, đều là dự án CNCF Graduated:
| Tiêu chí | Argo CD | Flux |
|---|---|---|
| Giao diện | Web UI mạnh, trực quan | Không có UI mặc định (cần Weave GitOps) |
| Mô hình | Application CRD, tập trung | Bộ controller nhỏ, mô-đun (GitOps Toolkit) |
| Đối tượng hợp | Đội cần dashboard, quản lý nhiều app | Đội thích CLI, cần tích hợp sâu vào automation |
| Multi-tenancy | Mạnh với AppProject | Qua Kustomization/namespace |
| Helm & Kustomize | Hỗ trợ tốt cả hai | Hỗ trợ tốt cả hai |
Tình huống thực tế
Tình huống 1: Startup e-commerce Việt chống "config drift"
Một startup thương mại điện tử ở Hà Nội (khoảng 25 kỹ sư) chạy 40 microservice trên EKS. Trước đây họ deploy bằng script kubectl apply chạy từ GitLab CI. Vấn đề bùng nổ trong đợt sale 12/12: một kỹ sư SRE trực đêm đã kubectl scale thủ công service thanh toán từ 4 lên 12 replica để chịu tải. Đợt sale qua đi, không ai scale xuống, chi phí EC2 tháng đó vọt thêm khoảng 1.800 USD. Tệ hơn, lần deploy tiếp theo qua CI lại đặt về 4 replica đúng lúc cao điểm khác, gây timeout đơn hàng.
Họ chuyển sang Argo CD. Số replica giờ nằm trong Git. Muốn scale, phải sửa YAML và merge PR — có người review, có lịch sử. Argo CD bật chế độ selfHeal, nên mọi kubectl scale thủ công đều bị kéo về đúng con số trong Git trong vòng 3 phút. Sau ba tháng, họ báo cáo giảm 90% các sự cố "không rõ nguyên nhân cấu hình" và mọi thay đổi production đều truy vết được qua Git blame.
Bài học: GitOps biến "thao tác thủ công vô hình" thành "thay đổi có kiểm soát và audit được". Self-healing loại bỏ config drift tận gốc.
Tình huống 2: Ngân hàng số Đông Nam Á và yêu cầu audit
Một ngân hàng số ở Singapore vận hành trên nền tảng đa cluster, chịu sự giám sát chặt của cơ quan quản lý tài chính (MAS). Yêu cầu compliance: mọi thay đổi lên production phải được duyệt bởi ít nhất hai người và lưu vết bất biến. Với mô hình push-based cũ, họ phải cấp kubeconfig production cho runner CI — auditor đánh giá đây là rủi ro nghiêm trọng vì credential có thể bị rò rỉ.
Họ triển khai Flux với mô hình pull-based. Credential production không còn rời khỏi cluster; Flux agent tự kéo từ Git repo được bảo vệ bằng branch protection (bắt buộc 2 approver). Toàn bộ lịch sử deploy chính là Git commit history — bất biến, ký số (signed commit), đúng chuẩn audit. Khi auditor hỏi "ai đã thay đổi network policy vào ngày X", câu trả lời là một lệnh git log duy nhất.
Bài học: Trong môi trường tuân thủ nghiêm ngặt, mô hình pull-based của GitOps không chỉ tiện — nó là điều kiện bắt buộc để đạt chuẩn bảo mật và audit.
Tình huống 3: Agency đa khách hàng và rollback tức thì
Một agency phần mềm ở Đà Nẵng quản lý hạ tầng cho 8 khách hàng khác nhau. Một lần, họ deploy phiên bản mới của một app du lịch và gây lỗi 500 hàng loạt — nhưng chỉ phát hiện sau 20 phút khi khách phàn nàn. Với quy trình cũ, rollback nghĩa là tìm lại image tag cũ, sửa file, chạy lại pipeline: mất thêm 15 phút căng thẳng.
Với Argo CD, họ chỉ cần vào UI, chọn app, nhấn Rollback về commit trước đó (hoặc chạy git revert rồi để Argo tự sync). Trạng thái production trở về đúng như phiên bản ổn định trong chưa đầy 2 phút. Vì mỗi phiên bản deploy tương ứng một Git commit, "rollback" đơn giản là "trỏ về commit cũ".
Bài học: Khi Git là source of truth, rollback không còn là thao tác đáng sợ — nó chỉ là quay về một điểm trong lịch sử.
Hướng dẫn từng bước
Dưới đây là quy trình thiết lập GitOps cơ bản với Argo CD. Ý tưởng tương tự áp dụng cho Flux.
Bước 1 — Tách repo cấu hình khỏi repo code. Nguyên tắc quan trọng: tạo một Git repo riêng chứa manifest (thường gọi là config repo hoặc deploy repo), tách khỏi repo source code của app. Cấu trúc gợi ý:
gitops-config/
├── apps/
│ └── payment-service/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── environments/
├── staging/
└── production/
Bước 2 — Cài Argo CD vào cluster.
kubectl create namespace argocd
kubectl apply -n argocd -f \
https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Bước 3 — Khai báo một Application. Đây là nơi bạn nói cho Argo CD biết: kéo từ repo nào, đường dẫn nào, deploy vào cluster/namespace nào.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: payment-service
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/cong-ty/gitops-config.git
targetRevision: main
path: apps/payment-service
destination:
server: https://kubernetes.default.svc
namespace: payment
syncPolicy:
automated:
prune: true # tự xóa resource không còn trong Git
selfHeal: true # tự sửa drift khi cluster bị chỉnh tay
Bước 4 — Áp dụng Application và để Argo CD tự làm việc.
kubectl apply -f payment-service-app.yaml
Từ giờ, Argo CD sẽ tự kéo manifest từ Git, so sánh với cluster, và đồng bộ. Bạn có thể mở Web UI để thấy trạng thái Synced / Healthy.
Bước 5 — Thực hiện thay đổi qua Git. Muốn nâng image từ v1.2.0 lên v1.3.0? Sửa deployment.yaml, tạo PR, review, merge. Argo CD phát hiện commit mới và tự sync. Đây chính là "deploy" trong thế giới GitOps — bạn không bao giờ gõ kubectl apply trực tiếp nữa.
Bước 6 — Bật thông báo và giám sát. Cấu hình Argo CD Notifications để gửi cảnh báo về Slack/Telegram khi sync thất bại hoặc app rơi vào trạng thái Degraded.
Lỗi thường gặp & mẹo
Lỗi 1: Vẫn kubectl apply thủ công song song với GitOps. Đây là sai lầm phổ biến nhất. Khi bạn bật selfHeal, thay đổi tay của bạn sẽ bị Argo/Flux kéo về ngay — gây bối rối "sao config của tôi biến mất?". Mẹo: Cam kết kỷ luật "chỉ thay đổi qua Git". Nếu cần can thiệp khẩn cấp, hãy sửa Git trước.
Lỗi 2: Lưu secret dạng plaintext trong Git. Git là source of truth, nhưng tuyệt đối không commit password/token thô vào đó. Mẹo: Dùng Sealed Secrets, SOPS, hoặc tích hợp External Secrets với Vault/KMS (sẽ học ở Bài 40). Chỉ commit phiên bản đã mã hóa.
Lỗi 3: Nhét cả code app và config vào chung một repo. Điều này gây vòng lặp CI vô tận: build tạo commit config, commit config kích hoạt build lại. Mẹo: Tách repo. Pipeline CI build image, rồi cập nhật image tag vào config repo (thường qua Argo CD Image Updater hoặc một bot).
Lỗi 4: Bật prune: true mà không hiểu hậu quả. prune sẽ xóa mọi resource không còn trong Git. Nếu bạn lỡ xóa nhầm một file, nó xóa luôn resource trên production. Mẹo: Bật prune nhưng dùng branch protection và review PR nghiêm túc; cân nhắc prune=false cho môi trường nhạy cảm lúc mới bắt đầu.
Lỗi 5: Quên xử lý drift do controller khác gây ra. HPA (autoscaler) sẽ liên tục thay đổi số replica — nếu bạn cũng khai báo replicas trong Git, Argo và HPA sẽ "đánh nhau". Mẹo: Bỏ trường replicas khỏi manifest khi dùng HPA, hoặc dùng ignoreDifferences để Argo bỏ qua trường đó.
Mẹo vàng: Bắt đầu nhỏ. Đừng chuyển cả 40 service sang GitOps trong một tuần. Chọn một service ít rủi ro, làm cho nhuần, rồi mở rộng dần.
Bài tập thực hành
- Dựng lab cơ bản: Cài
kindhoặcminikubetrên máy, cài Argo CD, và tạo một Git repo (có thể dùng GitHub public) chứa manifest cho một app đơn giản (ví dụ nginx). Khai báo một Application trỏ vào repo đó và quan sát Argo CD tự sync.
- Trải nghiệm self-healing: Sau khi app đã
Synced, chạykubectl scale deployment nginx --replicas=1thủ công. Quan sát Argo CD phát hiện drift và kéo về đúng số replica trong Git. Ghi lại mất bao lâu để reconcile.
- Thực hành rollback: Sửa image tag trong Git sang một phiên bản lỗi (ví dụ tag không tồn tại), merge, để Argo sync và thấy app
Degraded. Sau đó dùnggit revertđể quay lại và quan sát app tự phục hồi.
- So sánh công cụ: Viết một đoạn 200 từ so sánh: nếu công ty bạn có 15 dev không quen CLI nhưng cần nhìn dashboard deploy, bạn chọn Argo CD hay Flux? Vì sao? Nếu công ty ưu tiên automation thuần và tích hợp CI sâu thì sao?
- Suy nghĩ thiết kế: Vẽ sơ đồ cấu trúc repo GitOps cho một hệ thống có 3 môi trường (dev/staging/prod) và 5 service, sao cho tái sử dụng được config chung nhưng vẫn override được cho từng môi trường (gợi ý: Kustomize overlays).
Tóm tắt
GitOps là mô hình vận hành lấy Git làm nguồn sự thật duy nhất cho cả hạ tầng lẫn ứng dụng, dựa trên bốn nguyên tắc: khai báo (declarative), có phiên bản và bất biến (versioned & immutable), tự động kéo (pulled automatically), và đối soát liên tục (continuously reconciled). Khác biệt cốt lõi so với CI/CD truyền thống là mô hình pull-based: một controller sống trong cluster chủ động kéo trạng thái mong muốn từ Git và liên tục reconcile, nhờ đó chống drift, tự phục hồi, và giữ credential production an toàn bên trong cluster.
Hai công cụ chủ lực là Argo CD (mạnh về UI, phù hợp đội cần dashboard trực quan) và Flux (nhẹ, mô-đun, hợp đội ưu tiên CLI và automation sâu). Qua ba tình huống thực tế — từ startup e-commerce chống config drift, ngân hàng số đáp ứng audit, đến agency rollback tức thì — bạn thấy GitOps không chỉ là công cụ mà là một kỷ luật vận hành: mọi thay đổi đi qua Git, được review, được lưu vết, và có thể quay lui. Hãy nhớ nguyên tắc quan trọng nhất: một khi đã theo GitOps, đừng bao giờ chạm tay vào cluster nữa — hãy để Git nói chuyện thay bạn.