深入解析删除前钩子、源水合器增强功能与生产就绪特性
Argo CD 社区发布了又一个令人印象深刻的版本——3.3 版,带来了备受期待的功能,解决了平台工程师和 DevOps 团队长期以来的痛点。该版本于 2026 年初发布,代表着 GitOps 生态系统向前迈出的重要一步,引入了许多团队多年来一直要求的功能。
在这篇全面的技术指南中,我们将探讨 Argo CD 3.3 的主要功能,剖析其架构改进,提供升级说明,并分享实践案例,以帮助您在生产环境中利用这些新功能。

Argo CD 3.3 有何特别之处?
Argo CD 3.3 建立在 3.0、3.1 和 3.2 版本奠定的坚实基础之上。3.0 版本引入了架构改进和更优的默认配置,3.1 版本带来了 OCI 镜像仓库支持,而 3.3 版本则专注于完善应用生命周期、改善开发者体验和提升运维效率。
该版本包含五个主要功能领域:
- 删除前钩子 (PreDelete Hooks) — 补全生命周期管理的最后一块拼图
- 源水合器 (Source Hydrator) 改进 — 更智能的提交和更好的 monorepo 支持
- OIDC 后台令牌刷新 — 不再有意外的会话超时
- Git 浅克隆 (Shallow Git Clones) — 大幅提升大型仓库的性能
- KEDA 集成 — 直接从 Argo CD 进行高级自动扩缩容控制
让我们深入探讨这些功能。
PreDelete Hooks:生命周期中缺失的一环
问题所在
在 Argo CD 3.3 之前,团队可以通过 PreSync、Sync、PostSync 和 SyncFail 钩子实现全面的生命周期管理。然而,当时并没有原生的方式来在删除应用前执行清理操作。这迫使团队采用一些不便的变通方案:
- 在删除前手动运行清理脚本
- 依赖 Kubernetes finalizer (它可能会无限期地阻塞删除操作)
- 使用外部自动化工具来编排删除前的任务
- 寄希望于依赖资源能够正确清理
解决方案
PreDelete 钩子允许您在 Argo CD 移除应用资源之前执行 Job,例如:
- 在数据库拆除前备份数据
- 从外部服务网格或负载均衡器中注销服务
- 清理外部云资源 (S3 存储桶、DNS 记录等)
- 通知外部系统应用已被移除
- 在移除服务前优雅地排空流量
实践案例
以下是一个 PreDelete 钩子的综合示例,它会在删除应用前执行数据库备份:
apiVersion: batch/v1
kind: Job
metadata:
name: pre-delete-backup-job
annotations:
argocd.argoproj.io/hook: PreDelete
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
backoffLimit: 3
template:
metadata:
labels:
app: backup-job
spec:
serviceAccountName: backup-sa
containers:
- name: backup
image: postgres:15-alpine
env:
- name: PGHOST
value: "postgres-service"
- name: PGDATABASE
valueFrom:
secretKeyRef:
name: db-credentials
key: database
- name: PGUSER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: BACKUP_BUCKET
value: "s3://my-backups/postgres"
command:
- /bin/sh
- -c
- |
echo "Starting pre-delete backup..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="/tmp/backup_${TIMESTAMP}.sql"
# Create backup
pg_dump > ${BACKUP_FILE}
if [ $? -eq 0 ]; then
echo "Database backup successful"
# Upload to S3 (requires AWS CLI in image)
aws s3 cp ${BACKUP_FILE} ${BACKUP_BUCKET}/backup_${TIMESTAMP}.sql
if [ $? -eq 0 ]; then
echo "Backup uploaded successfully to S3"
exit 0
else
echo "Failed to upload backup to S3"
exit 1
fi
else
echo "Database backup failed"
exit 1
fi
restartPolicy: Never
高级 PreDelete 模式
对于复杂的清理场景,你可以组合使用多个 PreDelete 钩子:
---
# Hook 1: Notify external systems
apiVersion: batch/v1
kind: Job
metadata:
name: notify-deletion
annotations:
argocd.argoproj.io/hook: PreDelete
argocd.argoproj.io/hook-weight: "1" # Runs first
spec:
template:
spec:
containers:
- name: notify
image: curlimages/curl:latest
command:
- sh
- -c
- |
curl -X POST https://api.monitoring.com/deregister \
-H "Content-Type: application/json" \
-d '{"service": "my-app", "environment": "production"}'
restartPolicy: Never
---
# Hook 2: Backup data
apiVersion: batch/v1
kind: Job
metadata:
name: backup-data
annotations:
argocd.argoproj.io/hook: PreDelete
argocd.argoproj.io/hook-weight: "2" # Runs second
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
# backup logic here
restartPolicy: Never
---
# Hook 3: Cleanup external resources
apiVersion: batch/v1
kind: Job
metadata:
name: cleanup-external
annotations:
argocd.argoproj.io/hook: PreDelete
argocd.argoproj.io/hook-weight: "3" # Runs last
spec:
template:
spec:
containers:
- name: cleanup
image: cloud-cli:latest
command:
- sh
- -c
- |
# Delete S3 buckets, DNS records, etc.
aws s3 rb s3://app-bucket --force
aws route53 change-resource-record-sets ...
restartPolicy: Never
重要注意事项
- 安全第一:如果任何 PreDelete 钩子执行失败,删除操作将被阻止。这可以防止意外的数据丢失,但也意味着你需要有健壮的错误处理机制。
- 钩子删除策略:使用
argocd.argoproj.io/hook-delete-policy 来控制钩子本身何时被删除:
BeforeHookCreation:在创建新钩子之前删除旧的钩子
HookSucceeded:在成功执行后删除钩子
HookFailed:在执行失败后删除钩子
- 超时:为长时间运行的操作 (如大型数据库备份) 配置适当的超时时间。
Source Hydrator 改进:更智能、更整洁、更快速
源内容生成器 (Source Hydrator) 在 Argo CD 3.x 中受到了广泛关注,3.3 版本延续了这一趋势,其改进从根本上改变了它的工作方式。
使用 Git Notes 替代 Commit
- 旧有行为:在 v3.3 版本之前,对于每一个 DRY (Don’t Repeat Yourself) 源提交,无论清单文件是否实际发生变化,源内容生成器都会创建一个新的生成后 (hydrated) 的提交。这样做是为了跟踪哪个 DRY 提交已经被处理过。
- 全新行为:从 v3.3 版本开始,源内容生成器使用 Git notes 来记录最近一次生成后的 DRY 提交的状态,而不是创建不必要的提交。
- 优势:
- 更整洁的代码仓库:减少不必要的提交,避免 Git 历史记录变得混乱
- 更高的性能:对于变更频率高的团队,减少了 Git 操作
- 更低的冲突风险:自动化的提交减少,意味着合并冲突的可能性更小
- 简化的自动化:用于监控变更的外部工具现在可以专注于实际的清单文件变更
技术实现
Git note 存储在为源内容生成器保留的专用命名空间中:
# View the hydrator git notes
git notes --ref=refs/notes/argocd-source-hydrator list
# Show the note for a specific commit
git notes --ref=refs/notes/argocd-source-hydrator show <commit-sha>
重要迁移说明:如果您的自动化依赖注水提交 (hydrated commits) 作为信号,您需要更新自动化流程,转而查询新的 Git notes。该 note 包含了关于上次处理的 DRY 提交的元数据。
内联参数支持
呼声最高的功能之一现已推出:在注水 (hydration) 过程中直接传递参数,而无需提交参数文件。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
source:
repoURL: https://github.com/myorg/my-repo
targetRevision: main
path: apps/my-app
plugin:
name: source-hydrator
env:
# Inline parameters - no need to commit these!
- name: APP_VERSION
value: "2.1.0"
- name: REPLICA_COUNT
value: "3"
- name: ENVIRONMENT
value: "production"
- name: ENABLE_FEATURE_X
value: "true"
这对于以下场景尤其有价值:
- 快速测试不同的配置
- 特定于环境的覆盖
- 功能标志管理
- 避免因参数变更而导致 Git 提交泛滥
增强的 Monorepo 支持
3.3 版本为使用 Source Hydrator 的 monorepo 团队带来了显著改进:
- 多应用路径:更好地处理单个 monorepo 中的多个应用,改进了路径解析和变更检测。
- 选择性注水 (Selective Hydration):仅注水实际发生变更的应用,而不是在每次提交时都处理整个 monorepo。
Monorepo 结构示例:
monorepo/
├── apps/
│ ├── frontend/
│ │ ├── base/
│ │ │ └── kustomization.yaml
│ │ └── overlays/
│ │ ├── dev/
│ │ └── prod/
│ ├── backend/
│ │ ├── base/
│ │ └── overlays/
│ └── database/
│ └── manifests/
└── hydrator-config/
├── frontend.yaml
├── backend.yaml
└── database.yaml
现在,每个应用都可以独立进行注水,Source Hydrator 会智能地检测 monorepo 的哪些部分发生了变化。
行为变更:不再自动清理
重要破坏性变更:在 v3.3 之前的版本中,Source Hydrator 在写入新的 manifest 文件之前,会自动清理(删除所有文件)应用程序的配置路径。
- 新行为:从 v3.3 开始,此清理逻辑已被移除。现在,hydrator 只会覆盖或创建与当前 manifest 输出相对应的文件。
- 影响:应用路径中的任何额外文件或过时数据都将保留,除非被明确覆盖。
- 迁移策略:
# Manual cleanup if needed
git rm -r path/to/hydrated/manifests/*
git commit -m "Clean up before v3.3 migration"
# Or add a cleanup step to your CI/CD pipeline
- name: Clean hydration target
run: |
rm -rf manifests/hydrated/*
mkdir -p manifests/hydrated
OIDC 后台令牌刷新:告别意外登出
痛点
任何将 Keycloak 等 OIDC 提供商与 Argo CD 结合使用的人都经历过这种挫败感:您正在审查应用部署的紧要关头,却因为令牌过期而突然被登出。在许多 OIDC 配置中,默认 5 分钟的令牌生命周期让这个问题成了一个持续的烦恼。
解决方案
Argo CD 3.3 引入了自动后台令牌刷新功能。现在,服务器会在令牌过期前主动刷新它们,让您的 UI 会话在工作期间保持活动状态。
配置
通过在您的 Argo CD 配置中配置 refreshTokenThreshold 来启用令牌刷新:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
# Refresh tokens when they have less than 5 minutes remaining
oidc.config: |
name: Keycloak
issuer: https://keycloak.example.com/realms/master
clientID: argocd
clientSecret: $oidc.keycloak.clientSecret
requestedScopes: ["openid", "profile", "email", "groups"]
# New in 3.3: Refresh tokens proactively
refreshTokenThreshold: 300 # 300 seconds = 5 minutes
工作原理
- 背景监控:服务器监控令牌 (token) 的过期时间
- 主动刷新:当剩余生命周期低于阈值时,触发刷新操作
- 对用户透明:在后台进行,不会中断用户体验
- 支持多种提供商:适用于 Keycloak、Okta、Azure AD 及其他 OIDC 提供商
最佳实践
根据您的安全策略和用户体验需求,合理设置 refreshTokenThreshold 的值,例如设置为令牌总生命周期的 20% 左右。
Git 浅克隆:为大型仓库提速
性能问题
对于使用大型 Git 仓库的团队来说,初始克隆和后续的 fetch 操作可能会花费数分钟甚至数小时。这会影响:
- 应用同步时间
- 开发者生产力
- CI/CD 流水线时长
- Argo CD 服务器上的资源消耗
浅克隆的实现
Argo CD 3.3 引入了执行浅克隆 (shallow clones) 的能力,只拉取所需的提交记录,而非整个仓库的历史记录。
启用浅克隆
在添加仓库时,你现在可以指定 depth 标志:
# Via CLI
argocd repo add https://github.com/myorg/large-repo \
--username myuser \
--password mypassword \
--depth 1
# Or with specific depth
argocd repo add https://github.com/myorg/large-repo \
--username myuser \
--password mypassword \
--depth 50 # Last 50 commits
声明式配置
apiVersion: v1
kind: Secret
metadata:
name: large-repo-secret
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/myorg/large-repo
username: myuser
password: mytoken
# New in 3.3: depth for shallow clone
depth: "1"
注意事项与限制
何时使用浅克隆:
- 历史记录庞大的大型仓库
- 提交频率高的 Monorepo
- 仅需关注近期提交的项目
何时避免使用:
- 如果出于合规性需要完整的 Git 历史记录
- 当大量使用 Git 子模块 (submodules) 时
- 对于需要历史记录的复杂分支策略的仓库
配置技巧:
# For most use cases - fetch only the latest commit
depth: "1"
# For development environments - more history for debugging
depth: "50"
# For compliance-heavy environments - full clone
# (omit the depth parameter)
KEDA 集成:高级自动扩缩容控制
Argo CD 3.3 引入了对 KEDA (Kubernetes Event-driven Autoscaling) 的原生支持,可以直接在 Argo CD UI 中对自动扩缩容行为进行精细控制。
KEDA 新功能:暂停和恢复 ScaledObjects
现在,你可以直接从 Argo CD UI 中暂停和恢复 KEDA 的 ScaledObjects 和 ScaledJobs:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: api-scaler
annotations:
# Argo CD will recognize and manage this resource
argocd.argoproj.io/sync-options: Prune=false
spec:
scaleTargetRef:
name: api-deployment
minReplicaCount: 2
maxReplicaCount: 100
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
metricName: http_requests_per_second
threshold: '100'
query: sum(rate(http_requests_total[2m]))
暂停/恢复的使用场景:
- 维护窗口:在维护期间暂停自动扩缩容,以防止意外的伸缩活动
- 调试:在调查性能问题时停止自动扩缩容
- 受控发布:在关键部署期间手动管理扩缩容
- 成本管理:在低流量时段临时禁用自动扩缩容
ScaledJobs 的健康检查
Argo CD 现在能正确理解 KEDA ScaledJob 的健康状态:
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: batch-processor
spec:
jobTargetRef:
template:
spec:
containers:
- name: processor
image: batch-processor:v1.2.0
restartPolicy: OnFailure
pollingInterval: 30
maxReplicaCount: 10
successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 5
triggers:
- type: rabbitmq
metadata:
queueName: tasks
queueLength: '10'
hostFromEnv: RABBITMQ_HOST
之前,ScaledJobs 在 Argo CD UI 中会显示为“Unknown”。现在,你将看到基于作业执行状态的准确健康状况指示器。
实用的 KEDA + Argo CD 工作流
# Application with KEDA autoscaling
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: scalable-api
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/scalable-api
targetRevision: HEAD
path: k8s
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
# Argo CD will now properly track KEDA resources
ignoreDifferences:
- group: keda.sh
kind: ScaledObject
jsonPointers:
- /status
3.3 版本中的其他改进
通过卷挂载 (Volume Mount) 管理 Redis 凭证
增强了 Redis 凭证管理的安全性:
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-server
spec:
template:
spec:
containers:
- name: argocd-server
volumeMounts:
- name: redis-credentials
mountPath: /etc/redis-credentials
readOnly: true
env:
- name: REDIS_PASSWORD_FILE
value: /etc/redis-credentials/password
volumes:
- name: redis-credentials
secret:
secretName: redis-password
items:
- key: password
path: password
mode: 0400
Ceph CRD 健康检查
为 Rook-Ceph CRD (自定义资源定义) 提供了原生健康检查:
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
name: rook-ceph
annotations:
# Argo CD will now properly monitor Ceph cluster health
argocd.argoproj.io/sync-wave: "1"
spec:
# ... Ceph configuration
Argo CD 现在能够理解 Ceph 集群的状态:Creating、Ready、Updating、Error,并能在应用健康状况中正确反映这些状态。
UI 增强
- 强制刷新选项 (Hard Refresh Option):新增下拉菜单,用于强制执行完整的应用重新同步
- 改进的动作图标:为应用操作提供了更直观的图标
- 更优的错误信息:为常见的同步问题提供了更具描述性的错误信息
升级到 Argo CD 3.3
前提条件与规划
在升级之前,请确保你了解其支持策略:
- Argo CD 支持最近的三个次要版本
- 2.14 版本随着 3.2 版本的发布已停止支持 (EOL)
- 如果你正在使用 2.x 版本,请先升级到 3.0,然后再升级到 3.3
关键:需要启用服务器端应用 (Server-Side Apply)
重大变更 (Breaking Change):Argo CD 3.3 要求在升级时启用服务器端应用 (Server-Side Apply, SSA),以避免因 ApplicationSet 注解 (annotation) 大小限制而引发的问题。
升级流程
步骤 1:备份当前配置
# Backup all Argo CD resources
kubectl get applications -n argocd -o yaml > argocd-apps-backup.yaml
kubectl get applicationsets -n argocd -o yaml > argocd-appsets-backup.yaml
kubectl get configmaps -n argocd -o yaml > argocd-config-backup.yaml
kubectl get secrets -n argocd -o yaml > argocd-secrets-backup.yaml
# Backup the database
kubectl exec -n argocd argocd-redis-0 -- redis-cli SAVE
kubectl cp argocd/argocd-redis-0:/data/dump.rdb ./redis-backup.rdb
步骤 2:更新 Argo CD 清单 (Manifests)
如果你使用 Argo CD 管理 Argo CD 本身(自管理模式),请使用 SSA 更新 Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argocd
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/argoproj/argo-cd
targetRevision: v3.3.0
path: manifests/cluster-install
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
# CRITICAL: Enable Server-Side Apply
- ServerSideApply=true
# If using Kustomize, also enable:
- ClientSideApplyMigration=false
步骤 3:使用 kubectl 手动升级
# Apply with Server-Side Apply and force conflicts resolution
kubectl apply --server-side --force-conflicts \
-f https://raw.githubusercontent.com/argoproj/argo-cd/v3.3.0/manifests/install.yaml
步骤 4:更新组件版本
检查捆绑工具的更新版本:
- Helm:已升级至 3.19.2
- 无重大变更
- 不再支持 Helm 2.x(移除了
--client 标志)
- Kustomize:从 v5.7.0 升级至 v5.8.0
- 请查阅 Kustomize 的变更日志 (changelog) 以了解任何可能产生影响的变更。
步骤 5:环境变量变更
新增了用于 K8s 服务器端超时的环境变量:
apiVersion: apps/v1
kind: Deployment
metadata:
name: argocd-application-controller
spec:
template:
spec:
containers:
- name: argocd-application-controller
env:
# New in 3.3 - separate control for server-side timeout
- name: ARGOCD_K8S_SERVER_SIDE_TIMEOUT
value: "60s" # Default
# This now only controls TCP timeout
- name: ARGOCD_K8S_TCP_TIMEOUT
value: "30s"
升级后验证
# Verify all components are running
kubectl get pods -n argocd
# Check Argo CD version
argocd version
# Verify applications sync status
argocd app list
# Check for any degraded applications
argocd app list --output json | \
jq '.[] | select(.status.health.status != "Healthy") | .metadata.name'
# Monitor logs for errors
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-server --tail=100 -f
常见升级问题排查
问题 1:ApplicationSet 注解大小错误
Error: Failed to apply ApplicationSet: annotation size exceeds maximum
解决方案:确保已启用 ServerSideApply=true:
kubectl patch application argocd -n argocd \
--type merge \
-p '{"spec":{"syncPolicy":{"syncOptions":["ServerSideApply=true"]}}}'
问题 2:Kustomize 客户端应用 (Client-Side Apply) 迁移
Error: Failed to perform client-side apply migration
解决方案:添加 ClientSideApplyMigration=false 选项:
syncPolicy:
syncOptions:
- ServerSideApply=true
- ClientSideApplyMigration=false
问题 3:Source Hydrator Git Notes
如果你有自动化流程在监控 hydrated commits:
# Update scripts to check git notes instead
git notes --ref=refs/notes/argocd-source-hydrator show HEAD
# Or update CI/CD to trigger on actual manifest changes
git diff --name-only HEAD~1 HEAD | grep "manifests/"
Argo CD 3.3 最佳实践
1. PreDelete Hook 设计
# Always include proper error handling
apiVersion: batch/v1
kind: Job
metadata:
annotations:
argocd.argoproj.io/hook: PreDelete
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
activeDeadlineSeconds: 600 # Prevent runaway jobs
backoffLimit: 2 # Limit retries
template:
spec:
containers:
- name: cleanup
# Your cleanup logic with proper error codes
restartPolicy: Never
2. Source Hydrator 优化
# Use inline parameters for environment-specific config
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
plugin:
name: source-hydrator
env:
# Avoid committing these
- name: IMAGE_TAG
value: "v1.2.3"
- name: REPLICAS
value: "5"
3. OIDC 令牌刷新配置
# Balance between user experience and security
oidc.config: |
refreshTokenThreshold: 300 # 5 minutes before expiry
# Ensure your OIDC provider supports refresh tokens
requestedScopes: ["openid", "profile", "email", "offline_access"]
4. 浅克隆 (Shallow Clone) 策略
# Start with depth=1, increase if needed
apiVersion: v1
kind: Secret
metadata:
labels:
argocd.argoproj.io/secret-type: repository
stringData:
depth: "1" # Minimal for most cases
# depth: "50" # For development
# Omit for compliance environments
结论
Argo CD 3.3 代表了 GitOps 生态系统的一次重要演进。PreDelete hook 的引入完善了应用生命周期管理的故事,而 Source Hydrator 的改进则让管理复杂部署的团队效率更高。
对开发者体验的关注——通过 OIDC 后台刷新和浅克隆 (shallow clones) 等功能——展示了该项目的成熟度以及对社区反馈的积极响应。对于大规模运行 Argo CD 的团队来说,KEDA 集成和性能改进带来了切实的运维收益。
核心要点
- 规划升级:升级前请仔细阅读服务器端应用 (Server-Side Apply) 的要求
- 测试 PreDelete Hooks:在非生产环境中彻底测试清理程序
- 监控 Source Hydrator:更新任何依赖 hydrated commits 的自动化流程
- 利用新功能:OIDC 刷新和浅克隆 (shallow clones) 可以立即改善用户体验
- 保持更新:鉴于 3 个版本的支持策略,保持更新比以往任何时候都更加重要
未来展望
Argo CD 社区持续快速发展。请关注以下动向:
- 完整的 ApplicationSet UI (基础已在 3.2/3.3 版本中奠定)
- Source Hydrator 的进一步增强
- 更多的 KEDA 功能
- 针对大规模部署的性能优化
资源
欢迎在 云栈社区 分享你对 Argo CD 3.3 的使用经验或提出相关问题。