Chapter 2: Argo CD Getting Started

Haiyue
20min

Chapter 2: Argo CD Getting Started

Learning Objectives
  • Understand the core principles and advantages of GitOps
  • Master Argo CD installation and basic configuration
  • Learn to create Applications for application deployment
  • Proficiently use Argo CD UI and CLI operations

Key Concepts

GitOps Core Principles

GitOps is a continuous delivery approach that uses Git as the single source of truth for declarative infrastructure and applications.

🔄 正在渲染 Mermaid 图表...

Argo CD Architecture

🔄 正在渲染 Mermaid 图表...

Core Concepts

ConceptDescription
ApplicationRepresents a deployed application, contains source repository and target cluster information
ProjectLogical grouping of applications for permission control
RepositoryConnection configuration for Git repository or Helm repository
ClusterConnection configuration for target Kubernetes cluster
SyncOperation to synchronize Git state to cluster
RefreshOperation to pull latest configuration from Git
HealthHealth status of application resources

Installing Argo CD

Standard Installation

# Create namespace
kubectl create namespace argocd

# Install Argo CD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Wait for pods to be ready
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s

# Check deployment status
kubectl get pods -n argocd
# NAME                                                READY   STATUS    RESTARTS   AGE
# argocd-application-controller-0                     1/1     Running   0          2m
# argocd-applicationset-controller-xxx                1/1     Running   0          2m
# argocd-dex-server-xxx                               1/1     Running   0          2m
# argocd-notifications-controller-xxx                 1/1     Running   0          2m
# argocd-redis-xxx                                    1/1     Running   0          2m
# argocd-repo-server-xxx                              1/1     Running   0          2m
# argocd-server-xxx                                   1/1     Running   0          2m

High Availability Installation

# HA mode installation (recommended for production)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml

Helm Installation

# Add Helm repository
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

# Install Argo CD
helm install argocd argo/argo-cd \
  --namespace argocd \
  --create-namespace \
  --set server.service.type=LoadBalancer \
  --set configs.params.server.insecure=true
# Custom values.yaml
# argocd-values.yaml
server:
  replicas: 2
  service:
    type: LoadBalancer
  ingress:
    enabled: true
    hosts:
      - argocd.example.com
    tls:
      - secretName: argocd-tls
        hosts:
          - argocd.example.com

controller:
  replicas: 1

repoServer:
  replicas: 2

redis:
  enabled: true

configs:
  params:
    server.insecure: true
  repositories:
    - url: https://github.com/myorg/myapp.git
      name: myapp
helm install argocd argo/argo-cd -n argocd -f argocd-values.yaml

Accessing Argo CD

Getting Initial Password

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

# Username: admin
# Password: output from above command

Port Forward Access

# Port forward to localhost
kubectl port-forward svc/argocd-server -n argocd 8080:443

# Access via browser
# https://localhost:8080

Configuring Ingress Access

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  ingressClassName: nginx
  rules:
  - host: argocd.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              number: 443
  tls:
  - hosts:
    - argocd.example.com
    secretName: argocd-tls

CLI Login

# Install CLI
# macOS
brew install argocd

# Linux
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 localhost:8080
# Enter username: admin
# Enter password: <initial password>

# Change password
argocd account update-password

# View current user
argocd account get-user-info

Creating Application

Application Structure

🔄 正在渲染 Mermaid 图表...

Creating with YAML

# guestbook-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
  # Auto cleanup resources when application is deleted
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  # Project name (default is the built-in project)
  project: default

  # Source configuration
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook

  # Destination configuration
  destination:
    server: https://kubernetes.default.svc
    namespace: guestbook

  # Sync policy
  syncPolicy:
    automated:
      prune: true       # Delete resources not in Git
      selfHeal: true    # Auto-fix drift
      allowEmpty: false # Don't allow empty application
    syncOptions:
      - CreateNamespace=true  # Auto create namespace
      - PruneLast=true       # Execute deletion last
      - ApplyOutOfSyncOnly=true  # Only sync changed resources
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m
# Apply configuration
kubectl apply -f guestbook-app.yaml

# Check application status
kubectl get applications -n argocd
argocd app get guestbook

