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

LESSON 28: GITOPS WITH ARGOCD — ARCHITECTURE AND INSTALLATION

Understand GitOps principles, ArgoCD architecture, install ArgoCD HA, configure Git repositories, RBAC, SSO, and compare ArgoCD vs FluxCD.

🔒 DevSecOps — Lesson 28 LESSON 28: GITOPS WITH ARGOCD — ARCHITECTURE AND SETUP

Deploy Microservices On-Premises with Kubernetes HA

Part 7: GitOps with ArgoCD, Helm & Vault

xdev.asia

🎯 LESSON OBJECTIVE__HTMLTAG_68___
  • ✅ Understand GitOps principles and workflow
  • ✅ ArgoCD architecture: components, sync flow
  • ✅ Install ArgoCD HA on Kubernetes__HTMLTAG_75___
  • ✅ Configure Git repositories and SSH keys
  • ✅ RBAC and SSO integration
  • ✅ Compare ArgoCD vs FluxCD

PART 1: GITOPS PRINCIPLES

graph LR
    DEV["👨‍💻 Developer"] -->|"git push"| GIT["📦 Git Repository"]
    GIT -->|"webhook / poll"| ARGO["🔄 ArgoCD"]

    ARGO --> COMPARE["🔍 Compare<br/>Desired vs Live"]
    COMPARE -->|"Out of Sync?"| SYNC["⚡ Auto-sync"]
    SYNC --> K8S["☸ Apply to K8s"]

    style DEV fill:#15803d,stroke:#22c55e,color:#e2e8f0
    style GIT fill:#7c3aed,stroke:#a78bfa,color:#e2e8f0
    style ARGO fill:#1e3a5f,stroke:#3b82f6,color:#e2e8f0
    style COMPARE fill:#0f172a,stroke:#f59e0b,color:#e2e8f0
    style SYNC fill:#0f172a,stroke:#3b82f6,color:#e2e8f0
    style K8S fill:#1e3a5f,stroke:#60a5fa,color:#e2e8f0

GitOps Core Principles:

  1. Declarative: Desired state described in Git
  2. Versioned: Git history = deployment history
  3. Automated: Changes auto-applied (or approved)
  4. Self-healing: Drift detection + auto-correction
FeatureArgoCDFluxCD
ArchitectureCentralized (UI + API)Decentralized (per-cluster)
UIRich Web UICLI only (+ Weave GitOps UI)
Multi-clusterNative (single pane)_Per-cluster agents_
Helm SupportYes (template rendering)Yes (HelmRelease CRD)
KustomizeYesYes (native)
RBACBuilt-in, per-projectK8s RBAC_
SSOOIDC, SAML, LDAPVia K8s auth_
Best ForCentral platform teams_Distributed teams_

PART 2: ARGOCD ARCHITECTURE

graph TB
    subgraph ARGO["🔧 ArgoCD Server"]
        API["🌐 API Server<br/>REST/gRPC + Web UI"]
        REPO["📦 Repo Server<br/>Git clone + render"]
        CTRL["🔄 Application Controller<br/>Reconciliation loop"]

        API --> REDIS["⚡ Redis Cache"]
        REPO --> REDIS
        CTRL --> REDIS

        APPSET["📋 ApplicationSet Controller<br/>Generate Apps from templates"]
        NOTIF["🔔 Notifications Controller<br/>Slack, Email, Webhook"]
    end

    style ARGO fill:#0f172a,stroke:#3b82f6,color:#e2e8f0
    style API fill:#1e3a5f,stroke:#60a5fa,color:#e2e8f0
    style REPO fill:#1e3a5f,stroke:#60a5fa,color:#e2e8f0
    style CTRL fill:#1e3a5f,stroke:#60a5fa,color:#e2e8f0
    style REDIS fill:#dc2626,stroke:#ef4444,color:#e2e8f0
    style APPSET fill:#7c3aed,stroke:#a78bfa,color:#e2e8f0
    style NOTIF fill:#7c3aed,stroke:#a78bfa,color:#e2e8f0

PART 3: INSTALL ARGOCD HA

# Create namespace:
kubectl create namespace argocd

# Install ArgoCD HA:
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

helm install argocd argo/argo-cd \
  --namespace argocd \
  --version 7.3.0 \
  -f argocd-values.yaml

3.1. ArgoCD Values (Production)

# argocd-values.yaml:
global:
  domain: argocd.myapp.com

controller: replicas: 2 resources: requests: cpu: 500m memory: 512Mi limits: cpu: "2" memory: 2Gi

server: replicas: 2 resources: requests: cpu: 200m memory: 256Mi ingress: enabled: true ingressClassName: istio hostname: argocd.myapp.com tls: true

repoServer: replicas: 2 resources: requests: cpu: 200m memory: 256Mi

