技术博客

ArgoCD v3.5 深度解析:内部 mTLS、供应链安全与 GitOps 最佳实践

ArgoCD v3.5 于 2026 年 6 月发布,重点强化供应链安全:内部组件间通信启用强制 mTLS(此前内部流量未加密)、Git Commit 签名验证防止未授权代码部署、ApplicationSet 进入 UI 原生管理。本文讲解 v3.5 的关键变化、完整的 GitOps 工作流配置(App of Apps 模式)、多集群部署策略、RBAC 权限模型,以及与 GitHub Actions/Tekton 的 CI/CD 集成实践。

ArgoCDGitOpsCI/CD供应链安全Kubernetes自动化运维云原生mTLS

ArgoCD 是目前 Kubernetes GitOps 领域使用最广泛的工具。v3.5 在安全性上做了一次重要加固,解决了一个长期存在但容易被忽视的问题:组件间的内部流量一直没有加密


v3.5 关键变化

1. 内部组件 mTLS(最重要的变化)

问题背景:
  ArgoCD 由多个组件组成:
  API Server / Repo Server / Controller / Dex / Redis
  
  这些组件之间的通信(比如 API Server → Repo Server)
  在 v3.5 之前是明文传输,没有任何加密
  
  风险:
  如果集群内有恶意 Pod,可以嗅探 ArgoCD 内部通信
  可能获取 Git 凭据、配置信息等敏感数据

v3.5 的修复:
  所有内部组件通信强制走 mTLS
  证书由 ArgoCD 自动管理(无需手动配置)
  升级后自动生效,不需要额外配置

2. Git Commit 签名验证(供应链安全)

功能:验证部署到集群的 GitOps 变更必须有合法的 GPG/SSH 签名

应用场景:
  防止有人绕过 PR Review 直接推代码到 GitOps 分支
  防止 CI/CD 流水线被劫持,推送恶意的 K8s 配置
  
配置方式(在 Application 中启用):
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-app
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/company/k8s-configs
    targetRevision: main
    path: production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
  # v3.5 新增:要求 Git Commit 必须有签名
  sourceIntegrity:
    gpgKeys:
    - keyID: "ABCDEF1234567890"   # 允许的 GPG Key ID
    - keyID: "0987654321FEDCBA"
    failMode: fail   # commit 没有签名时:fail(拒绝)或 warn(告警)

3. ApplicationSet 原生 UI 管理

v3.5 之前:
  ApplicationSet 只能通过 kubectl apply 创建/修改
  UI 只能查看,无法编辑
  
v3.5 之后:
  在 ArgoCD Web UI 中直接创建/修改/删除 ApplicationSet
  可视化管理批量应用部署
  对不熟悉 YAML 的团队成员更友好

安装 ArgoCD v3.5

# 创建命名空间
kubectl create namespace argocd

# 安装 ArgoCD(使用官方 manifest)
kubectl apply -n argocd \
  -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.5.0/manifests/install.yaml

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

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

# 端口转发访问 UI
kubectl port-forward svc/argocd-server -n argocd 8080:443 &

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

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

App of Apps 模式(生产推荐)

对于管理多个应用的团队,App of Apps 是最清晰的组织方式。

目录结构示例:
k8s-configs/
├── apps/                          # Root Application 管理的 Apps
│   ├── Chart.yaml
│   ├── values.yaml
│   └── templates/
│       ├── production-api.yaml
│       ├── production-frontend.yaml
│       ├── production-db.yaml
│       └── monitoring.yaml
├── production/                    # 各 App 的实际配置
│   ├── api/
│   ├── frontend/
│   └── db/
└── monitoring/
    ├── prometheus/
    └── grafana/
# Root Application(管理所有其他 App)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/company/k8s-configs
    targetRevision: main
    path: apps                   # 指向包含所有子 App 的目录
    helm:
      valueFiles:
      - values.yaml
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd            # 子 App 对象本身放在 argocd 命名空间
  syncPolicy:
    automated:
      prune: true               # 删除 Git 里没有的资源
      selfHeal: true            # 自动修复手动修改
    syncOptions:
    - CreateNamespace=true
# 子 App 模板(apps/templates/production-api.yaml)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-api
  namespace: argocd
spec:
  project: production
  source:
    repoURL: https://github.com/company/k8s-configs
    targetRevision: main
    path: production/api
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - RespectIgnoreDifferences=true

ApplicationSet:批量管理多集群

# 在多个集群上部署同一套配置
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: production-cluster-apps
  namespace: argocd
