LabHub
배우기 러닝패스 코스

Policy as Code

A Generation Policy That Automates Tenant Onboarding

LabHub 에서 이어서 보기

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

목표

새 테넌트 네임스페이스가 만들어지는 순간 기본 보안·자원 리소스가 함께 생기도록 하는 생성 정책을 쓰고, 그 정책이 실제 클러스터에서 동작하려면 무엇이 더 필요한지까지 갖춥니다.

왜 중요한가

새 팀에게 네임스페이스를 하나 내주는 일은 보통 체크리스트로 굴러갑니다. NetworkPolicy 를 걸고, ResourceQuota 를 씌우고, LimitRange 를 넣고, 레지스트리 시크릿을 복사한다. 사람이 하면 언젠가 한 단계를 빠뜨리고, 빠뜨린 것이 하필 기본 차단 정책이면 그 네임스페이스만 몇 달 동안 열려 있게 됩니다. 생성 규칙은 이 체크리스트를 네임스페이스 생성 이벤트에 묶어 버립니다. 여기서 세 가지를 배웁니다. 첫째, 트리거 범위를 라벨로 좁히지 않으면 시스템 네임스페이스까지 대상이 됩니다. 둘째, 시크릿처럼 내용을 정책 파일에 적으면 안 되는 것은 clone 으로 원본만 가리킵니다 — 정책은 git 에 들어가니까요. 셋째, 백그라운드 컨트롤러는 최소 권한으로 설치되므로 만들 리소스 종류의 권한을 따로 붙여야 하고, 권한이 없으면 요청은 성공하고 리소스만 조용히 안 생깁니다. 이 환경에서는 컨트롤러가 돌지 않아 실제 리소스가 생기지는 않고, kyverno CLI 로 로컬 평가한 결과와 정책 YAML 구조로 채점합니다.

단계

  1. /root/policy/generate/add-networkpolicy.yamlkind: ClusterPolicy 를 만드세요. spec.rules[0].generateapiVersion: networking.k8s.io/v1, kind: NetworkPolicy, name: default-deny 를 적고, generate.data.specpodSelector: {}policyTypes 를 두되 Ingress 를 반드시 포함하세요.
  2. 같은 규칙의 match.any[0].resources.kindsNamespace 로 하고, selector.matchLabelslabhub.io/tenant: "true" 를 적어 테넌트 네임스페이스에만 반응하게 하세요.
  3. generate.synchronizetrue 로 두세요. 그리고 /root/policy/generate/out/sync-note.txt 에 켰을 때의 동작(누가 손으로 고치면 되돌린다)과 껐을 때의 차이(만들 때 한 번만 관여한다)를 둘 다 적으세요.
  4. /root/policy/generate/clone-registry-secret.yaml 을 만드세요. generate.kindSecret, generate.clone.namespacepol-lab, generate.clone.nameregistry-creds 입니다. generate.data 는 쓰면 안 되고, 정책 파일 안에 시크릿 내용이 들어가서도 안 됩니다.
  5. add-networkpolicy.yamlgenerate.namespace"{{ request.object.metadata.name }}" 로, generate.name 을 명시하세요. 그리고 /root/policy/generate/out/vars-note.txt 에 정책에서 쓸 수 있는 변수를 정리하되 request.object 와 요청자 정보를 담은 변수(request.operation 또는 request.userInfo)를 반드시 포함하세요.
  6. /root/policy/generate/background-rbac.yamlkind: ClusterRole 을 만드세요. rulesnetworkpolicies 를 포함하고 verbscreateupdate 를 넣으세요(동기화를 켰으니 갱신도 필요합니다). metadata.labelsrbac.kyverno.io/aggregate-to-background-controller: "true" 같은 집계 라벨을 다세요.
  7. kyverno apply /root/policy/generate/add-networkpolicy.yaml --resource /opt/lab/fixtures/policy/resources/target-ns.yaml 을 실행하고, 생성된 NetworkPolicy 매니페스트만 /root/policy/generate/out/generated.txt 로 저장하세요. 실행 요약 줄(pass: ..., error: 0 ...)은 넣지 마세요.
  8. /root/policy/generate/tenant-onboarding.yaml 에 규칙 3개짜리 정책을 만드세요. 각 규칙이 각각 NetworkPolicy·ResourceQuota·LimitRange 를 생성하고, 규칙 이름은 서로 달라야 하며, 세 규칙 모두 generate.synchronize: true 여야 합니다. 그리고 /root/policy/generate/out/onboarding-report.jsontrigger_namespacetenant-alpha 로, generated 배열에 생성될 리소스 3건 이상을 kind 키를 포함해 담으세요(ResourceQuota 가 반드시 들어가야 합니다).

참고

기본 NetworkPolicy 를 만드는 규칙 쓰기

