LabHub
배우기 러닝패스 코스

정책을 코드로 · 정책도 시험해야 한다 · 실습

규칙을 풀어 줬는데 시험은 그날도 초록불이었다

LabHub 에서 이어서 보기

목표

정책 하나에 붙일 시험 하네스를 처음부터 만든다. 입력 표본·기대 판정·기대 메시지를 표 파일에 적고, 그 표를 읽어 서버 dry-run 으로 어드미션을 태우는 실행기를 써서, 메시지 변경·범위 어긋남·규칙 완화 세 가지가 시험에서 어떻게 빨간불로 드러나는지 손으로 확인한다.

왜 중요한가

정책이 고장 나는 가장 흔한 방식은 오류가 아니라 침묵이다. 매치 범위가 어긋나면 정책은 아무 소리 없이 전부 통과시키고, 대시보드에는 빨간 줄 하나 뜨지 않는다. 그래서 잘 도는 정책과 죽은 정책이 겉으로 구분되지 않는다. 여기에 두 번째 힘이 겹친다 - 정책은 누가 막힐 때마다 느슨해지는 방향으로만 고쳐진다. 시험은 이 두 가지를 동시에 막는 유일한 장치다. 다만 통과 표본만 모아 둔 시험은 정책을 통째로 지워도 초록불이라 아무것도 지키지 못한다. 그래서 이 실습은 거부 표본과 기대 메시지를 계약으로 고정하고, 시험 자체가 무의미해진 상태(표본 없음·거부 기대 없음)를 성공과 실패 어느 쪽도 아닌 세 번째 종료 코드로 빼내는 데까지 간다.

단계

