Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 37 — GitOps — Argo CD & Flux

Đã đọc 0/15 mục · còn khoảng 12 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

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 CDFlux
Giao diệnWeb UI mạnh, trực quanKhông có UI mặc định (cần Weave GitOps)
Mô hìnhApplication CRD, tập trungBộ 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-tenancyMạnh với AppProjectQua Kustomization/namespace
Helm & KustomizeHỗ trợ tốt cả haiHỗ trợ tốt cả hai
Nói ngắn gọn: Argo CD thắng khi bạn cần một dashboard đẹp để cả team (kể cả dev) nhìn thấy trạng thái deploy. Flux thắng khi bạn muốn một hệ thống nhẹ, ghép nối linh hoạt, ưu tiên vận hành hoàn toàn qua Git và CLI.

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 kind hoặc minikube trê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ạy kubectl scale deployment nginx --replicas=1 thủ 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ùng git 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.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi