Chuyển đến nội dung chính

BÀI 36: GITOPS VỚI ARGOCD VÀ FLUX

GitOps principles: Git là single source of truth. ArgoCD 3.x hub-and-spoke multi-cluster, Flux 2.x decentralized pull-based. CI/CD pipeline với GitHub Actions + ArgoCD/Flux. App of Apps pattern.

🎯 Mục tiêu bài học

Hiểu GitOps principles, cách setup ArgoCD và Flux, sự khác biệt giữa 2 tools, CI/CD pipeline với GitOps, và secrets management trong GitOps workflow.

GitOps with ArgoCD & Flux - Workflow Diagram

1. GitOps Principles (OpenGitOps)

GitOps là phương pháp deploy và operate applications sử dụng Git làm "single source of truth":

  • Declarative: desired state được mô tả dưới dạng code trong Git (Kubernetes manifests)
  • Versioned và Immutable: Git history là audit trail đầy đủ
  • Pulled Automatically: GitOps agent pull changes từ Git, không push từ CI/CD
  • Continuously Reconciled: agent liên tục kiểm tra và sửa drift (ai đó change trực tiếp trong cluster)

Lợi ích: security (cluster không cần credentials của CI/CD), audit trail, rollback đơn giản (git revert), drift detection.

2. ArgoCD 3.x

2.1 Architecture

  • API Server: REST/gRPC API, Web UI, CLI
  • Repo Server: clone và render Kubernetes manifests từ Git
  • Application Controller: watch K8s resources, detect drift, sync

2.2 Cài đặt ArgoCD

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Hoặc với Helm

helm repo add argo https://argoproj.github.io/argo-helm helm install argocd argo/argo-cd -n argocd --create-namespace

Lấy initial admin password

kubectl -n argocd get secret argocd-initial-admin-secret
-o jsonpath="{.data.password}" | base64 -d

Port-forward UI

kubectl port-forward svc/argocd-server -n argocd 8080:443

Mở https://localhost:8080

2.3 Application CRD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/k8s-configs
    targetRevision: main
    path: apps/my-app/overlays/production    # Kustomize overlay
  destination:
    server: https://kubernetes.default.svc  # in-cluster
    namespace: production
  syncPolicy:
    automated:
      prune: true       # xóa resources đã bị xóa khỏi Git
      selfHeal: true    # tự sửa drift
    syncOptions:
    - CreateNamespace=true
    - ServerSideApply=true  # Helm 4 SSA support
  revisionHistoryLimit: 10

2.4 App of Apps Pattern

# Root application quản lý tất cả applications khác
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/myorg/k8s-configs
    path: apps-of-apps/production   # thư mục chứa Application CRDs khác
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

2.5 ApplicationSet — Generate Applications Dynamically

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-addons
  namespace: argocd
spec:
  generators:
  # Tạo Application cho mỗi cluster
  - clusters: {}
  template:
    metadata:
      name: '{{name}}-addons'
    spec:
      project: addons
      source:
        repoURL: https://github.com/myorg/cluster-addons
        path: 'clusters/{{name}}'
        targetRevision: main
      destination:
        server: '{{server}}'
        namespace: kube-system
      syncPolicy:
        automated: {}

3. Flux 2.x

3.1 Flux Architecture

Flux là decentralized GitOps — cluster tự pull từ Git, không có central hub.

  • Source Controller: watch Git repos, Helm repos, OCI artifacts
  • Kustomize Controller: apply Kustomize resources
  • Helm Controller: manage Helm releases via CRDs
  • Notification Controller: send alerts to Slack, Teams, GitHub
  • Image Automation Controller: auto-update image tags trong Git

3.2 Cài đặt Flux

# Cài Flux CLI
curl -s https://fluxcd.io/install.sh | sudo bash

Bootstrap Flux (tạo resources trong cluster và push configs lên GitHub)