Creating with CLI

# Create application
argocd app create guestbook \
  --repo https://github.com/argoproj/argocd-example-apps.git \
  --path guestbook \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace guestbook \
  --sync-policy automated \
  --auto-prune \
  --self-heal

# List applications
argocd app list

# Get application details
argocd app get guestbook

# View application resources
argocd app resources guestbook

# View application manifests
argocd app manifests guestbook

Creating with UI

🔄 正在渲染 Mermaid 图表...

Sync Operations

Sync Status Explanation

🔄 正在渲染 Mermaid 图表...
StatusDescription
SyncedCluster state matches Git
OutOfSyncCluster state doesn’t match Git
UnknownUnable to determine sync status

Health Status Explanation

StatusDescription
HealthyAll resources running healthy
ProgressingResources being deployed
DegradedResources running abnormally
SuspendedResources suspended
MissingResources don’t exist
UnknownUnable to determine health status

Manual Sync

# Sync application
argocd app sync guestbook

# Sync specific resource
argocd app sync guestbook --resource ':Deployment:guestbook-ui'

# Force sync (ignore difference check)
argocd app sync guestbook --force

# Dry run sync (don't actually execute)
argocd app sync guestbook --dry-run

# Sync and wait for completion
argocd app sync guestbook --wait

# Sync and wait for health
argocd app sync guestbook --wait --health

Auto Sync Configuration

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/myapp.git
    targetRevision: HEAD
    path: manifests
  destination:
    server: https://kubernetes.default.svc
    namespace: myapp
  syncPolicy:
    automated:
      # Auto prune: delete resources not in Git
      prune: true
      # Self-heal: auto sync when drift detected
      selfHeal: true
      # Don't allow empty application (prevent accidental deletion of all resources)
      allowEmpty: false
    syncOptions:
      # Auto create namespace
      - CreateNamespace=true
      # Validate resource configuration
      - Validate=true
      # Replace instead of patch
      - Replace=false
      # Server-side apply
      - ServerSideApply=true

Configuring Repository

Adding Git Repository

# Add public repository
argocd repo add https://github.com/argoproj/argocd-example-apps.git

# Add private repository (HTTPS)
argocd repo add https://github.com/myorg/private-repo.git \
  --username <username> \
  --password <password>

# Add private repository (SSH)
argocd repo add git@github.com:myorg/private-repo.git \
  --ssh-private-key-path ~/.ssh/id_rsa

# Add private repository (Deploy Key)
argocd repo add git@github.com:myorg/private-repo.git \
  --ssh-private-key-path ./deploy-key

# List repositories
argocd repo list

Configuring Repository with Secret

# Configure private repository with Secret
apiVersion: v1
kind: Secret
metadata:
  name: private-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/myorg/private-repo.git
  username: git-username
  password: ghp_xxxxxxxxxxxx

---
# SSH key method
apiVersion: v1
kind: Secret
metadata:
  name: private-repo-ssh
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: git@github.com:myorg/private-repo.git
  sshPrivateKey: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----

Adding Helm Repository

# Add public Helm repository
argocd repo add https://charts.bitnami.com/bitnami --type helm --name bitnami

# Add private Helm repository
argocd repo add https://charts.example.com \
  --type helm \
  --name private-helm \
  --username admin \
  --password secret
# Application using Helm Chart
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://charts.bitnami.com/bitnami
    chart: nginx
    targetRevision: 15.0.0
    helm:
      releaseName: nginx
      values: |
        replicaCount: 3
        service:
          type: ClusterIP
      parameters:
        - name: image.tag
          value: "1.25.0"
  destination:
    server: https://kubernetes.default.svc
    namespace: nginx
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Configuring Target Cluster

Adding External Cluster

# View current clusters
argocd cluster list

# Add external cluster (using kubeconfig context)
argocd cluster add <context-name>

# Add cluster with specific name
argocd cluster add <context-name> --name production-cluster

# View cluster details
argocd cluster get https://kubernetes.default.svc

Configuring Cluster with Secret