redis: enabled: true

applicationSet: replicas: 2

notifications: enabled: true

configs: params: server.insecure: false

rbac: policy.default: role:readonly policy.csv: | p, role:admin, applications, *, /, allow p, role:admin, clusters, *, *, allow p, role:admin, repositories, *, *, allow p, role:admin, projects, *, *, allow p, role:developer, applications, get, /, allow p, role:developer, applications, sync, /, allow p, role:developer, logs, get, /, allow g, admin-team, role:admin g, dev-team, role:developer

repositories: infra-repo: url: [email protected]:myorg/k8s-manifests.git sshPrivateKeySecret: name: repo-ssh-key key: sshPrivateKey

# Deploy:
helm install argocd argo/argo-cd -n argocd -f argocd-values.yaml

# Get initial admin password:
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath='{.data.password}' | base64 -d

# Install ArgoCD CLI:
curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x argocd && sudo mv argocd /usr/local/bin/

# Login:
argocd login argocd.myapp.com --grpc-web

# Add Git repository:
argocd repo add [email protected]:myorg/k8s-manifests.git \
  --ssh-private-key-path ~/.ssh/id_rsa

PART 4: CREATE ARGOCD APPLICATION

# argocd-app-order.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: order-service
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: production
  
  source:
    repoURL: [email protected]:myorg/k8s-manifests.git
    targetRevision: main
    path: apps/order-service/overlays/production
  
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  
  syncPolicy:
    automated:
      prune: true              # Delete resources not in Git
      selfHeal: true           # Auto-fix drift
      allowEmpty: false
    syncOptions:
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
      - PruneLast=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

4.1. ArgoCD Project

# argocd-project.yaml:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: production
  namespace: argocd
spec:
  description: "Production applications"

sourceRepos: - "[email protected]:myorg/k8s-manifests.git" - "https://charts.bitnami.com/bitnami"

destinations: - namespace: "default" server: https://kubernetes.default.svc - namespace: "messaging" server: https://kubernetes.default.svc - namespace: "database" server: https://kubernetes.default.svc

clusterResourceWhitelist: - group: "" kind: Namespace

namespaceResourceBlacklist: - group: "" kind: ResourceQuota - group: "" kind: LimitRange

roles: - name: developer policies: - p, proj:production:developer, applications, get, production/, allow - p, proj:production:developer, applications, sync, production/, allow groups: - dev-team


PART 5: APPLICATIONSET (MULTI-APP GENERATION)

# Generate apps from directory structure:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: microservices
  namespace: argocd
spec:
  generators:
    - git:
        repoURL: [email protected]:myorg/k8s-manifests.git
        revision: main
        directories:
          - path: "apps/*/overlays/production"
  
  template:
    metadata:
      name: "{{path[1]}}"
    spec:
      project: production
      source:
        repoURL: [email protected]:myorg/k8s-manifests.git
        targetRevision: main
        path: "{{path}}"
      destination:
        server: https://kubernetes.default.svc
        namespace: default
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

PART 6: NOTIFICATIONS

# Slack notification:
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  service.slack: |
    token: $slack-token
  
  template.app-sync-succeeded: |
    message: |
      ✅ Application {{.app.metadata.name}} has been successfully synced.
      Revision: {{.app.status.sync.revision}}
    slack:
      attachments: |
        [{
          "color": "#18be52",
          "title": "{{.app.metadata.name}} synced",
          "fields": [{
            "title": "Sync Status",
            "value": "{{.app.status.sync.status}}",
            "short": true
          }]
        }]
  
  trigger.on-sync-succeeded: |
    - when: app.status.sync.status == 'Synced'
      send: [app-sync-succeeded]
  
  trigger.on-sync-failed: |
    - when: app.status.sync.status == 'OutOfSync'
      send: [app-sync-failed]

💡 KEY TAKEAWAYS

  1. GitOps: Git is the single source of truth for infrastructure
  2. ArgoCD: Declarative CD, auto-sync, drift detection, rich UI
  3. HA install: 2+ replicas for controller, server, repo-server
  4. Projects: RBAC boundaries, limit repos/namespaces per team
  5. ApplicationSet: Generate hundreds of apps from templates
  6. Self-heal: Auto-revert manual kubectl changes

🎯 EXERCISE

Exercise 1: ArgoCD Setup

  • Install ArgoCD HA
  • Add Git repo, create Project
  • Deploy sample app via ArgoCD Application
  • Manually edit deployment → watch self-heal

Exercise 2: ApplicationSet

  • Create directory-based ApplicationSet
  • Add new service → auto-discover & deploy

📚 NEXT POST

In Lesson 29: Helm Charts for Microservices — Templates, Values, Dependencies, we will build reusable Helm charts for the entire microservices stack.