Triển khai GitOps Production với ArgoCD, Helm và Kustomize trên Kubernetes: Kiến trúc App-of-Apps, Sync Waves & Drift Remediation

1. Tại sao Mô hình CI Push-Based Truyền thống Gặp Giới hạn Bảo mật và Độ tin cậy trên Kubernetes?

Trong các hệ thống triển khai truyền thống sử dụng mô hình Push-Based CI/CD (như chạy kubectl apply hoặc helm upgrade trực tiếp từ GitHub Actions / GitLab CI Runner), hệ thống CI bắt buộc phải nắm giữ chứng chỉ quản trị cụm Kubernetes (KUBECONFIG với quyền cluster-admin hoặc edit trên nhiều Namespace) và kết nối trực tiếp vào Kubernetes API Server từ mạng bên ngoài. Kiến trúc này tạo ra ba rủi ro vận hành lớn khi mở rộng quy mô như đã phân tích trong Kiến trúc Microservices với Docker & Kubernetes: Hướng dẫn thực chiến từ A-Z:

  1. Rủi ro Lộ Khóa Đặc quyền Cao (Blast Radius): Nếu CI Runner hoặc kho lưu trữ biến môi trường bị xâm nhập, kẻ tấn công có thể chiếm quyền điều khiển trực tiếp toàn bộ cụm Kubernetes Production.
  2. Trôi lệch Cấu hình (Configuration Drift): Khi kỹ sư vận hành thực hiện chỉnh sửa khẩn cấp bằng kubectl edit deployment hoặc kubectl scale trực tiếp trên cụm mà không cập nhật lại Git, trạng thái thực tế trên cụm (Live State) lệch khỏi trạng thái định nghĩa trong mã nguồn (Desired State) mà CI Pipeline hoàn toàn không biết.
  3. Thiếu Khả năng Đồng bộ Liên tục (Continuous Reconciliation): CI Pipeline chỉ chạy khi có sự kiện git push. Nếu một tài nguyên trên cụm bị xóa nhầm ngoài giờ triển khai, hệ thống Push-Based không thể tự động phát hiện và khôi phục.

GitOps với ArgoCD giải quyết triệt để bài toán này bằng cách đảo chiều luồng điều khiển sang mô hình Pull-Based Reconciliation Loop tuân thủ 4 nguyên lý của OpenGitOps (CNCF): Khai báo (Declarative), Phiên bản hóa bất biến (Versioned & Immutable), Tự động kéo (Pulled Automatically) và Đối soát liên tục (Continuously Reconciled).


2. Kiến trúc Nội bộ của ArgoCD và Luồng Đối soát Trạng thái (Reconciliation Loop)

ArgoCD hoạt động như một Kubernetes Controller chạy bên trong cụm (argocd namespace), liên tục so sánh cấu hình маниfest kết xuất từ kho Git/Helm với trạng thái đối tượng thực tế trên Kubernetes API (etcd).

flowchart TD
    subgraph GitRepositories ["1. Nguồn Sự thật Duy nhất: Git &OCI Registries"]
        A["App Source Repo: Mã nguồn + Dockerfile + CI Build"] -- "Cập nhật Image Tag qua PR/Commit" --> B["GitOps Config Repo: Helm Charts + Kustomize Overlays"]
    end

    subgraph ArgoCDControlPlane ["2. Tầng Điều khiển ArgoCD trong Cụm Kubernetes (argocd namespace)"]
        B -- "Webhook / Polling (3 phút)" --> C["argocd-repo-server: Kết xuất Helm Template & Kustomize Build"]
        C -- "Cache Manifest JSON" --> D["argocd-redis: Bộ đệm Trạng thái Kết xuất"]
        D --> E["argocd-application-controller: So sánh Desired State vs Live State"]
        F["argocd-server: API / Web UI / CLI + RBAC & SSO"] --> E
    end

    subgraph TargetWorkloads ["3. Môi trường Đích: Kubernetes Production Namespaces"]
        E -- "Phát hiện OutOfSync / Drift" --> G["Sync Engine: Thực thi PreSync -> Sync Waves -> PostSync"]
        G --> H["Production Workloads: Deployment, Service, HPA, NetworkPolicy"]
        H -- "Báo cáo Health Status" --> E
    end

Ba Thành phần Cốt lõi trong ArgoCD Control Plane:

  • argocd-repo-server: Dịch vụ không trạng thái (Stateless) chịu trách nhiệm sao chép kho Git, chạy helm template hoặc kustomize build để biên dịch cấu hình thành Kubernetes YAML/JSON thuần túy.
  • argocd-application-controller: Bộ điều khiển trung tâm (StatefulSet) giám sát các ứng dụng đang chạy, đối chiếu cây tài nguyên thực tế (Live State) với kết quả từ repo-server (Target State), phát hiện trạng thái Synced hoặc OutOfSync, và kích hoạt luồng đồng bộ theo chính sách (automated.selfHeal, automated.prune).
  • argocd-server: Cung cấp giao diện gRPC/REST API và Web UI tích hợp OIDC/SSO cùng kiểm soát truy cập theo vai trò (RBAC).

