亮着绿灯却没人知道依据——亲手编写健康规则
目标
在 argocd-cm 的 resource.customizations.health.<그룹>_<종류>(占位符依次为组、类型)中编写 Lua 规则,把 CRD 的健康状态分成 Healthy、Progressing、Degraded、Suspended 四类,并把样本与期望整理成表,做回归检查。
为什么重要
人在 Argo CD 界面上实际看的不是同步,而是健康状态。Deployment、Service、Job 这样的内置类型由控制器自动判定,但 CRD 没有内置规则。 如果 Operator 创建的资源在界面上总是同一种颜色,那并不意味着运行良好,而是意味着没有可供判定的依据。亲手编写规则之所以重要,有两个原因。第一,必须把“还在创建中”和“已经坏掉”区分开,才能配置告警。第二,规则一旦写好就会被遗忘,所以必须把样本和期望一起放进仓库,这样以后 status 字段变化时,规则才不会悄悄出错。
步骤
- 把
/root/ga-health/argocd-cm.yaml创建为data: {}的空 argocd-cm ConfigMap,并在/root/ga-health/deploy.yaml中放置ga-health命名空间的 Deploymentweb——spec.replicas为 3,status中写入observedGeneration: 1、replicas: 3、updatedReplicas: 2、readyReplicas: 1、availableReplicas: 1。把argocd admin settings resource-overrides health /root/ga-health/deploy.yaml --argocd-cm-path /root/ga-health/argocd-cm.yaml的输出保存到/root/ga-health/builtin.txt。 - 在
/root/ga-health/w-ready.yaml中创建example.com/v1的Widget——名称为w-ready,命名空间为ga-health,spec.size为 3,status.phase为Ready。用第 1 步的空 argocd-cm 查询这个文件的健康状态,把输出保存到/root/ga-health/nocustom.txt。 - 在
/root/ga-health/argocd-cm-healthy.yaml中放置键resource.customizations.health.example.com_Widget,并编写 Lua:当status.phase为Ready时返回Healthy,其他情况返回Progressing。两种情况都要填写hs.message。把用这个 ConfigMap 判定/root/ga-health/w-ready.yaml的输出保存到/root/ga-health/healthy.txt。 - 创建
/root/ga-health/w-failed.yaml——名称为w-failed,status.phase为Failed,status.reason为DiskFull。/root/ga-health/argocd-cm-degraded.yaml要在第 3 步的规则上增加Failed分支并返回Degraded,且hs.message中必须包含该资源的status.reason值。把判定输出保存到/root/ga-health/degraded.txt。 - 创建
/root/ga-health/w-building.yaml(status.phase为Building,名称为w-building)和/root/ga-health/w-nostatus.yaml(完全没有status,名称为w-nostatus)。用第 4 步的 ConfigMap 依次判定这两个文件,把输出追加到/root/ga-health/progressing.txt。两者都必须是Progressing。 - 创建
/root/ga-health/w-paused.yaml——名称为w-paused,spec.paused为true,status.phase为Ready。/root/ga-health/argocd-cm-full.yaml要在前面的规则上再增加一个分支:当spec.paused为真时,先于其他条件返回Suspended。把判定输出保存到/root/ga-health/suspended.txt。 - 创建
/root/ga-health/argocd-cm-typo.yaml——内容与第 6 步相同,只是把键名写成resource.customizations.health.example.com_Widgets(类型写成复数)。把用这个 ConfigMap 判定/root/ga-health/w-ready.yaml的输出保存到/root/ga-health/typo.txt。 - 在
/root/ga-health/health-matrix.tsv中写至少四行<샘플파일이름>\t<기대 STATUS>(占位符依次为样本文件名、期望的 STATUS)——Healthy、Degraded、Progressing、Suspended都必须至少出现一次。/root/ga-health/check-health.sh读取这张表,用/root/ga-health/argocd-cm-full.yaml判定每个样本,匹配则输出OK …,不匹配则输出MISMATCH …,只写到标准输出,只要有一行不匹配就必须以非 0 退出码结束。把它的输出保存到/root/ga-health/health-result.txt。
参考
- Lua 片段通过
obj接收资源,并 return 填好hs.status和hs.message的表。 - 健康状态的名称有 Healthy、Progressing、Degraded、Suspended、Missing、Unknown。
- 键名的分隔符不是点,而是下划线——
resource.customizations.health.<그룹>_<종류>(占位符依次为组、类型)。 - 常见错误:漏掉没有 status 的那一刻,导致新建的资源每次都以红灯开始。
- 常见错误:把类型名称写成复数。不会报错,而是表现得像没有规则一样。
- 参考:https://argo-cd.readthedocs.io/en/stable/operator-manual/health/
先看内置判定
把 /root/ga-health/argocd-cm.yaml 创建为 data: {} 的空 argocd-cm ConfigMap,并在 /root/ga-health/deploy.yaml 中放置 ga-health 命名空间的 Deployment web——spec.replicas 为 3,status 中写入 observedGeneration: 1、replicas: 3、updatedReplicas: 2、readyReplicas: 1、availableReplicas: 1。把 argocd admin settings resource-overrides health /root/ga-health/deploy.yaml --argocd-cm-path /root/ga-health/argocd-cm.yaml 的输出保存到 /root/ga-health/builtin.txt。
Deployment 有内置的健康规则,所以即使 argocd-cm 是空的也能得出判定。期望是三个,却只就绪了一个,请预测会得出什么状态。输出的第一行就是 STATUS。
CRD 根本没有规则
在 /root/ga-health/w-ready.yaml 中创建 example.com/v1 的 Widget——名称为 w-ready,命名空间为 ga-health,spec.size 为 3,status.phase 为 Ready。用第 1 步的空 argocd-cm 查询这个文件的健康状态,把输出保存到 /root/ga-health/nocustom.txt。
对于不认识的类型,Argo CD 不会凭空编造判定。在界面上,这样的资源通常看起来像绿灯,实际上意思是“没有可供判定的依据”。请原样读一读输出的句子。
用 Lua 写出绿灯的条件
在 /root/ga-health/argocd-cm-healthy.yaml 中放置键 resource.customizations.health.example.com_Widget,并编写 Lua:当 status.phase 为 Ready 时返回 Healthy,其他情况返回 Progressing。两种情况都要填写 hs.message。把用这个 ConfigMap 判定 /root/ga-health/w-ready.yaml 的输出保存到 /root/ga-health/healthy.txt。
Lua 片段通过名为 obj 的全局变量接收资源,并 return 填好 hs.status 和 hs.message 的表。完全没有 status 的资源也会传进来,所以请先检查 obj.status ~= nil。键名的分隔符不是点,而是下划线——<그룹>_<종류>(占位符依次为组、类型)。
红灯必须同时给出原因
创建 /root/ga-health/w-failed.yaml——名称为 w-failed,status.phase 为 Failed,status.reason 为 DiskFull。/root/ga-health/argocd-cm-degraded.yaml 要在第 3 步的规则上增加 Failed 分支并返回 Degraded,且 hs.message 中必须包含该资源的 status.reason 值。把判定输出保存到 /root/ga-health/degraded.txt。
如果消息写成固定字符串,在界面上就看不出是哪个资源、因为什么而失效。Lua 中拼接字符串用 ..,而值可能不存在,所以要像 (obj.status.reason or "unknown") 这样设置默认值。
未知状态与没有状态,归入同一类
创建 /root/ga-health/w-building.yaml(status.phase 为 Building,名称为 w-building)和 /root/ga-health/w-nostatus.yaml(完全没有 status,名称为 w-nostatus)。用第 4 步的 ConfigMap 依次判定这两个文件,把输出追加到 /root/ga-health/progressing.txt。两者都必须是 Progressing。
写规则时容易漏掉的是“控制器还没有写 status 的那一刻”。这时如果给出 Degraded,新建的资源每次都会以红灯开始。这就是把默认分支设为 Progressing 的原因。
有意停下的不是故障
创建 /root/ga-health/w-paused.yaml——名称为 w-paused,spec.paused 为 true,status.phase 为 Ready。/root/ga-health/argocd-cm-full.yaml 要在前面的规则上再增加一个分支:当 spec.paused 为真时,先于其他条件返回 Suspended。把判定输出保存到 /root/ga-health/suspended.txt。
Suspended 是 Argo CD 认识的第四种健康状态——这是人有意停下的东西,不应该触发告警的位置。调换一下分支顺序,就能立刻看出为什么它必须放在最前面(phase 是 Ready,所以绿灯分支会先命中)。
键名错一个字母,规则就整条消失
创建 /root/ga-health/argocd-cm-typo.yaml——内容与第 6 步相同,只是把键名写成 resource.customizations.health.example.com_Widgets(类型写成复数)。把用这个 ConfigMap 判定 /root/ga-health/w-ready.yaml 的输出保存到 /root/ga-health/typo.txt。
键名中的类型必须与清单中的 kind 逐字相同。写错时不会报错,只是表现得像没有规则一样——这类错误只有看界面才会发现。请与第 2 步的输出比较一下。
把样本和期望整理成表,对规则做回归检查
在 /root/ga-health/health-matrix.tsv 中写至少四行 <샘플파일이름>\t<기대 STATUS>(占位符依次为样本文件名、期望的 STATUS)——Healthy、Degraded、Progressing、Suspended 都必须至少出现一次。/root/ga-health/check-health.sh 读取这张表,用 /root/ga-health/argocd-cm-full.yaml 判定每个样本,匹配则输出 OK …,不匹配则输出 MISMATCH …,只写到标准输出,只要有一行不匹配就必须以非 0 退出码结束。把它的输出保存到 /root/ga-health/health-result.txt。
只写样本文件名、由脚本补上路径,表会更短。只想取出 STATUS 这一行,用 sed -n 's/^STATUS: //p' 比较方便。如果脚本自己去写文件,评分器再次运行时就会覆盖学员的产出文件,所以请只输出到标准输出。