LabHub
배우기 러닝패스 코스

KCA — Kyverno 인증 어소시에이트 · 정책 운영 · 실습

라벨 규칙을 풀었는데 아무도 몰랐다

LabHub 에서 이어서 보기

목표

Kyverno CLI 의 apply·test·jp 로 정책이 무엇을 거부하고 무엇을 바꾸고 무엇을 만드는지 클러스터에 올리기 전에 판정하고,
그 판정을 시험 묶음과 CI 스크립트로 고정합니다.

왜 중요한가

어드미션 정책은 틀리면 조용합니다. 검증 규칙을 느슨하게 고친 실수는 아무 요청도 막지 않을 뿐 오류를 내지 않고,
변형 규칙의 앵커 하나는 이미 값이 있는 리소스를 건드리는지 아닌지를 바꿉니다. 운영 클러스터에서 그 차이를 발견하면 이미 늦습니다.
kyverno test 는 "이 리소스는 통과, 저 리소스는 실패, 이 리소스는 이렇게 바뀐다" 는 기대를 먼저 적어 두고 엔진의 실제 판정과 비교합니다.
그래서 정책을 고친 사람이 의도하지 않은 완화를 했을 때 시험이 먼저 빨간불을 켭니다. 클러스터에 없는 ConfigMap 이나 API 호출 결과는
values 파일로 채우고, 조건식의 JMESPath 는 kyverno jp 로 따로 돌려 보면서 정책 저장소를 코드처럼 검증합니다.

단계

1. /root/kca-cli/validate/policy.yaml 에 ClusterPolicy require-team 을 작성하세요. 규칙 check-team 은 Pod 를 골라 metadata.labels.team 이 비어 있지 않은 값이어야 한다고 요구하고 failureAction 은 Enforce 입니다. /root/kca-cli/validate/resources.yaml 에는 Pod good(라벨 team=pay), 라벨 없는 Pod bad, 파드 템플릿에 team 라벨이 없는 Deployment web 을 둡니다(모두 namespace default). kyverno apply--policy-report 를 붙여 실행하고 표준 출력을 /root/kca-cli/apply-report.yaml 에 저장하세요.
2. /root/kca-cli/validate/kyverno-test.yaml 에 Test 를 작성하세요(apiVersion cli.kyverno.io/v1alpha1). policies 는 policy.yaml, resources 는 resources.yaml 이고, results 에 good 은 pass, bad 는 fail, Deployment web 은 1단계 보고서에 나온 자동 생성 규칙 이름으로 fail 을 기대합니다. kyverno test /root/kca-cli/validate 가 3건 모두 통과해야 합니다.
3. /root/kca-cli/validate/root/kca-cli/regressed 로 통째로 복사하고, 복사본의 policy.yaml 에서 team 키만 등가 앵커 =(team) 으로 바꾸세요(라벨이 없으면 통과하게 되는 흔한 실수). kyverno test /root/kca-cli/regressed --remove-color 의 출력 전체를 /root/kca-cli/regression.txt 에 저장하고 종료 코드도 확인하세요. 요약 줄과 종료 코드만 보지 말고 표의 RESULT·REASON 열에서 기대와 실제가 어긋난 행을 찾습니다. 원본 validate 는 그대로 통과해야 합니다.
4. /root/kca-cli/mutate/ 에 ClusterPolicy add-managed-by(규칙 add-label, Pod 에 managed-by: kyverno 라벨을 없을 때만 추가하는 추가 앵커 사용), resources.yaml(라벨 없는 Pod plain, managed-by: helm 라벨이 있는 Pod owned), 변형 뒤 기대 모습 patched.yaml(plain 에 라벨이 붙은 Pod), kyverno-test.yaml 을 두세요. 시험은 plain 을 patchedResources 와 비교해 pass, owned 는 skip 을 기대하고 kyverno test /root/kca-cli/mutate 가 통과해야 합니다.
5. /root/kca-cli/generate/ 에 ClusterPolicy ns-quota(규칙 gen-quota, Namespace 가 생기면 그 네임스페이스에 ResourceQuota default-quotaspec.hard.pods: "10" 으로 생성, synchronize false), resources.yaml(Namespace team-a), 기대 생성물 generated.yaml, kyverno-test.yaml(team-a 에 대해 generatedResource 비교, pass)을 두고 kyverno test /root/kca-cli/generate 를 통과시키세요.
6. /root/kca-cli/context/ 에 ClusterPolicy allowed-registries 를 두세요. 규칙 check-registry 는 Pod 에 대해 컨텍스트 reg 로 ConfigMap platform/registry-config 를 읽고, foreach 로 모든 컨테이너 이미지가 reg.data.allowed(쉼표로 구분한 패턴 목록) 중 하나에 맞지 않으면 거부합니다(Enforce). resources.yaml 에는 이미지가 registry.lab/web:1.0 하나인 Pod internal, 거기에 docker.io/busybox:1.36 컨테이너 sidecar 를 더한 Pod external 을 둡니다. 클러스터가 없으므로 values.yaml(kind Values)로 reg.data.allowedregistry.lab/* 로 채우고, kyverno-test.yaml 의 variables 로 연결해 internal pass, external fail 을 통과시키세요.
7. /root/kca-cli/jp/query.txt 에 JMESPath 식 하나를 쓰세요. Pod 객체를 입력으로 받아 이미지가 registry.lab/ 로 시작하지 않는 컨테이너의 이름 목록을 돌려줘야 합니다. /root/kca-cli/jp/external.yaml 에 6단계의 Pod external 한 개만 두고, kyverno jp query -i jp/external.yaml -q jp/query.txt 의 출력을 /root/kca-cli/jp/result.json 에 저장하세요.
8. /root/kca-cli/ci.sh 를 실행 가능한 스크립트로 만드세요. 첫 인자로 루트 디렉터리(없으면 /root/kca-cli)를 받아 그 아래 validate·mutate·generate·context 네 디렉터리에 각각 kyverno test 를 돌리고, 하나라도 실패하면 0 이 아닌 값으로 끝나야 합니다. 3단계에서 본 것처럼 종료 코드가 0 이어도 출력 표에 기대와 실제가 어긋난 행(REASON 이 Want ...)이 있으면 실패로 처리해야 합니다. regressed 는 돌리지 않습니다. 채점기는 복사본의 정책·시험을 여러 방식으로 망가뜨려 스크립트가 실패하는지 봅니다.

참고

단계 8개

  1. 정책을 올리기 전에 엔진에 먼저 물어본다
  2. 기대 결과를 먼저 적어 두는 시험
  3. 라벨 규칙을 풀었는데 시험이 먼저 알아챘다
  4. 바뀐 결과까지 비교하는 mutate 시험
  5. 만들어질 객체를 미리 비교하는 generate 시험
  6. 클러스터 없이 ConfigMap 컨텍스트를 채운다
  7. 조건식을 정책 밖에서 먼저 돌려 본다
  8. 정책 저장소의 CI 문지기