LabHub
배우기 러닝패스 코스

ポリシーをコードで

必須ラベルとレジストリ制限のポリシーを書く

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

필수 라벨을 요구하는 검증 정책과 레지스트리를 제한하는 거부 규칙을 직접 쓰고, 통과·실패 판정과 정책 리포트를 로컬에서 확인합니다. 마지막에는 정당한 예외를 좁은 범위로 표현합니다.

왜 중요한가

검증 정책에서 사고를 내는 것은 조건식이 아니라 매치 범위입니다. 조건이 틀리면 테스트에서 걸리지만, 매치가 틀리면 정책이 조용히 아무것도 하지 않기 때문에 아무도 눈치채지 못합니다. 그래서 통과해야 할 리소스와 막혀야 할 리소스를 둘 다 넣어 보는 것이 정책 작성의 기본기입니다. 또 하나, 거부 메시지는 정책의 절반입니다. 배포가 막힌 사람이 볼 수 있는 것은 kubectl apply 가 뱉은 한 줄뿐이고, 그 한 줄이 불친절하면 정책 운영 비용이 전부 문의로 돌아옵니다. 마지막으로 이 환경에는 정책 엔진 컨트롤러가 떠 있지 않아 클러스터가 잘못된 파드를 실제로 막지는 않습니다. 판정은 kyverno apply로컬에서 확인하며, 채점도 정책 YAML 의 구조와 그 실행 결과를 봅니다.

단계

  1. /root/policy/validate/require-labels.yaml 을 만드세요. apiVersion: kyverno.io/v1, kind: ClusterPolicy, metadata.namerequire-labels 입니다. spec.validationFailureActionEnforce 로(또는 규칙의 validate.failureActionEnforce 로), spec.backgroundtrue 로 두고, spec.rules[0].namecheck-required-labels 로 지으세요.
  2. 같은 규칙에 match.any[0].resources.kindsPod 를, namespacespol-lab 을 지정하세요. 그리고 규칙에 exclude.any[0].resources.namespaceskube-system 을 빼세요.
  3. validate.pattern.metadata.labels 아래에 app.kubernetes.io/nameteam 두 라벨을 각각 "?*" 로 요구하세요. 같은 validatemessage 를 넣되 15자 이상으로, 무엇을 고쳐야 하는지 알 수 있게 쓰세요.
  4. kyverno apply /root/policy/validate/require-labels.yaml --resource /opt/lab/fixtures/policy/resources/good-pod.yaml 을 실행해 결과를 /root/policy/validate/out/pass.txt 로 저장하세요. 결과에 require-labels 라는 정책 이름과 통과 표시가 보여야 하고, 실패 건수는 0 이어야 합니다.
  5. 같은 정책을 /opt/lab/fixtures/policy/resources/bad-pod.yaml 로 돌려 /root/policy/validate/out/fail.txt 로 저장하세요(실패 건수 1 이상, 정책 이름 포함). 그리고 /root/policy/validate/out/fail-note.txt 에 어떤 라벨이 없어서 걸렸는지 한국어로 적으세요.
  6. /root/policy/validate/restrict-registry.yaml 에 두 번째 ClusterPolicy 를 만드세요. 규칙에 validate.deny.conditions.all(또는 any)을 쓰고, 허용 레지스트리로 registry.labhub.io 를 넣어 그 밖의 이미지를 거부하게 하세요. 그다음 /opt/lab/fixtures/policy/resources/bad-registry.yaml 로 돌린 결과를 /root/policy/validate/out/registry.txt 로 저장하세요(거부/실패가 보여야 합니다).
  7. restrict-registry.yaml 의 규칙에 preconditions 를 추가하세요. {{ request.operation }} 같은 요청 컨텍스트 변수를 써서 CREATE·UPDATE 일 때만 규칙이 돌게 합니다. 그리고 /root/policy/validate/out/precondition-note.txt 에 preconditions 와 deny 의 차이를 적으세요 — preconditions 가 거짓이면 규칙이 건너뛰어진다는 점과, deny 는 규칙이 실행된 결과로 거부한다는 점이 둘 다 들어가야 합니다.
  8. require-labels.yaml 을 good-pod 와 bad-pod 둘 다 --resource 로 넣고 --policy-report 로 실행해 /root/policy/validate/out/policy-report.yaml 로 저장하세요(summary.pass 1 이상, summary.fail 1 이상). 그리고 /root/policy/validate/exception.yamlkind: PolicyException 을 만들어 spec.exceptions[0].policyNamerequire-labels, ruleNamescheck-required-labels, spec.match.any[0].resources.nameslegacy-batch-* 처럼 이름 단위로 좁히세요.

참고

정책 뼈대와 강제 모드 정하기

