前言
ArgoCD 的 Health Status 告诉你应用是否真正健康------不只是 YAML 是否同步了,而是 Pod 是否就绪、服务是否可用。本篇讲解 ArgoCD 内置健康检查的工作原理,以及如何为自定义资源编写健康检查脚本。
一、Health Status 的五种状态
Healthy → 所有资源都健康,服务正常运行
Progressing → 正在滚动更新,部分 Pod 还在启动
Degraded → 有资源不健康,可能有 Pod 崩溃
Suspended → 资源被暂停(如 CronJob 暂停)
Missing → 资源不存在(Git 中有但集群中没有)
状态流转
+───────────+
| OutOfSync | (Git 和集群有差异)
+──────┬─────+
↓ 同步
+───────────+
| Progressing | (滚动更新中)
+──────┬─────+
↙ ↘
+────────+ +───────────+
| Healthy | | Degraded |
+────────+ +───────────+
↑ ↓ 修复
└─────────────────────┘
二、内置健康检查
ArgoCD 内置支持的资源类型
| 资源类型 | 健康判断逻辑 |
|---|---|
| Deployment | readyReplicas == replicas |
| StatefulSet | readyReplicas == replicas |
| DaemonSet | desiredNumberScheduled == numberReady |
| Service | 类型为 LoadBalancer 时检查 ingress 是否分配 |
| Ingress | 检查是否有 assigned IP/hostname |
| Job | 成功完成 |
| CronJob | 最近一次调度成功 |
| PDB | disruptionsAllowed >= 0 |
| HPA | 当前指标可用 |
检查示例
bash
argocd app get myapp
# Health Status: Healthy
# NAME KIND STATUS HEALTH
# myapp Deployment Synced Healthy
# myapp Service Synced Healthy
# myapp-ingress Ingress Synced Healthy
bash
# 如果 Pod 在滚动更新中
argocd app get myapp
# Health Status: Progressing
# NAME KIND STATUS HEALTH
# myapp Deployment Synced Progressing
# → 2/4 pods ready, waiting for 2 more
bash
# 如果 Pod 崩溃
argocd app get myapp
# Health Status: Degraded
# NAME KIND STATUS HEALTH
# myapp Deployment Synced Degraded
# → 2/4 pods ready, 2 pods crashloopbackoff
三、自定义健康检查(Lua 脚本)
为什么需要自定义
ArgoCD 不认识 CRD(自定义资源定义)的健康状态。比如你用了 Argo Rollouts(金丝雀控制器),ArgoCD 不知道一个 Rollout 资源什么时候算健康。
用 Lua 编写健康检查
yaml
# argocd-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
# 自定义健康检查脚本
resource.customizations.health.argoproj.io_Rollout: |
hs = {}
if obj.status ~= nil then
if obj.status.phase == "Healthy" then
hs.status = "Healthy"
hs.message = "Rollout is healthy"
elseif obj.status.phase == "Progressing" then
hs.status = "Progressing"
hs.message = "Rollout is in progress: " .. (obj.status.message or "")
elseif obj.status.phase == "Degraded" then
hs.status = "Degraded"
hs.message = "Rollout is degraded: " .. (obj.status.message or "")
else
hs.status = "Progressing"
hs.message = "Rollout phase: " .. (obj.status.phase or "Unknown")
end
else
hs.status = "Progressing"
hs.message = "Waiting for rollout status"
end
return hs
为 CertManager Certificate 编写健康检查
lua
resource.customizations.health.cert-manager.io_Certificate: |
hs = {}
if obj.status ~= nil and obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Ready" then
if condition.status == "True" then
hs.status = "Healthy"
hs.message = "Certificate is ready"
else
hs.status = "Progressing"
hs.message = "Certificate is not ready: " .. (condition.message or "")
end
return hs
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for certificate status"
return hs
为 ExternalSecret 编写健康检查
lua
resource.customizations.health.external-secrets.io_ExternalSecret: |
hs = {}
if obj.status ~= nil and obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Ready" then
if condition.status == "True" then
hs.status = "Healthy"
hs.message = "ExternalSecret synced successfully"
else
hs.status = "Degraded"
hs.message = "ExternalSecret sync failed: " .. (condition.message or "")
end
return hs
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for ExternalSecret to sync"
return hs
培训要点 :Lua 脚本中的
obj对象就是 K8s API 返回的资源 JSON。你可以检查obj.status中的任何字段。编写时先用kubectl get <crd> -o yaml查看实际状态结构。
四、资源忽略差异(IgnoreDifferences)
什么时候需要
场景1: HPA 自动调整了副本数
Git: replicas=3
集群: replicas=5(HPA 扩容了)
→ ArgoCD 报告 OutOfSync
→ 但这是预期行为,不应该被"修复"
场景2: Mutating Webhook 注入了 sidecar
Git: 没有 sidecar
集群: 有 sidecar(Istio 注入的)
→ ArgoCD 报告 OutOfSync
→ 但这是自动注入,不应该被删除
配置忽略差异
yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp-prod
namespace: argocd
spec:
ignoreDifferences:
# 忽略 Deployment 副本数差异(HPA 管理)
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
# 忽略 Pod 的 sidecar 注入
- group: ''
kind: Pod
jsonPointers:
- /spec/initContainers
- /spec/containers
# 忽略 Service 的 clusterIP(K8s 自动分配)
- group: ''
kind: Service
jsonPointers:
- /spec/clusterIP
- /spec.clusterIPs
# 用 jq 表达式忽略复杂字段
- group: apps
kind: Deployment
jqPathExpressions:
- .spec.template.spec.containers[].resources
全局忽略差异
yaml
# argocd-cm ConfigMap --- 全局配置
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.ignoreDifferences.apps_Deployment: |
jsonPointers:
- /spec/replicas
- /spec/template/spec/containers/0/resources
五、资源动作(Resource Actions)
什么是资源动作
ArgoCD 允许对资源定义自定义操作(如重启 Pod、暂停 CronJob),通过 UI 或 CLI 触发。
定义资源动作
lua
# argocd-cm
resource.customizations.actions.argoproj.io_Rollout: |
# 定义可用动作
discovery: |
actions = []
-- 如果 Rollout 暂停了,提供"恢复"动作
if obj.spec.paused ~= nil and obj.spec.paused then
table.insert(actions, {name = "resume", label = "Resume", icon = "play"})
else
-- 如果没暂停,提供"暂停"动作
table.insert(actions, {name = "pause", label = "Pause", icon: "pause"})
end
-- 提供"重启"动作
table.insert(actions, {name = "restart", label = "Restart", icon = "reload"})
return actions
# 定义动作执行逻辑
definitions:
- name: resume
action.lua: |
obj.spec.paused = false
return obj
- name: pause
action.lua: |
obj.spec.paused = true
return obj
- name: restart
action.lua: |
-- 设置 annotation 触发重启
if obj.spec.template.metadata.annotations == nil then
obj.spec.template.metadata.annotations = {}
end
obj.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = os.date("!%Y-%m-%dT%H:%M:%SZ")
return obj
触发资源动作
bash
# CLI 触发
argocd app actions myapp-prod --action restart
# Web UI
# → 应用页面 → 右键资源 → Actions → 选择操作
六、本篇要点回顾
- Health Status 五状态:Healthy / Progressing / Degraded / Suspended / Missing
- ArgoCD 内置常见资源类型的健康检查(Deployment/Service/Job等)
- CRD 需要自定义 Lua 健康检查,检查
obj.status字段 ignoreDifferences忽略 HPA 副本数、Webhook 注入等预期差异- 资源动作(Resource Actions)在 UI/CLI 中触发自定义操作(暂停/恢复/重启)
下一篇预告:ArgoCD 篇结束,接下来进入 Flux 实战篇:《环境搭建:安装配置与首次 GitRepository》。