sequenceDiagram
    autonumber
    participant CI as GitHub Actions CI Pipeline
    participant Git as GitOps Config Repository
    participant Repo as argocd-repo-server
    participant Ctrl as argocd-application-controller
    participant K8s as Kubernetes API Server (etcd)

    CI->>Git: Commit cập nhật image tag (sha-a1b2c3d) vào overlays/production/kustomization.yaml
    Git->>Ctrl: Gửi Git Webhook thông báo có commit mới trên nhánh main
    Ctrl->>Repo: Yêu cầu kết xuất manifest cho commit mới (Revision sha-a1b2c3d)
    Repo->>Git: git fetch & chạy kustomize build --enable-helm
    Repo-->>Ctrl: Trả về danh sách Kubernetes Manifests chuẩn hóa (Desired State)
    Ctrl->>K8s: Truy vấn trạng thái thực tế của các tài nguyên trên cụm (Live State)
    K8s-->>Ctrl: Trả về cấu hình hiện hành trên cụm
    Ctrl->>Ctrl: Phát hiện trạng thái OutOfSync trên Deployment order-service
    Ctrl->>K8s: Thực thi PreSync Job (Database Migration, wave -1) -> Apply Deployment (wave 0)
    K8s-->>Ctrl: Xác nhận Rollout hoàn tất và Pod đạt trạng thái Healthy


3. Chiến lược Kết hợp Helm và Kustomize: Kiến trúc Chuẩn cho Đa Môi trường (dev, staging, prod)

Trong thực tế vận hành doanh nghiệp, sử dụng đơn lẻ Helm hoặc Kustomize thường bộc lộ hạn chế:

  • Helm rất mạnh khi đóng gói các thành phần hạ tầng của bên thứ ba (như ingress-nginx, cert-manager, prometheus-stack) hoặc biểu mẫu hóa cấu trúc dịch vụ chuẩn, nhưng việc chèn thêm một annotation bảo mật đặc thù hoặc một sidecar container chưa được định nghĩa sẵn trong templates/ của Helm Chart gốc sẽ buộc bạn phải fork toàn bộ Chart.
  • Kustomize lại xuất sắc trong việc áp dụng các bản vá cấu hình theo từng môi trường (Strategic Merge Patch và JSON 6902 Patch) mà không cần sửa đổi biểu mẫu gốc (Last-Mile Customization).

Cấu trúc thư mục GitOps kết hợp cả hai công cụ theo tiêu chuẩn công nghiệp:

infoteck-gitops-config/
├── apps/
│   └── order-service/
│       ├── base/
│       │   ├── Chart.yaml
│       │   ├── values.yaml
│       │   └── templates/
│       │       ├── deployment.yaml
│       │       ├── service.yaml
│       │       └── hpa.yaml
│       └── overlays/
│           ├── staging/
│           │   ├── kustomization.yaml
│           │   └── values-staging.yaml
│           └── production/
│               ├── kustomization.yaml
│               ├── values-production.yaml
│               └── patches/
│                   └── pod-security-context.yaml
└── clusters/
    └── production/
        └── applicationset.yaml

Cấu hình overlays/production/kustomization.yaml Tích hợp helmCharts:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: production-orders

helmCharts:
  - name: order-service
    repo: ""
    version: 1.2.0
    releaseName: order-service
    namespace: production-orders
    valuesFile: values-production.yaml

images:
  - name: ghcr.io/infoteck/order-service
    newTag: "sha-9f8e7d6"

patches:
  - path: patches/pod-security-context.yaml
    target:
      kind: Deployment
      name: order-service

Và bản vá bảo mật patches/pod-security-context.yaml áp đặt tiêu chuẩn bảo mật container mà không cần sửa đổi Helm Chart gốc:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  template:
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 10001
        runAsGroup: 10001
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: order-service
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL


4. Tự động hóa Quy mô lớn với AppProject Phân quyền Chặt chẽ và ApplicationSet