/root/policy/validate/require-labels.yaml 을 만드세요. apiVersion: kyverno.io/v1, kind: ClusterPolicy, metadata.namerequire-labels 입니다. spec.validationFailureActionEnforce 로(또는 규칙의 validate.failureActionEnforce 로), spec.backgroundtrue 로 두고, spec.rules[0].namecheck-required-labels 로 지으세요.

ClusterPolicy 는 kyverno.io 그룹의 CRD 입니다. 실패 시 막을지 기록만 할지, 그리고 기존 리소스도 검사 대상으로 볼지를 spec 에서 정합니다.

적용 대상과 제외 대상 좁히기

같은 규칙에 match.any[0].resources.kindsPod 를, namespacespol-lab 을 지정하세요. 그리고 규칙에 exclude.any[0].resources.namespaceskube-system 을 빼세요.

match 는 any 아래에 resources 로 종류와 네임스페이스를 적습니다. 짝이 되는 exclude 를 빼먹으면 시스템 네임스페이스까지 대상이 됩니다.

필수 라벨 패턴과 거부 메시지 쓰기

validate.pattern.metadata.labels 아래에 app.kubernetes.io/nameteam 두 라벨을 각각 "?*" 로 요구하세요. 같은 validatemessage 를 넣되 15자 이상으로, 무엇을 고쳐야 하는지 알 수 있게 쓰세요.

pattern 은 검사할 오브젝트와 같은 모양으로 씁니다. "있기만 하면 된다"는 뜻의 연산자가 따로 있습니다. 메시지는 거부당한 사람이 읽는 유일한 문서입니다.

통과해야 할 파드로 돌려 보기

kyverno apply /root/policy/validate/require-labels.yaml --resource /opt/lab/fixtures/policy/resources/good-pod.yaml 을 실행해 결과를 /root/policy/validate/out/pass.txt 로 저장하세요. 결과에 require-labels 라는 정책 이름과 통과 표시가 보여야 하고, 실패 건수는 0 이어야 합니다.

kyverno CLI 는 정책 파일과 --resource 로 받은 매니페스트를 로컬에서 평가합니다. 결과에 정책 이름이 보이도록 출력 형식을 고르세요.

위반 파드로 돌려 원인 적기

같은 정책을 /opt/lab/fixtures/policy/resources/bad-pod.yaml 로 돌려 /root/policy/validate/out/fail.txt 로 저장하세요(실패 건수 1 이상, 정책 이름 포함). 그리고 /root/policy/validate/out/fail-note.txt 에 어떤 라벨이 없어서 걸렸는지 한국어로 적으세요.

통과만 확인하면 아무것도 매칭하지 않는 정책과 구분할 수 없습니다. 실패가 있으면 종료 코드가 1이라는 점도 기억하세요.

레지스트리를 제한하는 deny 규칙 쓰기

/root/policy/validate/restrict-registry.yaml 에 두 번째 ClusterPolicy 를 만드세요. 규칙에 validate.deny.conditions.all(또는 any)을 쓰고, 허용 레지스트리로 registry.labhub.io 를 넣어 그 밖의 이미지를 거부하게 하세요. 그다음 /opt/lab/fixtures/policy/resources/bad-registry.yaml 로 돌린 결과를 /root/policy/validate/out/registry.txt 로 저장하세요(거부/실패가 보여야 합니다).

"목록 안에 없으면 거부" 같은 조건은 pattern 으로 표현하기 어렵습니다. conditions 아래 any 와 all 중 무엇이 맞는지 생각해 보세요.

preconditions 로 규칙 적용 범위 좁히기

restrict-registry.yaml 의 규칙에 preconditions 를 추가하세요. {{ request.operation }} 같은 요청 컨텍스트 변수를 써서 CREATE·UPDATE 일 때만 규칙이 돌게 합니다. 그리고 /root/policy/validate/out/precondition-note.txt 에 preconditions 와 deny 의 차이를 적으세요 — preconditions 가 거짓이면 규칙이 건너뛰어진다는 점과, deny 는 규칙이 실행된 결과로 거부한다는 점이 둘 다 들어가야 합니다.

preconditions 가 거짓이면 규칙은 평가조차 되지 않습니다. deny 와 무엇이 다른지 파일로 정리해야 통과합니다.

정책 리포트와 좁은 예외 만들기

require-labels.yaml 을 good-pod 와 bad-pod 둘 다 --resource 로 넣고 --policy-report 로 실행해 /root/policy/validate/out/policy-report.yaml 로 저장하세요(summary.pass 1 이상, summary.fail 1 이상). 그리고 /root/policy/validate/exception.yamlkind: PolicyException 을 만들어 spec.exceptions[0].policyNamerequire-labels, ruleNamescheck-required-labels, spec.match.any[0].resources.nameslegacy-batch-* 처럼 이름 단위로 좁히세요.

통과 1건과 실패 1건이 한 리포트 요약에 같이 담기려면 리소스를 둘 다 넣어야 합니다. 예외는 정책 이름·규칙 이름·리소스 이름까지 좁히세요.