flux bootstrap github
--owner=myorg
--repository=fleet-infra
--branch=main
--path=clusters/production
--personal # personal token, hoặc dùng --token-auth

3.3 GitRepository và Kustomization

# GitRepository: define source
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 5m     # check Git mỗi 5 phút
  url: https://github.com/myorg/k8s-configs
  ref:
    branch: main
  secretRef:
    name: github-token
---
# Kustomization: apply từ Git source
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: my-app
  path: ./apps/my-app/overlays/production
  prune: true         # xóa resources đã xóa khỏi Git
  healthChecks:
  - apiVersion: apps/v1
    kind: Deployment
    name: my-app
    namespace: production

3.4 HelmRelease

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: my-app
  namespace: production
spec:
  interval: 1h
  chart:
    spec:
      chart: my-app
      version: "0.2.x"    # semver range, auto-update minor/patch
      sourceRef:
        kind: HelmRepository
        name: my-helm-repo
        namespace: flux-system
  values:
    replicaCount: 3
    image:
      tag: "1.2.3"
  upgrade:
    remediation:
      retries: 3   # retry nếu upgrade fail

4. CI/CD Pipeline với GitOps

# .github/workflows/deploy.yaml
name: Build and Deploy
on:
  push:
    branches: [main]

jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

- name: Build and push image
  run: |
    docker build -t myregistry.io/myapp:${{ github.sha }} .
    docker push myregistry.io/myapp:${{ github.sha }}

- name: Update manifests in GitOps repo
  run: |
    git clone https://myorg:${{ secrets.GITOPS_TOKEN }}@github.com/myorg/k8s-configs
    cd k8s-configs
    # Update image tag
    sed -i "s|tag:.*|tag: ${{ github.sha }}|" apps/my-app/values.yaml
    git config user.email "[email protected]"
    git commit -am "Update my-app to ${{ github.sha }}"
    git push
# ArgoCD/Flux sẽ tự động detect và deploy thay đổi

5. Secrets trong GitOps

Không commit plaintext secrets lên Git. Các giải pháp:

  • Sealed Secrets: encrypt với public key, chỉ controller trong cluster có thể decrypt
  • SOPS: Mozilla SOPS + KMS (AWS KMS, GCP KMS, Azure Key Vault)
  • External Secrets Operator: sync từ external secret stores (recommended)
# Sealed Secrets
kubeseal < my-secret.yaml > my-sealed-secret.yaml
# my-sealed-secret.yaml an toàn để commit lên Git

SOPS với AWS KMS

sops --encrypt --kms arn:aws:kms:us-east-1:123456789012:key/xxx secret.yaml > secret.enc.yaml

Commit secret.enc.yaml

Flux tự động decrypt với SOPS khi apply

6. ArgoCD vs Flux

Feature           ArgoCD 3.x              Flux 2.x
──────────────────────────────────────────────────────────
Architecture      Centralized hub         Decentralized per-cluster
UI                ✅ Web UI               ❌ CLI only (+ Weave GitOps)
Multi-cluster     ✅ Hub-and-spoke        ✅ Pull-based per cluster
Security model    Cluster connects to hub  Cluster only pulls from Git
RBAC              Fine-grained            Basic
Image automation  Argo Image Updater      ✅ Built-in (Image Automation)
Notifications     ✅ argocd-notifications  ✅ Notification Controller
Community         Large, CNCF Graduated   Active, CNCF Graduated
Best for          Centralized ops team    Distributed teams, security-first

Tóm tắt

  • GitOps: Git = single source of truth, pull-based, drift detection
  • ArgoCD: centralized, excellent UI, hub-and-spoke multi-cluster
  • Flux: decentralized, cluster pulls từ Git, image automation built-in
  • App of Apps (ArgoCD): quản lý nhiều apps bằng 1 root app
  • Secrets: không commit plaintext, dùng Sealed Secrets, SOPS, hoặc ESO