ArgoCD 部署

ArgoCD 部署

ArgoCD 是 Kubernetes 的声明式 GitOps 持续交付工具。

安装 ArgoCD

使用 kubectl 安装

# 创建 namespace
kubectl create namespace argocd

# 安装 ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# 等待 Pod 就绪
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s

# 查看状态
kubectl get pods -n argocd

访问 ArgoCD UI

# 方式 1: Port Forward
kubectl port-forward svc/argocd-server -n argocd 8080:443

# 方式 2: LoadBalancer
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

# 方式 3: Ingress
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    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:
              name: https
  tls:
  - hosts:
    - argocd.example.com
    secretName: argocd-tls
EOF

获取初始密码

# 获取 admin 初始密码
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# 登录
# URL: https://localhost:8080
# 用户名: admin
# 密码: (上面获取的密码)

ArgoCD CLI

安装 CLI

# Linux
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd

# macOS
brew install argocd

# 登录
argocd login localhost:8080 --username admin --password <password>

# 修改密码
argocd account update-password

Application 配置

基础 Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
spec:
  # 项目
  project: default
  
  # 源仓库
  source:
    repoURL: https://github.com/example/myapp
    targetRevision: HEAD
    path: k8s/overlays/production
  
  # 目标集群
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  
  # 同步策略
  syncPolicy:
    automated:
      prune: true      # 自动删除不在Git中的资源
      selfHeal: true   # 自动修复偏差
      allowEmpty: false
    syncOptions:
    - CreateNamespace=true
    - PruneLast=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

Helm Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-helm
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/myapp
    targetRevision: main
    path: helm/myapp
    helm:
      # values.yaml 覆盖
      values: |
        replicaCount: 3
        image:
          repository: myapp
          tag: v1.0.0
        ingress:
          enabled: true
          hosts:
            - myapp.example.com
      
      # 或从文件加载
      valueFiles:
      - values-prod.yaml
      
      # 参数覆盖
      parameters:
      - name: image.tag
        value: v1.0.0
      - name: replicaCount
        value: "5"
  
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Kustomize Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-kustomize
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/myapp
    targetRevision: main
    path: k8s/overlays/production
    kustomize:
      # 公共标签
      commonLabels:
        environment: production
        team: platform
      
      # 镜像覆盖
      images:
      - myapp=myapp:v1.0.0
      
      # Namespace 前缀
      nameSuffix: -prod
      
      # 副本数覆盖
      replicas:
      - name: myapp
        count: 5
  
  destination:
    server: https://kubernetes.default.svc
    namespace: production

多环境管理

目录结构

myapp/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml
    │   └── values.yaml
    ├── staging/
    │   ├── kustomization.yaml
    │   └── values.yaml
    └── production/
        ├── kustomization.yaml
        └── values.yaml

开发环境 Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-dev
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/myapp
    targetRevision: develop
    path: k8s/overlays/dev
  destination:
    server: https://kubernetes.default.svc
    namespace: dev
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

生产环境 Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp-prod
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/myapp
    targetRevision: main  # 生产环境使用 main 分支
    path: k8s/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: false     # 生产环境手动删除
      selfHeal: false  # 生产环境手动修复
    syncOptions:
    - CreateNamespace=true
  # 忽略差异
  ignoreDifferences:
  - group: apps
    kind: Deployment
    jsonPointers:
    - /spec/replicas  # 忽略 HPA 修改的副本数

ApplicationSet - 批量管理

Git Generator

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapps
  namespace: argocd
spec:
  generators:
  - git:
      repoURL: https://github.com/example/apps
      revision: HEAD
      directories:
      - path: apps/*
  template:
    metadata:
      name: '{{path.basename}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/example/apps
        targetRevision: HEAD
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

List Generator(多环境)

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp-envs
  namespace: argocd
spec:
  generators:
  - list:
      elements:
      - env: dev
        cluster: https://dev-cluster
        namespace: development
      - env: staging
        cluster: https://staging-cluster
        namespace: staging
      - env: prod
        cluster: https://prod-cluster
        namespace: production
  template:
    metadata:
      name: 'myapp-{{env}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/example/myapp
        targetRevision: HEAD
        path: k8s/overlays/{{env}}
      destination:
        server: '{{cluster}}'
        namespace: '{{namespace}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

ArgoCD Project

创建 Project

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: platform-team
  namespace: argocd
spec:
  description: Platform team applications
  
  # 源仓库白名单
  sourceRepos:
  - https://github.com/example/*
  
  # 目标集群和命名空间
  destinations:
  - namespace: 'platform-*'
    server: https://kubernetes.default.svc
  - namespace: production
    server: https://kubernetes.default.svc
  
  # 允许的资源类型
  clusterResourceWhitelist:
  - group: ''
    kind: Namespace
  - group: 'rbac.authorization.k8s.io'
    kind: ClusterRole
  
  # 命名空间级别资源
  namespaceResourceWhitelist:
  - group: 'apps'
    kind: Deployment
  - group: ''
    kind: Service
  - group: ''
    kind: ConfigMap

同步策略

手动同步

# CLI 同步
argocd app sync myapp

# 仅同步特定资源
argocd app sync myapp --resource apps:Deployment:myapp

# 强制同步
argocd app sync myapp --force

自动同步

syncPolicy:
  automated:
    prune: true      # 自动删除
    selfHeal: true   # 自动修复
  syncOptions:
  - CreateNamespace=true  # 自动创建命名空间
  - PruneLast=true        # 最后删除资源

Sync Waves(同步波次)

# 第一波:创建命名空间
apiVersion: v1
kind: Namespace
metadata:
  name: myapp
  annotations:
    argocd.argoproj.io/sync-wave: "0"
---
# 第二波:创建 ConfigMap/Secret
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  annotations:
    argocd.argoproj.io/sync-wave: "1"
---
# 第三波:创建 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  annotations:
    argocd.argoproj.io/sync-wave: "2"

健康检查

自定义健康检查

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
spec:
  # ...
  # 健康评估
  health:
    status: Healthy
    message: "All pods are running"

Resource Hooks

apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration
  annotations:
    argocd.argoproj.io/hook: PreSync  # 同步前执行
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  template:
    spec:
      containers:
      - name: migrate
        image: myapp:latest
        command: ["npm", "run", "migrate"]
      restartPolicy: Never

小结

本节介绍了 ArgoCD:

安装配置:kubectl/Helm 安装,UI/CLI 访问
Application:Git/Helm/Kustomize 应用管理
多环境:开发、测试、生产环境隔离
ApplicationSet:批量管理应用
同步策略:自动/手动同步,Sync Waves

下一节介绍 Helm Chart 管理。