LabHub
배우기 러닝패스 코스

KCA — Kyverno Certified Associate

Having Written a Policy and Having It Enforced Are Different

LabHub 에서 이어서 보기

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

한 줄 요약

Kyverno 는 막는 것이 존재 이유인데, 막는 부분이 없는 환경에서는 정책을 썼다는 사실 외에 아무것도 확인되지 않습니다.

Concept map: CRD만 적재된 환경 · 막는 것이 존재 이유 · validate 보다 먼저 · 뒤

왜 진짜 어드미션이어야 하나

초기 정책 작성 실습의 CRD만 적재된 환경에서는 저장 성공과 실제 정책 실행을 구분해야 합니다. 이 모듈과 웹훅 장애 실습은 컨트롤러가 실행되는 실제 VM에서 정상 요청과 위반 요청을 비교합니다.

Kyverno 는 어드미션 컨트롤러입니다. 막는 것이 존재 이유인데, 막는 부분이 없는 환경에서 배운 셈입니다.

세 동작은 시점이 다릅니다

동작 언제 무엇을
mutate 어드미션, validate 보다 먼저 요청을 고친다
validate 어드미션 거절하거나 통과시킨다
generate 어드미션 , 별도 컨트롤러가 다른 오브젝트를 만든다

이 순서를 알면 정책을 조합할 수 있습니다. "없으면 넣어 준다"(mutate)와 "반드시 있어야 한다"(validate)를 함께 두면 사용자는 아무것도 안 해도 통과합니다.

그리고 generate 가 어드미션 밖이라는 것이 두 가지를 낳습니다 — 별도 권한이 필요하고, 즉시 만들어지지 않습니다. 권한이 없으면 정책은 멀쩡한데 아무것도 안 만들어지고, 오류는 Kyverno 로그 안에만 있습니다.

가장 위험한 것은 조용한 실패

Kyverno 파드가 Running 이어도 웹훅 설정이 없으면 아무 일도 일어나지 않습니다. 정책은 그대로 있고 오류도 없습니다. 정책을 다 써 두고 하나도 적용되지 않은 상태가 정상처럼 보입니다.

그래서 정책을 쓴 뒤에는 반드시 막히는지 직접 시험해야 합니다.

정책 하나가 클러스터를 잠글 수 있습니다

정책의 적용 대상에 들어온 시스템 Pod가 요구 조건을 위반하면 재생성이 거부될 수 있습니다. 그렇다고 모든 정책이 시스템을 막거나, 기존 Pod가 즉시 종료되거나, 정책 삭제까지 항상 막히는 것은 아닙니다. 실제 요청 종류·대상 범위·복구 경로를 확인해야 합니다.

정책을 배포하는 순서

새 정책은 위반 현황을 수집하고 팀이 수정할 시간을 확보한 뒤 강제합니다.

1. Audit + 보고서        적용 대상의 위반을 수집한다
2. 수정·예외·복구 시험   정상 요청과 위반 요청을 모두 시험한다
3. Enforce + 관찰        위반 요청을 거부하고 영향을 관찰한다

이 실습의 Kyverno ClusterPolicy는 Audit → Enforce입니다. Warn은 이 필드의 세 번째 값이 아닙니다. Audit 위반을 응답 경고로 알리려면 spec.emitWarning을 함께 설정합니다. 다른 정책 엔진의 모드 이름을 이 API에 그대로 넣지 마세요.

위반 목록에서 수정할 항목과 승인된 예외를 구분하고 적용 범위별로 전환합니다. 기존 Pod가 계속 실행되는 것만으로 다음 배포도 통과한다고 판단하지 않습니다.

# Kyverno — 지금 걸리는 것들
kubectl get policyreport -A -o json | jq -r '
  .items[].results[] | select(.result=="fail") |
  "\(.policy): \(.resources[0].namespace)/\(.resources[0].name)"' | sort | uniq -c

자기 자신을 잠그지 않기

정책이 시스템 구성요소의 복구 요청을 거부하면 장애를 키울 수 있습니다. 다음은 라벨 규칙에 둘 수 있는 예외의 부분 예시입니다. 모든 시스템 보안 정책에 무조건 적용하는 목록도, 웹훅 호출을 제외하는 설정도 아닙니다.

spec:
  rules:
    - name: require-nonroot
      match:
        any:
          - resources: {kinds: [Pod]}
      exclude:
        any:
          - resources:
              namespaces: [kube-system, kyverno, gatekeeper-system]

등록된 웹훅 호출이 실패하면 failurePolicy: Fail은 해당 요청을 거부하고, Ignore는 그 웹훅을 건너뛰어 나머지 처리를 계속합니다. 정상 응답으로 명시한 정책 위반 거부는 Ignore여도 유효합니다. 정책 객체가 삭제되는 것도, 다른 정책의 검사까지 무시되는 것도 아닙니다.

정책 규칙의 exclude는 엔진 내부에서 적용됩니다. API 서버의 실제 호출 범위는 WebhookConfiguration의 rules·namespaceSelector·objectSelector 등으로 확인합니다. 엔진 장애 시 자기 복구 요청을 제외하려면 이 호출 단계까지 봐야 합니다. 검증 생략 위험과 가용성을 비교하고 승인된 복구 경로를 시험하세요.

웹훅 등록이 없는 상태등록은 있지만 응답하지 않는 상태도 다릅니다. 후속 장애 실습에서는 두 상태를 따로 만들고 요청 결과와 실제 등록을 비교합니다.

변형(mutate)이 검증보다 먼저다

어드미션 순서는 정해져 있습니다.

변형 웹훅 → 스키마 검증 → 검증 웹훅 → etcd 저장

그래서 "기본값을 채워 주는 정책" 과 "그 필드를 요구하는 정책" 을 함께 두면 자동으로 통과합니다. 사용자가 안 적어도 변형이 채우고 검증이 확인합니다.

다만 변형은 사용자가 모르게 바꾼다 는 점을 잊으면 안 됩니다. kubectl get -o yaml 로 저장된 결과가 자기가 쓴 것과 다르면 혼란스럽습니다. 변형 정책은 무엇을 바꾸는지 문서에 적고, 가능하면 애노테이션으로 흔적을 남깁니다.

실무에서 진짜 중요한 것

정책을 배포한 뒤에는 정상·위반 오브젝트를 모두 시험합니다. 컨트롤러가 Running인 것만으로 웹훅 등록과 요청 처리가 보장되지는 않습니다. 생성 명령의 종료 코드뿐 아니라 거부 메시지와 저장 여부도 확인합니다.

정책 범위를 넓힐 때 시스템 복구를 시험합니다. 규칙 예외와 웹훅 호출 제외를 구분하고, 실제 시스템 워크로드가 요구 조건을 만족하는지 확인합니다. 운영 중인 클러스터 전체에 장애 실험을 적용하지 않습니다.

generate가 동작하지 않으면 대상 일치와 백그라운드 컨트롤러 권한을 함께 봅니다. 로그의 Forbidden은 권한 조사의 근거이지만, 출력이 없다는 사실만으로 원인을 확정할 수는 없습니다.

다음 실습에서 이것들을 진짜 Kyverno 위에서 직접 확인합니다.

공식 문서로 확인하기

이 실습의 고정 버전은 Kyverno 1.19.1입니다. 최신 문서의 API를 기존 VM에 그대로 적용하지 말고 설치 버전의 CRD와 함께 확인하세요.