apiVersion: v1
kind: Secret
metadata:
  name: production-cluster
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: cluster
stringData:
  name: production
  server: https://production-cluster.example.com:6443
  config: |
    {
      "bearerToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
      "tlsClientConfig": {
        "insecure": false,
        "caData": "LS0tLS1CRUdJTi..."
      }
    }

Hands-on Practice

Deploying Example Application

# 1. Create application
kubectl apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: demo-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: demo
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
EOF

# 2. Check application status
argocd app get demo-app

# 3. Manual sync
argocd app sync demo-app

# 4. Wait for sync completion
argocd app wait demo-app --sync --health

# 5. View deployed resources
kubectl get all -n demo

# 6. Access application
kubectl port-forward svc/guestbook-ui -n demo 8081:80
# Browser access http://localhost:8081

Deploy with Kustomize

# Project structure
# myapp/
# ├── base/
# │   ├── deployment.yaml
# │   ├── service.yaml
# │   └── kustomization.yaml
# └── overlays/
#     ├── development/
#     │   └── kustomization.yaml
#     ├── staging/
#     │   └── kustomization.yaml
#     └── production/
#         └── kustomization.yaml

# Application configuration
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-production
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/myapp.git
    targetRevision: main
    path: overlays/production
    # Kustomize configuration
    kustomize:
      namePrefix: prod-
      commonLabels:
        env: production
      images:
        - name: myapp
          newName: gcr.io/myorg/myapp
          newTag: v1.2.3
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Deploy with Helm

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: prometheus
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://prometheus-community.github.io/helm-charts
    chart: kube-prometheus-stack
    targetRevision: 45.0.0
    helm:
      releaseName: prometheus
      # Use values file
      valueFiles:
        - values-production.yaml
      # Inline values
      values: |
        prometheus:
          prometheusSpec:
            retention: 30d
            storageSpec:
              volumeClaimTemplate:
                spec:
                  accessModes: ["ReadWriteOnce"]
                  resources:
                    requests:
                      storage: 50Gi
        grafana:
          adminPassword: secret
          persistence:
            enabled: true
            size: 10Gi
      # Parameter override
      parameters:
        - name: alertmanager.enabled
          value: "true"
  destination:
    server: https://kubernetes.default.svc
    namespace: monitoring
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true

Rollback Operations

# View history versions
argocd app history demo-app

# Rollback to specific version
argocd app rollback demo-app <revision>

# View differences
argocd app diff demo-app

# View detailed differences
argocd app diff demo-app --local-repo-root .

Common Troubleshooting

Sync Failed

# View sync status
argocd app get myapp

# View detailed logs
argocd app logs myapp

# View resource events
kubectl describe application myapp -n argocd

# Check repository connection
argocd repo get https://github.com/myorg/myapp.git

# Force refresh
argocd app get myapp --refresh
argocd app get myapp --hard-refresh

Health Check Failed

# View resource health status
argocd app resources myapp

# View specific resource status
kubectl describe deployment myapp -n production
kubectl get events -n production --sort-by='.lastTimestamp'

# View Pod logs
kubectl logs -l app=myapp -n production

Permission Issues

# Check Argo CD ServiceAccount permissions
kubectl auth can-i create deployments --as system:serviceaccount:argocd:argocd-application-controller -n target-namespace

# View RBAC configuration
kubectl get clusterrolebinding -l app.kubernetes.io/part-of=argocd
Important Notes
  1. Initial Password Security: Change admin password immediately after first login
  2. Repository Credentials: Private repository credentials are securely stored as Secrets
  3. Sync Strategy: In production environments, it’s recommended to manually sync first, then enable auto-sync after validation
  4. Resource Limits: Configure appropriate resource limits for Argo CD components

Summary

Through this chapter, you should have mastered:

  • GitOps Principles: Core concepts of declarative, versioned, and automated
  • Installation and Deployment: Standard installation, HA installation, and Helm installation methods
  • Application Management: Creating, syncing, and rolling back applications
  • Repository Configuration: Connection configuration for Git and Helm repositories
  • CLI Operations: Common argocd commands

In the next chapter, we will dive deep into advanced Argo CD configuration, including ApplicationSet, multi-cluster management, and sync strategy optimization.