Trên môi trường Production, tuyệt đối không gắn mọi ứng dụng vào project default của ArgoCD. Hãy khởi tạo một AppProject giới hạn chặt chẽ kho Git nguồn, Namespace đích và danh mục tài nguyên cụm được phép tạo:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: core-commerce-prod
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  description: "Dự án GitOps Production cho nhóm dịch vụ Core Commerce"
  sourceRepos:
    - "https://github.com/infoteck-vn/infoteck-gitops-config.git"
  destinations:
    - namespace: "production-*"
      server: "https://kubernetes.default.svc"
  clusterResourceWhitelist: []
  namespaceResourceBlacklist:
    - group: ""
      kind: ResourceQuota
    - group: ""
      kind: LimitRange
  roles:
    - name: commerce-readonly
      description: "Quyền chỉ xem cho kỹ sư phát triển"
      policies:
        - p, proj:core-commerce-prod:commerce-readonly, applications, get, core-commerce-prod/*, allow

Tiếp theo, sử dụng ApplicationSet với Git Directory Generator để ArgoCD tự động phát hiện mọi dịch vụ trong apps/*/overlays/production và khởi tạo Application tương ứng:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: production-microservices
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
    - git:
        repoURL: "https://github.com/infoteck-vn/infoteck-gitops-config.git"
        revision: main
        directories:
          - path: "apps/*/overlays/production"
  template:
    metadata:
      name: "{{index .path.segments 1}}-prod"
      namespace: argocd
    spec:
      project: core-commerce-prod
      source:
        repoURL: "https://github.com/infoteck-vn/infoteck-gitops-config.git"
        targetRevision: main
        path: "{{.path.path}}"
      destination:
        server: "https://kubernetes.default.svc"
        namespace: "production-{{index .path.segments 1}}"
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
          allowEmpty: false
        syncOptions:
          - CreateNamespace=true
          - PrunePropagationPolicy=foreground
          - PruneLast=true
          - ApplyOutOfSyncOnly=true
          - ServerSideApply=true
        retry:
          limit: 3
          backoff:
            duration: 10s
            factor: 2
            maxDuration: 3m


5. Điều phối Thứ tự Triển khai và Database Migration bằng Sync Phases & Sync Waves

Khi triển khai bản cập nhật ứng dụng đi kèm thay đổi lược đồ cơ sở dữ liệu (như thêm chỉ mục hoặc cột mới trên hệ thống Tối ưu hóa hiệu năng MySQL 8.0 cho hệ thống phục vụ triệu người dùng), ArgoCD cung cấp cơ chế Resource Hooks (PreSync, Sync, PostSync, SyncFail) kết hợp Sync Waves (sắp xếp theo giá trị số nguyên tăng dần từ âm sang dương). ArgoCD chỉ chuyển sang Wave tiếp theo khi mọi tài nguyên ở Wave hiện tại đạt trạng thái Healthy:

apiVersion: batch/v1
kind: Job
metadata:
  name: order-db-migration-v120
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
    argocd.argoproj.io/sync-wave: "-1"
spec:
  backoffLimit: 1
  activeDeadlineSeconds: 180
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: ghcr.io/infoteck/order-service:sha-9f8e7d6
          command: ["/app/order-service", "migrate", "up"]
          envFrom:
            - secretRef:
                name: order-db-credentials


6. Kiểm tra Thực nghiệm, Xử lý Sự cố (argocd app diff) và Quy trình Rollback An toàn

Để tích hợp quy trình kiểm chứng GitOps vào Xây dựng CI/CD Pipeline tự động triển khai với GitHub Actions và Docker, kỹ sư SRE sử dụng bộ lệnh CLI dưới đây để kiểm tra trước sự thay đổi (diff) trên Pull Request trước khi gộp nhánh:

# 1. Kiểm tra bản kết xuất Kustomize + Helm cục bộ trước khi commit
kustomize build --enable-helm apps/order-service/overlays/production | kubeconform -strict -summary

# 2. So sánh sự khác biệt giữa nhánh PR hiện tại và trạng thái thực tế đang chạy trên Production
argocd app diff order-service-prod --local apps/order-service/overlays/production

# 3. Theo dõi tiến trình đồng bộ và trạng thái sức khỏe của từng tài nguyên theo thời gian thực
argocd app wait order-service-prod --health --sync --timeout 300

[!WARNING]
Quy tắc Rollback Khi Bật selfHeal: true: Khi automated.selfHeal: true đang kích hoạt trên môi trường Production, lệnh argocd app rollback từ CLI sẽ bị từ chối hoặc bị ghi đè ngay lập tức bởi trạng thái trên nhánh main của kho Git. Để Rollback chuẩn GitOps, hãy thực hiện git revert <commit-sha> trên kho infoteck-gitops-config và đẩy lên nhánh main—ArgoCD sẽ tự động khôi phục phiên bản ổn định trước đó kèm đầy đủ lịch sử kiểm toán Git.


7. Tài liệu Tham khảo & Nguồn Chính thống

  1. ArgoCD Official Documentation — Architectural Overview & Core Concepts: https://argo-cd.readthedocs.io/en/stable/operator-manual/architecture/
  2. ArgoCD Sync Phases and Waves Specification: https://argo-cd.readthedocs.io/en/stable/user-guide/sync-waves/
  3. Kubernetes SIG-CLI — Kustomize helmCharts Generator Documentation: https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/helmcharts/
  4. OpenGitOps CNCF Sandbox Project — GitOps Principles v1.0.0: https://opengitops.dev/