【GitOps·ArgoCD篇】健康检查与资源钩子:自定义健康状态

前言

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 → 选择操作

六、本篇要点回顾

  1. Health Status 五状态:Healthy / Progressing / Degraded / Suspended / Missing
  2. ArgoCD 内置常见资源类型的健康检查(Deployment/Service/Job等)
  3. CRD 需要自定义 Lua 健康检查,检查 obj.status 字段
  4. ignoreDifferences 忽略 HPA 副本数、Webhook 注入等预期差异
  5. 资源动作(Resource Actions)在 UI/CLI 中触发自定义操作(暂停/恢复/重启)

下一篇预告:ArgoCD 篇结束,接下来进入 Flux 实战篇:《环境搭建:安装配置与首次 GitRepository》。

相关推荐
heimeiyingwang2 天前
【GitOps·ArgoCD篇】同步策略:自动同步、手动同步与同步钩子
argocd·gitops
heimeiyingwang6 天前
【GitOps·入门篇】工具生态:ArgoCD、Flux、Jenkins X 对比选型
jenkins·flux·argocd·gitops
xiaoxiangsiyan16 天前
GitLab CI/CD 自托管(EE 企业版)+ Kubernetes Runner 集群 + ArgoCD(GitOps 部署)
运维·网络·ci/cd·容器·kubernetes·gitlab·argocd
nvd1116 天前
ArgoCD 双层轮询深入拆解:从 redis-app.yaml 注册到缓存重建的完整链路
redis·缓存·argocd
meijinmeng17 天前
EKS 集群 ArgoCD `v3.0.6 → v3.1.x → v3.2.x` 备份,恢复,升级,巡检手册
argocd·cicd
运维大师18 天前
【K8S 运维实战】32-GitOps实践ArgoCD
运维·kubernetes·argocd
spider_xcxc19 天前
Argo CD Webhook 完全指南:从原理到实战,实现 Git 变更即时同步
argocd
啊真真真20 天前
ArgoCD:我的GitOps探索之旅与未来展望
java·算法·argocd
nvd1125 天前
基于 ArgoCD 优雅落地 K8s Gateway API 与 Kong 控制器(KIC)
kubernetes·gateway·argocd