LabHub
배우기 러닝패스 코스

KCA — Kyverno認定アソシエイト

注入・生成の規則と権限を立てる

LabHub 에서 이어서 보기

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

목표

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.patchStrategicMergemetadata.labelskca.io/managed-bykyverno 로 넣게 하세요.
  2. 같은 파일에 규칙 inject-sidecar 를 추가하세요. match.any[0].resources.selector.matchLabelskca.io/inject 로 대상을 고르고, mutate.patchStrategicMerge.spec.template.spec.containers[0] 에 name log-collector, image, 그리고 resources.limitsmemorycpu 를 모두 넣으세요.
  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.apiVersionnetworking.k8s.io/v1, kindNetworkPolicy, namedefault-deny, namespace 는 새 네임스페이스 이름을 받는 변수, synchronizetrue, generate.data.spec.policyTypes 에는 IngressEgress 를 넣으세요.
  5. /root/kca-mutate/generate-clone.yaml 에 kind ClusterPolicy, metadata.name kca-clone-baseline 을 쓰세요. generate.kindConfigMap, namekca-baseline, clone.namespacekca-shared, clone.namekca-baseline-config, synchronizetrue 이고 data 는 쓰지 마세요.
  6. 클러스터에 네임스페이스 kca-shared 를 만들고 그 안에 Role kca-clone-reader 를 실제로 만드세요. 코어 그룹의 configmapsget, 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=inforetention=7d 두 개입니다. 그 뒤 kubectl auth can-i 로 해당 서비스어카운트가 이 네임스페이스의 configmaps 는 읽을 수 있고 secrets 는 읽을 수 없는지 확인하세요.

참고

patchStrategicMerge 로 라벨 주입

/root/kca-mutate/ 디렉터리를 만들고 mutate-labels.yaml 에 kind ClusterPolicy, metadata.name kca-add-team-label 을 쓰세요. 규칙 add-managed-by 를 만들어 match 의 kinds 에 Deployment 를 넣고, mutate.patchStrategicMergemetadata.labelskca.io/managed-bykyverno 로 넣게 하세요.

mutate 블록 안에 오브젝트 모양을 그대로 그리면 그 부분만 병합됩니다. 라벨 키에 점과 슬래시가 있으면 YAML 에서 따옴표로 감싸세요.

사이드카 주입과 리소스 리밋

같은 파일에 규칙 inject-sidecar 를 추가하세요. match.any[0].resources.selector.matchLabelskca.io/inject 로 대상을 고르고, mutate.patchStrategicMerge.spec.template.spec.containers[0] 에 name log-collector, image, 그리고 resources.limitsmemorycpu 를 모두 넣으세요.

주입하는 컨테이너에 리소스 리밋을 반드시 넣어야 합니다. mutate 가 validate 보다 먼저 돈다는 사실이 왜 여기서 중요한지 떠올리세요. 그리고 모든 워크로드가 아니라 라벨로 고른 것에만 주입되게 하세요.

JSON Patch 로 어노테이션 추가

/root/kca-mutate/mutate-json6902.yaml 에 kind ClusterPolicy 를 쓰고 spec.rules[0].mutate.patchesJson6902 로 어노테이션 kca.io/owner 를 추가하는 add 연산을 작성하세요. 경로는 /metadata/annotations/ 아래이며 키의 슬래시를 이스케이프해야 합니다.

JSON Pointer 는 슬래시로 경로를 나눕니다. 키 이름 자체에 슬래시가 들어가면 특별한 이스케이프가 필요하고, 그 표기를 모르면 경로가 엉뚱한 곳을 가리킵니다.

네임스페이스마다 default-deny 생성

/root/kca-mutate/generate-netpol.yaml 에 kind ClusterPolicy, metadata.name kca-generate-default-deny 를 쓰세요. match 의 kinds 는 Namespace, generate.apiVersionnetworking.k8s.io/v1, kindNetworkPolicy, namedefault-deny, namespace 는 새 네임스페이스 이름을 받는 변수, synchronizetrue, generate.data.spec.policyTypes 에는 IngressEgress 를 넣으세요.

generate 는 무엇을(apiVersion/kind), 어떤 이름으로, 어느 네임스페이스에 만들지를 모두 적어야 합니다. 대상 네임스페이스는 방금 만들어진 그 네임스페이스이므로 변수로 받습니다.

clone 방식으로 복제하기

/root/kca-mutate/generate-clone.yaml 에 kind ClusterPolicy, metadata.name kca-clone-baseline 을 쓰세요. generate.kindConfigMap, namekca-baseline, clone.namespacekca-shared, clone.namekca-baseline-config, synchronizetrue 이고 data 는 쓰지 마세요.

clone 은 원본의 네임스페이스와 이름을 지정합니다. data 와 함께 쓸 수 없다는 점, 그리고 원본 변경을 따라가게 하려면 어떤 필드가 필요한지 확인하세요.

복제 원본을 읽을 Role 만들기

클러스터에 네임스페이스 kca-shared 를 만들고 그 안에 Role kca-clone-reader 를 실제로 만드세요. 코어 그룹의 configmapsget, list, watch 만 허용하고 delete 는 넣지 마세요.

여기서부터 실제 클러스터입니다. 읽기만 필요하므로 동사는 세 개면 충분하고, 코어 그룹 리소스의 apiGroups 는 빈 문자열입니다.

백그라운드 컨트롤러에 바인딩

클러스터에 네임스페이스 kyverno 와 그 안의 ServiceAccount kyverno-background-controller 를 만들고, kca-shared 에 RoleBinding kca-clone-reader 를 실제로 만들어 Role kca-clone-reader 를 그 서비스어카운트에 묶으세요.

대상은 kyverno 네임스페이스의 서비스어카운트입니다. 그 네임스페이스와 서비스어카운트도 이 실습 환경에는 없으니 함께 만들어야 합니다.

원본 컨피그맵과 권한 검증

kca-shared 에 ConfigMap kca-baseline-config 를 실제로 만드세요. 데이터는 log-level=inforetention=7d 두 개입니다. 그 뒤 kubectl auth can-i 로 해당 서비스어카운트가 이 네임스페이스의 configmaps 는 읽을 수 있고 secrets 는 읽을 수 없는지 확인하세요.

복제 원본이 실제로 있어야 clone 이 성립합니다. 그리고 kubectl auth can-i 에 --as 로 서비스어카운트를 흉내 내면 권한이 제대로 붙었는지 손으로 확인할 수 있습니다.