KCA — Kyverno 인증 어소시에이트 · mutate 와 generate · 실습
주입·생성 규칙과 권한 세우기
목표
mutate 두 방식과 generate 두 방식을 매니페스트로 작성하고, generate 가 실제로 동작하는 데 필요한 RBAC 을 클러스터에 직접 세워 권한까지 검증합니다.
왜 중요한가
generate 규칙은 Kyverno 에서 가장 조용하게 실패하는 기능입니다. admission 은 성공하므로 kubectl 은 아무 오류도 내지 않고, 리소스만 생기지 않습니다. 원인은 대개 두 가지인데 match 가 안 됐거나 background 컨트롤러에 권한이 없는 것입니다. 이 실습에서 권한을 직접 만들고 auth can-i 로 확인해 보면, 나중에 현장에서 생성물이 안 보일 때 정책 YAML 을 뒤지는 대신 UpdateRequest 와 권한을 먼저 보게 됩니다. 사이드카 주입에 리소스 리밋을 함께 넣는 습관도 같은 종류의 예방 조치입니다.
단계
1. /root/kca-mutate/ 디렉터리를 만들고 mutate-labels.yaml 에 kind ClusterPolicy, metadata.name kca-add-team-label 을 쓰세요. 규칙 add-managed-by 를 만들어 match 의 kinds 에 Deployment 를 넣고, mutate.patchStrategicMerge 로 metadata.labels 의 kca.io/managed-by 를 kyverno 로 넣게 하세요.
2. 같은 파일에 규칙 inject-sidecar 를 추가하세요. match.any[0].resources.selector.matchLabels 의 kca.io/inject 로 대상을 고르고, mutate.patchStrategicMerge.spec.template.spec.containers[0] 에 name log-collector, image, 그리고 resources.limits 의 memory 와 cpu 를 모두 넣으세요.
3. /root/kca-mutate/mutate-json6902.yaml 에 kind ClusterPolicy 를 쓰고 spec.rules[0].mutate.patchesJson6902 로 어노테이션 kca.io/owner 를 추가하는 add 연산을 작성하세요. 경로는 /metadata/annotations/ 아래이며 키의 슬래시를 이스케이프해야 합니다.
4. /root/kca-mutate/generate-netpol.yaml 에 kind ClusterPolicy, metadata.name kca-generate-default-deny 를 쓰세요. match 의 kinds 는 Namespace, generate.apiVersion 은 networking.k8s.io/v1, kind 는 NetworkPolicy, name 은 default-deny, namespace 는 새 네임스페이스 이름을 받는 변수, synchronize 는 true, generate.data.spec.policyTypes 에는 Ingress 와 Egress 를 넣으세요.
5. /root/kca-mutate/generate-clone.yaml 에 kind ClusterPolicy, metadata.name kca-clone-baseline 을 쓰세요. generate.kind 는 ConfigMap, name 은 kca-baseline, clone.namespace 는 kca-shared, clone.name 은 kca-baseline-config, synchronize 는 true 이고 data 는 쓰지 마세요.
6. 클러스터에 네임스페이스 kca-shared 를 만들고 그 안에 Role kca-clone-reader 를 실제로 만드세요. 코어 그룹의 configmaps 에 get, list, watch 만 허용하고 delete 는 넣지 마세요.
7. 클러스터에 네임스페이스 kyverno 와 그 안의 ServiceAccount kyverno-background-controller 를 만들고, kca-shared 에 RoleBinding kca-clone-reader 를 실제로 만들어 Role kca-clone-reader 를 그 서비스어카운트에 묶으세요.
8. kca-shared 에 ConfigMap kca-baseline-config 를 실제로 만드세요. 데이터는 log-level=info 와 retention=7d 두 개입니다. 그 뒤 kubectl auth can-i 로 해당 서비스어카운트가 이 네임스페이스의 configmaps 는 읽을 수 있고 secrets 는 읽을 수 없는지 확인하세요.
참고
kubectl create role kca-clone-reader --verb=get,list,watch --resource=configmaps -n kca-shared로 빠르게 만들 수 있습니다.- 권한 확인은
kubectl auth can-i get configmaps --as=system:serviceaccount:kyverno:kyverno-background-controller -n kca-shared입니다. - 흔한 실수 1: generate 에 clone 과 data 를 같이 쓰는 것. 둘 중 하나만 고릅니다.
- 흔한 실수 2: JSON Patch 경로에서 키의 슬래시를 그대로 두는 것. 경로 구분자와 구별되지 않습니다.
단계 8개
- patchStrategicMerge 로 라벨 주입
- 사이드카 주입과 리소스 리밋
- JSON Patch 로 어노테이션 추가
- 네임스페이스마다 default-deny 생성
- clone 방식으로 복제하기
- 복제 원본을 읽을 Role 만들기
- 백그라운드 컨트롤러에 바인딩
- 원본 컨피그맵과 권한 검증