Green but Nobody Knows Why: Writing Health Rules Yourself
한국어 원문으로 표시합니다.
목표
argocd-cm 의 resource.customizations.health.<그룹>_<종류> 에 Lua 규칙을 써서 CRD 의 헬스를 Healthy·Progressing·Degraded·Suspended 네 칸으로 갈라 내고, 표본과 기대를 표로 묶어 회귀 검사한다.
왜 중요한가
Argo CD 화면에서 사람이 실제로 보는 것은 동기화가 아니라 헬스다. Deployment·Service·Job 같은 내장 종류는 컨트롤러가 알아서 판정하지만 CRD 에는 내장 규칙이 없다. 오퍼레이터가 만드는 자원이 화면에서 늘 같은 색으로 보인다면, 그건 잘 되고 있다는 뜻이 아니라 판정할 근거가 없다는 뜻이다. 규칙을 직접 쓰는 일이 중요한 이유는 두 가지다. 첫째, 아직 만들어지는 중과 이미 망가진 것을 갈라야 알림을 걸 수 있다. 둘째, 규칙은 한 번 쓰면 잊히는 코드라 표본과 기대를 함께 저장소에 두어야 나중에 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.size3,status.phase는Ready입니다. 1단계의 빈 argocd-cm 으로 이 파일의 헬스를 물어 출력을/root/ga-health/nocustom.txt에 저장하세요./root/ga-health/argocd-cm-healthy.yaml에 키resource.customizations.health.example.com_Widget를 두고,status.phase가Ready면Healthy를, 그 밖에는Progressing을 돌려주는 Lua 를 쓰세요. 두 경우 모두hs.message를 채웁니다./root/ga-health/w-ready.yaml을 이 ConfigMap 으로 판정한 출력을/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>를 네 줄 이상 적으세요 —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로 리소스를 받고hs.status·hs.message를 채운 테이블을 return 합니다. - 헬스 상태 이름은 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 를 두고, status.phase 가 Ready 면 Healthy 를, 그 밖에는 Progressing 을 돌려주는 Lua 를 쓰세요. 두 경우 모두 hs.message 를 채웁니다. /root/ga-health/w-ready.yaml 을 이 ConfigMap 으로 판정한 출력을 /root/ga-health/healthy.txt 에 저장하세요.
Lua 조각은 obj 라는 전역 변수로 리소스를 받고, hs.status 와 hs.message 를 채운 테이블을 return 합니다. 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> 를 네 줄 이상 적으세요 — 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' 가 편합니다. 스크립트가 파일을 직접 쓰면 채점기가 다시 돌릴 때 학생 산출물을 덮어쓰니 표준출력으로만 내보내세요.