LabHub
배우기 러닝패스 코스

ポリシーをコードで

既定値を埋めてくれる変形ポリシーを書く

LabHub 에서 이어서 보기

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

목표

빠진 값을 채워 주는 변형 정책을 세 가지 방식으로 쓰고, 이미 지정된 값은 건드리지 않는다는 것을 직접 확인합니다. 마지막에는 무엇이 어떻게 바뀌었는지 대조 보고서를 만듭니다.

왜 중요한가

막기만 하는 정책은 문제를 사용자에게 떠넘깁니다. 리밋 없는 파드를 전부 거부하면 규칙은 지켜지지만 팀마다 "얼마를 넣어야 하나요"라는 질문이 생깁니다. 변형 정책은 조직의 기본값을 대신 채워 넣어 규칙을 지키면서 아무도 막지 않습니다. 다만 여기에는 넘지 말아야 할 선이 있습니다 — 사용자가 명시한 값은 절대 덮어쓰지 않는 것입니다. 팀이 cpu: 500m 이라고 적었는데 정책이 조용히 바꿔 버리면 그 팀은 자기 매니페스트를 믿을 수 없게 되고, 그때부터 정책은 신뢰가 아니라 공포의 대상이 됩니다. 그래서 추가 앵커 +() 는 문법 장식이 아니라 계약입니다. 참고로 이 환경에는 어드미션 웹훅이 돌지 않으므로 변형은 kyverno CLI 로 로컬 평가해 결과 매니페스트를 확인합니다.

단계

  1. /root/policy/mutate/add-team-label.yamlkind: ClusterPolicy 를 만드세요. spec.background 를 명시하고, spec.rules[0].mutate.patchStrategicMerge.metadata.labels 아래에 +(team): unassigned 를 넣으세요. 규칙 이름은 add-default-team, 매치는 pol-lab 네임스페이스의 Pod 입니다.
  2. /root/policy/mutate/add-defaults.yaml 에 두 번째 정책을 만들고, +(...) 추가 앵커로 컨테이너의 resources.limitscpumemory 기본값을 채우는 규칙을 쓰세요. 그리고 /root/policy/mutate/out/anchors.md (150바이트 이상)에 조건 앵커 (), 추가 앵커 +(), 그리고 =() 또는 X() 의 차이를 정리하세요.
  3. 같은 add-defaults.yamlmutate.patchesJson6902 를 쓰는 규칙을 하나 더 넣으세요. op: addpath: /spec/containers/0/imagePullPolicy, value: IfNotPresent 형태입니다. 그리고 /root/policy/mutate/out/json6902-note.txt 에 이 방식이 배열·인덱스를 다룰 때 왜 필요한지 적으세요.
  4. add-defaults.yamlmutate.foreach 규칙을 넣으세요. list: "request.object.spec.containers" 로 컨테이너 목록을 받고, 내부에서 element 변수로 현재 항목을 가리켜야 합니다.
  5. 두 정책을 /opt/lab/fixtures/policy/resources/bad-pod.yaml 에 적용하고, 변형된 Pod 매니페스트/root/policy/mutate/out/mutated.yaml 로 저장하세요. 그 파일에는 metadata.labels.team, spec.containers[0].resources.limits.memory, spec.containers[0].imagePullPolicy 세 값이 모두 채워져 있어야 합니다.
  6. 같은 두 정책을 /opt/lab/fixtures/policy/resources/good-pod.yaml 에 적용해 /root/policy/mutate/out/preserved.yaml 로 저장하세요. 이 파드에는 원래 team: platform 라벨과 cpu: 500m 제한이 있으며, 변형 뒤에도 그대로여야 합니다.
  7. /root/policy/mutate/mutate-existing.yaml 을 만드세요. spec.mutateExistingOnPolicyUpdate: true 를 두고, 규칙의 mutate.targetskind: Pod, namespace: pol-lab 을 적어 트리거가 아닌 리소스를 고치게 하세요. 그리고 /root/policy/mutate/out/existing-note.txt 에 이 동작이 백그라운드에서 돌기 때문에 추가 RBAC 권한이 필요하다는 점을 적으세요.
  8. /root/policy/mutate/out/mutate-report.json 을 만드세요. 최상위 mutations 배열에 3건 이상을 담고, 각 항목은 field·before·after·rule 네 키를 가져야 합니다. beforeafter 가 같은 항목은 넣지 마세요. fieldteam 이 들어간 항목의 after 값은 5번에서 만든 mutated.yamlmetadata.labels.team 값과 정확히 같아야 합니다.

참고

라벨을 덧붙이는 변형 정책 만들기