spec:
  generators:
  # 使用集群生成器:自动为每个注册的集群创建 Application
  - clusters:
      selector:
        matchLabels:
          environment: production    # 只针对 production 集群
  template:
    metadata:
      name: '{{name}}-production-app'   # {{name}} 是集群名
    spec:
      project: production
      source:
        repoURL: https://github.com/company/k8s-configs
        targetRevision: main
        path: 'clusters/{{name}}'       # 每个集群有自己的配置目录
      destination:
        server: '{{server}}'            # 集群 API Server 地址
        namespace: production
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
# 使用矩阵生成器:环境 × 服务 组合
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: multi-env-apps
spec:
  generators:
  - matrix:
      generators:
      - list:
          elements:
          - env: staging
            namespace: staging
          - env: production
            namespace: production
      - list:
          elements:
          - app: api
            path: services/api
          - app: frontend
            path: services/frontend
  template:
    metadata:
      name: '{{env}}-{{app}}'
    spec:
      project: '{{env}}'
      source:
        repoURL: https://github.com/company/k8s-configs
        targetRevision: main
        path: '{{path}}'
        helm:
          valueFiles:
          - values-{{env}}.yaml
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{namespace}}'

RBAC 权限配置

# argocd-rbac-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.default: role:readonly    # 默认只读权限
  policy.csv: |
    # 平台团队:所有权限
    p, role:platform, applications, *, */*, allow
    p, role:platform, clusters, *, *, allow
    p, role:platform, repositories, *, *, allow
    
    # 开发团队:只能同步自己负责的应用
    p, role:dev-team, applications, sync, production/frontend, allow
    p, role:dev-team, applications, sync, production/api, allow
    p, role:dev-team, applications, get, */*, allow
    
    # 只读角色(监控/审计)
    p, role:readonly, applications, get, */*, allow
    p, role:readonly, clusters, get, *, allow
    
    # 用户组绑定(配合 SSO/LDAP)
    g, platform-team, role:platform
    g, dev-team, role:dev-team
    g, auditors, role:readonly
  
  # 配合 SSO 时的 scopes 配置
  scopes: '[groups, email]'

与 GitHub Actions 集成

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [main]
    paths:
    - 'k8s/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    # 对 commit 进行 GPG 签名(配合 ArgoCD v3.5 签名验证)
    - name: Sign commit
      uses: crazy-max/ghaction-import-gpg@v6
      with:
        gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
        passphrase: ${{ secrets.GPG_PASSPHRASE }}
        git_user_signingkey: true
        git_commit_gpgsign: true
    
    # 更新镜像版本(触发 ArgoCD 同步)
    - name: Update image tag
      run: |
        IMAGE_TAG=${{ github.sha }}
        sed -i "s|image: myapp:.*|image: myapp:${IMAGE_TAG}|" k8s/production/deployment.yaml
        git add k8s/production/deployment.yaml
        git commit -S -m "chore: update image to ${IMAGE_TAG}"    # -S 表示 GPG 签名
        git push
    
    # 触发 ArgoCD 同步并等待完成
    - name: Sync ArgoCD Application
      run: |
        argocd app sync production-api \
          --server ${{ secrets.ARGOCD_SERVER }} \
          --auth-token ${{ secrets.ARGOCD_TOKEN }} \
          --insecure \
          --timeout 300
        
        argocd app wait production-api \
          --server ${{ secrets.ARGOCD_SERVER }} \
          --auth-token ${{ secrets.ARGOCD_TOKEN }} \
          --insecure \
          --health \
          --timeout 300

常用排查命令

# 查看所有 Application 状态
argocd app list

# 查看某个 App 的详细状态
argocd app get production-api

# 手动触发同步
argocd app sync production-api

# 查看同步历史
argocd app history production-api

# 回滚到上一个版本
argocd app rollback production-api

# 查看 App 的资源差异(Git vs 集群实际状态)
argocd app diff production-api

# 强制替换(谨慎使用)
argocd app sync production-api --force

# 查看 ArgoCD 组件日志(排查问题)
kubectl logs -n argocd deployment/argocd-server -f
kubectl logs -n argocd deployment/argocd-repo-server -f
kubectl logs -n argocd deployment/argocd-application-controller -f

小结

ArgoCD v3.5 的内部 mTLS 是一个应该尽快升级的安全改进——此前内部流量未加密是一个被普遍忽视的风险点。Commit 签名验证则把供应链安全落实到 GitOps 的核心环节,确保进入生产集群的每一个配置变更都可溯源、可审计。

对于已经在用 ArgoCD 的团队,v3.5 的升级路径比较平滑,内部 mTLS 升级后自动生效,不需要修改现有的 Application 配置。