1. /root/poltest 에서 작업합니다(export KUBECONFIG=/root/.kube/config, kubectl config use-context kwok-lab). /root/poltest/policy.yamladmissionregistration.k8s.io/v1 의 ValidatingAdmissionPolicy require-min-replicas 를 쓰세요 — matchConstraints.resourceRulesapps 그룹 v1deployments 에 대한 CREATE·UPDATE 를 잡고, validation 은 object.spec.replicas >= 2 이며 messageExpression 이 below the minimum 2 replicas 라는 조각을 담은 문장을 만듭니다. /root/poltest/binding.yaml 에 바인딩 require-min-replicas-bind 를 쓰세요 — policyNamerequire-min-replicas, validationActions["Deny"], matchResources.namespaceSelector.matchLabelspolicy-test: "yes" 입니다. 둘 다 적용하고 네임스페이스 poltest 를 만들어 라벨 policy-test=yes 를 붙이세요. 표본 둘도 만듭니다 — /root/poltest/cases/ok-two.yaml 은 Deployment ok-tworeplicas: 2, /root/poltest/cases/bad-one.yaml 은 Deployment bad-onereplicas: 1 입니다. 마지막으로 ok-two.yaml 하나만 서버 dry-run 으로 보내 그 출력을 /root/poltest/01-allow.txt 에 저장하세요.
2. /root/poltest/cases.txt 에 골든 케이스 표를 쓰세요. 한 줄이 한 표본이고 칸은 | 로 나눕니다 — 이름 | 매니페스트 경로 | allow 또는 deny | 기대 메시지 조각 네 칸입니다. 매니페스트 경로는 표 파일이 있는 디렉터리 기준으로 적고, # 로 시작하는 줄과 빈 줄은 주석입니다. 기대가 allow 인 줄은 메시지 칸에 - 를 적습니다. 지금은 두 줄을 넣으세요 — allow-twocases/ok-two.yaml 을 allow 로, deny-onecases/bad-one.yaml 을 deny 로 적고 메시지 조각은 실제 거부 메시지에서 그대로 옮긴 below the minimum 2 replicas 입니다.
3. /root/poltest/run-cases.sh 를 만드세요. 인자로 표 파일을 받고(없으면 스크립트 옆의 cases.txt) 표의 줄마다 그 매니페스트를 kubectl create -n poltest -f <파일> --dry-run=server 로 보냅니다. 명령이 성공하면 실제 판정은 allow, 실패하면 deny 입니다. 기대와 같으면 PASS <이름> 한 줄을, 다르면 FAIL <이름> <까닭> 한 줄을 찍습니다. 매니페스트 경로는 표 파일이 있는 디렉터리 기준으로 풉니다. 마지막 줄에는 total=<수> pass=<수> fail=<수> 를 찍고, 실패가 하나라도 있으면 0 이 아닌 값으로 끝냅니다. 만들었으면 bash run-cases.sh 로 돌려 두 줄이 다 PASS 로 나오는지 확인하세요.
4. 거부 표본 둘을 더 만드세요 — /root/poltest/cases/bad-zero.yaml 은 Deployment bad-zeroreplicas: 0 이고, /root/poltest/cases/bad-default.yaml 은 Deployment bad-defaultreplicas 필드를 아예 적지 않습니다. 둘을 cases.txtdeny-zero·deny-default 라는 이름으로 더하고 기대 메시지 조각은 같은 below the minimum 2 replicas 로 둡니다. 표는 이제 네 줄이고 그중 세 줄이 deny 기대입니다. bash run-cases.sh 가 다시 전부 PASS 로 끝나야 합니다.
5. run-cases.sh 를 고쳐서 기대가 deny 인 줄은 거부 메시지에 기대 조각이 들어 있어야 PASS 가 되게 하세요(조각이 - 이거나 비어 있으면 메시지는 보지 않습니다). 그다음 /root/poltest/policy-msgdrift.yaml 을 만드세요 — 이름과 규칙은 policy.yaml 과 같고 messageExpression 만 다른 문장으로 바꾼 것으로, 그 문장에는 below the minimum 2 replicas 가 들어 있으면 안 됩니다. 그것을 적용하고 bash run-cases.sh 를 돌려 출력 전체/root/poltest/05-drift.txt 에 저장하세요(FAIL 줄이 세 줄 이상 나와야 합니다). 마지막으로 policy.yaml 을 다시 적용해 원래 메시지로 되돌리고, 시험이 다시 전부 PASS 로 끝나는 것을 확인하세요.
6. /root/poltest/cases/sts-one.yaml 에 StatefulSet sts-one 을 쓰세요 — replicas: 1, serviceName: sts-one 입니다. cases.txtdeny-sts-one 줄을 deny 기대로 더하고(메시지 조각은 같은 below the minimum 2 replicas) bash run-cases.sh 를 돌려 출력 전체를 /root/poltest/06-falsepass.txt 에 저장하세요 — 그 표본이 FAIL 로 나옵니다. 지금 정책은 deployments 만 보기 때문에 이 요청을 아예 판정하지 않고, 거부가 없으니 통과처럼 보이는 것입니다. 이제 policy.yamlresources["deployments", "statefulsets"] 로 넓혀 다시 적용하고, 시험이 다섯 줄 모두 PASS 로 끝나는 것을 확인하세요.
7. /root/poltest/policy-loose.yaml 을 만드세요 — policy.yaml 과 이름·자원·메시지는 같고 최소값만 2 에서 1 로 내린 것입니다(누가 '한 대짜리도 올리게 해 주세요' 라고 요청해 조건을 한 칸 푼 상황입니다). 그것을 적용하고 bash run-cases.sh 를 돌려 출력 전체를 /root/poltest/07-regression.txt 에 저장하세요 — FAIL 이 두 줄 이상 나옵니다. 그다음 policy.yaml 을 다시 적용해 되돌리고 시험이 다시 전부 PASS 로 끝나는 것을 확인하세요.
8. run-cases.sh 를 마지막으로 고쳐 파이프라인 게이트로 쓸 수 있게 하세요. 요약 줄을 total=<수> pass=<수> fail=<수> deny=<수> result=<PASS|FAIL|INVALID> 로 늘리고 (deny 는 기대가 deny 인 줄의 수), 찍은 줄 전체를 표 파일이 있는 디렉터리의 report.txt 에도 그대로 남기세요. 종료 코드 규약은 셋입니다 — 전부 통과면 0, 하나라도 기대와 어긋나면 1, 표에 표본이 하나도 없거나 deny 기대가 하나도 없으면 2(result 는 INVALID). 고친 뒤 bash run-cases.sh 를 돌려 /root/poltest/report.txt 를 남기고, 거부 기대를 뺀 표로도 한 번 돌려 2 가 나오는지 확인하세요.

참고

단계 8개

  1. 통과 표본 하나만 돌려 보고 정책이 산다고 믿었다
  2. 기대를 표로 적어 두자 빠진 쪽이 드러났다
  3. 표를 읽어 돌리는 실행기를 만든다
  4. 그럴듯하지만 규칙을 어기는 표본을 더한다
  5. 메시지만 다듬었는데 시험이 빨간불이 됐다
  6. 정책이 쳐다보지도 않은 자원이 통과로 읽혔다
  7. 규칙을 한 칸 풀어 줬더니 시험이 먼저 알아챘다
  8. 빈 시험이 초록불이 되지 않게 종료 코드를 정한다