/root/policy/generate/add-networkpolicy.yamlkind: ClusterPolicy 를 만드세요. spec.rules[0].generateapiVersion: networking.k8s.io/v1, kind: NetworkPolicy, name: default-deny 를 적고, generate.data.specpodSelector: {}policyTypes 를 두되 Ingress 를 반드시 포함하세요.

생성 규칙은 만들 리소스의 apiVersion·kind·name·namespace 를 먼저 적습니다. 내용을 정책에 직접 쓰는 키가 따로 있습니다.

트리거와 대상 셀렉터 좁히기

같은 규칙의 match.any[0].resources.kindsNamespace 로 하고, selector.matchLabelslabhub.io/tenant: "true" 를 적어 테넌트 네임스페이스에만 반응하게 하세요.

무엇이 만들어질 때 반응할지를 match 에 적습니다. 모든 네임스페이스에 만들면 시스템 네임스페이스까지 대상이 되니 라벨로 좁히세요.

동기화 켜고 그 의미 정리하기

generate.synchronizetrue 로 두세요. 그리고 /root/policy/generate/out/sync-note.txt 에 켰을 때의 동작(누가 손으로 고치면 되돌린다)과 껐을 때의 차이(만들 때 한 번만 관여한다)를 둘 다 적으세요.

켜면 만든 뒤에도 계속 지켜봅니다. 껐을 때와 무엇이 달라지는지를 파일로 적어야 통과합니다.

원본을 복사하는 clone 규칙 쓰기

/root/policy/generate/clone-registry-secret.yaml 을 만드세요. generate.kindSecret, generate.clone.namespacepol-lab, generate.clone.nameregistry-creds 입니다. generate.data 는 쓰면 안 되고, 정책 파일 안에 시크릿 내용이 들어가서도 안 됩니다.

시크릿 내용을 정책 파일에 적으면 정책이 곧 유출 경로가 됩니다. 원본이 어디에 있는지만 알려 주는 방식이 있고, 내용을 직접 적는 키와는 함께 쓸 수 없습니다.

요청 컨텍스트 변수로 대상 정하기

add-networkpolicy.yamlgenerate.namespace"{{ request.object.metadata.name }}" 로, generate.name 을 명시하세요. 그리고 /root/policy/generate/out/vars-note.txt 에 정책에서 쓸 수 있는 변수를 정리하되 request.object 와 요청자 정보를 담은 변수(request.operation 또는 request.userInfo)를 반드시 포함하세요.

만들어진 네임스페이스 이름은 요청 오브젝트에서 꺼냅니다. 정책에서 쓸 수 있는 변수 세 가지를 정리해야 통과합니다.

생성 권한을 위한 ClusterRole 쓰기

/root/policy/generate/background-rbac.yamlkind: ClusterRole 을 만드세요. rulesnetworkpolicies 를 포함하고 verbscreateupdate 를 넣으세요(동기화를 켰으니 갱신도 필요합니다). metadata.labelsrbac.kyverno.io/aggregate-to-background-controller: "true" 같은 집계 라벨을 다세요.

백그라운드 컨트롤러는 스스로 아무 권한이 없습니다. 동기화를 켰다면 만드는 것 말고 갱신도 필요합니다. 권한을 모아 가는 집계 라벨도 잊지 마세요.

트리거 리소스로 돌려 생성 결과 저장하기

kyverno apply /root/policy/generate/add-networkpolicy.yaml --resource /opt/lab/fixtures/policy/resources/target-ns.yaml 을 실행하고, 생성된 NetworkPolicy 매니페스트만 /root/policy/generate/out/generated.txt 로 저장하세요. 실행 요약 줄(pass: ..., error: 0 ...)은 넣지 마세요.

저장할 것은 생성된 리소스 매니페스트입니다. 실행 요약 줄은 넣지 마세요 — 채점이 오류 문자열을 찾습니다.

온보딩 정책 묶음과 결과 보고서 만들기

/root/policy/generate/tenant-onboarding.yaml 에 규칙 3개짜리 정책을 만드세요. 각 규칙이 각각 NetworkPolicy·ResourceQuota·LimitRange 를 생성하고, 규칙 이름은 서로 달라야 하며, 세 규칙 모두 generate.synchronize: true 여야 합니다. 그리고 /root/policy/generate/out/onboarding-report.jsontrigger_namespacetenant-alpha 로, generated 배열에 생성될 리소스 3건 이상을 kind 키를 포함해 담으세요(ResourceQuota 가 반드시 들어가야 합니다).

네트워크·할당량·기본 리소스 세 가지를 한 정책 안 서로 다른 규칙으로 만듭니다. 규칙 이름이 겹치면 안 되고 전부 동기화가 켜져 있어야 합니다.