/root/policy/mutate/add-team-label.yamlkind: ClusterPolicy 를 만드세요. spec.background 를 명시하고, spec.rules[0].mutate.patchStrategicMerge.metadata.labels 아래에 +(team): unassigned 를 넣으세요. 규칙 이름은 add-default-team, 매치는 pol-lab 네임스페이스의 Pod 입니다.

변형은 mutate 아래에 씁니다. 맵에 필드를 더하는 데는 오브젝트와 같은 모양으로 쓰는 방식이 가장 읽기 쉽습니다. 이미 값이 있는 파드도 곧 다루게 되니 덮어쓰지 않는 표기를 처음부터 쓰세요.

추가 앵커로 자원 기본값 채우기

/root/policy/mutate/add-defaults.yaml 에 두 번째 정책을 만들고, +(...) 추가 앵커로 컨테이너의 resources.limitscpumemory 기본값을 채우는 규칙을 쓰세요. 그리고 /root/policy/mutate/out/anchors.md (150바이트 이상)에 조건 앵커 (), 추가 앵커 +(), 그리고 =() 또는 X() 의 차이를 정리하세요.

"없으면 넣고 있으면 두기"를 뜻하는 앵커가 따로 있습니다. 앵커 세 종류의 차이를 문서로 정리해야 통과합니다.

JSON 패치로 배열 항목 고치기

같은 add-defaults.yamlmutate.patchesJson6902 를 쓰는 규칙을 하나 더 넣으세요. op: addpath: /spec/containers/0/imagePullPolicy, value: IfNotPresent 형태입니다. 그리고 /root/policy/mutate/out/json6902-note.txt 에 이 방식이 배열·인덱스를 다룰 때 왜 필요한지 적으세요.

Strategic Merge 로는 "몇 번째 컨테이너"를 콕 집기 어렵습니다. op·path·value 세 가지로 위치를 지정하는 방식이 있습니다.

컨테이너 목록을 도는 규칙 쓰기

add-defaults.yamlmutate.foreach 규칙을 넣으세요. list: "request.object.spec.containers" 로 컨테이너 목록을 받고, 내부에서 element 변수로 현재 항목을 가리켜야 합니다.

컨테이너 개수를 모를 때는 인덱스를 쓸 수 없습니다. 목록을 받는 키와 현재 항목을 가리키는 변수 이름을 확인하세요.

정책을 돌려 변형 결과 저장하기

두 정책을 /opt/lab/fixtures/policy/resources/bad-pod.yaml 에 적용하고, 변형된 Pod 매니페스트/root/policy/mutate/out/mutated.yaml 로 저장하세요. 그 파일에는 metadata.labels.team, spec.containers[0].resources.limits.memory, spec.containers[0].imagePullPolicy 세 값이 모두 채워져 있어야 합니다.

두 정책 파일을 한 번에 넘길 수 있습니다. 저장할 것은 실행 요약이 아니라 변형된 파드 매니페스트입니다.

이미 있는 값이 보존되는지 확인하기

같은 두 정책을 /opt/lab/fixtures/policy/resources/good-pod.yaml 에 적용해 /root/policy/mutate/out/preserved.yaml 로 저장하세요. 이 파드에는 원래 team: platform 라벨과 cpu: 500m 제한이 있으며, 변형 뒤에도 그대로여야 합니다.

같은 정책을 값이 채워진 파드에 돌립니다. 원래 값이 바뀌었다면 앵커를 안 썼거나 잘못 쓴 것입니다.

이미 존재하는 리소스를 고치는 정책 쓰기

/root/policy/mutate/mutate-existing.yaml 을 만드세요. spec.mutateExistingOnPolicyUpdate: true 를 두고, 규칙의 mutate.targetskind: Pod, namespace: pol-lab 을 적어 트리거가 아닌 리소스를 고치게 하세요. 그리고 /root/policy/mutate/out/existing-note.txt 에 이 동작이 백그라운드에서 돌기 때문에 추가 RBAC 권한이 필요하다는 점을 적으세요.

트리거가 아니라 다른 리소스를 고치려면 대상을 따로 적어야 합니다. 정책을 고쳤을 때 기존 리소스도 손볼지 정하는 스위치도 있습니다.

변형 전후 대조 보고서 만들기

/root/policy/mutate/out/mutate-report.json 을 만드세요. 최상위 mutations 배열에 3건 이상을 담고, 각 항목은 field·before·after·rule 네 키를 가져야 합니다. beforeafter 가 같은 항목은 넣지 마세요. fieldteam 이 들어간 항목의 after 값은 5번에서 만든 mutated.yamlmetadata.labels.team 값과 정확히 같아야 합니다.

필드마다 전·후 값과 어느 규칙이 했는지를 담습니다. 값이 안 바뀐 항목은 변형이 아니므로 넣으면 안 됩니다.