본문 바로가기
클라우드/Kyverno

[Kyverno]퀵 스타트 가이드 (Quick Start Guides)

by gasbugs 2025. 12. 29.
"이 포스팅은 Kyverno 공식 문서의 Quick Start 내용을 바탕으로 이해를 돕기 위해 국문으로 번역 및 정리한 글입니다."
https://kyverno.io/blog/2023/11/16/kyverno-1.11-released/

 

 

Kyverno 정책 및 규칙 유형에 대한 소개

이 섹션은 Kyverno를 신속하게 설치 및 실행하고, Kyverno의 핵심 기능 몇 가지를 시연해 볼 수 있는 가이드를 제공합니다. 검증(Validation), 변이(Mutation), 생성(Generation)에 초점을 맞춘 가이드들이 준비되어 있어, 사용 사례에 가장 적합한 항목을 선택하여 진행할 수 있습니다.

주의: 이 가이드들은 개념 증명(PoC)이나 실습용으로 제작되었으며, 운영 환경용으로 권장되지 않습니다. 운영 환경 설치에 대한 자세한 정보는 [설치 페이지]를 참조하세요.

 

먼저, 최신 릴리스 매니페스트를 사용해 Kyverno를 설치합니다.

kubectl create -f https://github.com/kyverno/kyverno/releases/latest/download/install.yaml

 

그 다음, 관심 있는 퀵 스타트 가이드를 선택하세요. 또는 위에서부터 순서대로 진행해 보셔도 좋습니다.


1. 리소스 검증 (Validate Resources)

검증 가이드에서는 모든 Pod에 team이라는 레이블이 반드시 포함되도록 하는 간단한 정책 예시를 살펴봅니다. 검증은 정책의 가장 일반적인 사용 사례로, "예" 또는 "아니오"를 결정하는 의사 결정 프로세스 역할을 합니다. 정책을 준수하는 리소스는 통과 허용("예, 허용됨")되고, 준수하지 않는 리소스는 통과가 거부("아니오, 허용되지 않음")될 수 있습니다.

검증 정책의 또 다른 효과는 **정책 보고서(Policy Reports)**를 생성하는 것입니다. 정책 보고서는 Kyverno가 생성하고 관리하는 커스텀 리소스(CRD)로, 허용된 리소스에 대한 정책 결정 결과를 사용자가 보기 편한 방식으로 보여줍니다.

클러스터에 아래 정책을 추가하세요. 모든 Pod에 team 레이블을 요구하는 단일 검증 규칙이 포함되어 있습니다. (Kyverno는 검증 외에도 변이, 생성, 정리, 이미지 설정 확인 등 다양한 규칙 유형을 지원합니다.) failureAction 필드가 Enforce로 설정되어 있어 미준수 Pod를 차단합니다. 기본값인 Audit을 사용하면 위반 사항을 보고만 하고 요청을 차단하지는 않습니다.

YAML
kubectl create -f- << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  # 파드에 관련된 매칭이 발생하면 검사를 진행하는 check-team이라는 룰을 생성
  rules:
  - name: check-team
    match:
      any:
      - resources:
          kinds:
          - Pod
    # team이라는 레이블이 구성되어 있어야 함. 없으면 안 됨
    validate:
      failureAction: Enforce
      message: "label 'team' is required"
      pattern:
        metadata:
          labels:
            team: "?*"
EOF

 

필수 레이블 없이 Deployment를 생성해 봅니다.

kubectl create deployment nginx --image=nginx

 

다음과 같은 에러가 발생해야 합니다.

error: failed to create deployment: admission webhook "validate.kyverno.svc-fail" denied the request: 
resource Deployment/default/nginx was blocked due to the following policies:
require-labels:
  autogen-check-team: 'validation error: label ''team'' is
    required. Rule autogen-check-team failed at path /spec/template/metadata/labels/team/'

 

에러 반환 외에도 Kyverno는 해당 정보를 포함하는 이벤트(Event)를 동일한 네임스페이스에 생성합니다.

참고: Kyverno는 kube-system이나 kyverno와 같은 시스템 네임스페이스를 제외하도록 설정되어 있을 수 있습니다. 테스트 시 사용자 정의 네임스페이스나 default 네임스페이스를 사용하세요.

 

정책은 Pod를 대상으로 하지만, 방금 생성한 Deployment가 차단된 점에 주목하세요. 이는 Kyverno의 규칙 자동 생성(rule auto-generation) 기능 덕분입니다. Kyverno는 Pod 전용으로 작성된 정책을 Deployment를 포함한 모든 표준 쿠버네티스 Pod 컨트롤러에 지능적으로 적용합니다.

이제 필수 레이블을 포함하여 Pod를 생성해 봅니다.

kubectl run nginx --image nginx --labels team=backend

 

이 Pod 설정은 정책을 준수하므로 생성이 허용됩니다. Pod가 생성된 후 몇 초간 기다린 뒤 Kyverno가 수행한 다른 작업을 확인해 보겠습니다. 다음 명령어를 실행하여 Kyverno가 방금 생성한 정책 보고서를 조회합니다.

kubectl get policyreport -o wide

 

"PASS" 열에 결과가 1로 표시된 정책 보고서를 볼 수 있습니다. 이는 방금 생성한 Pod가 정책을 통과했기 때문입니다.

NAME                                   KIND         NAME                            PASS   FAIL   WARN   ERROR   SKIP   AGE
3f9d6279-445b-403d-a255-2a0a8da419a8   Pod          nginx                           1      0      0      0       0      4s
72a484fd-29a8-4126-ade6-ade1c4aba275   ReplicaSet   my-backstage-84ff474f85         0      1      0      0       0      2m7s
7492fb75-0003-4d6d-9ce0-fcf52c933f0c   Pod          my-backstage-84ff474f85-8777r   0      1      0      0       0      2m7s
757ae125-e628-46b7-ab20-6849a831baae   Deployment   my-backstage                    0      1      0      0       0      2m7s

 

방금 생성한 정책을 삭제하여 정리합니다.

kubectl delete clusterpolicy require-labels

 

축하합니다! 쿠버네티스 클러스터에 검증 정책을 성공적으로 구현했습니다.


2. 리소스 변이 (Mutate Resources)

변이는 리소스가 클러스터에 수용되기 전에 리소스를 변경하거나 "변형"하는 기능입니다. 변이 규칙은 검증 규칙과 유사하게 리소스(Pod나 ConfigMap 등)를 선택하고 원하는 상태를 정의합니다.

클러스터에 아래 변이 정책을 추가하세요. 이 정책은 모든 새로운 Pod에 team 레이블을 추가하고 값을 bravo로 설정합니다. 단, 해당 Pod에 이미 이 레이블이 할당되어 있지 않은 경우에만 동작합니다. +(team) 표기법은 Kyverno 앵커(anchor)를 사용하여 레이블 키가 없을 때 수행할 동작을 정의합니다.

kubectl create -f- << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-labels
spec:
  # 앞선 규칙과 동일하게 kind가 파드가 매칭되면 작업을 수행
  rules:
  - name: add-team
    match:
      any:
      - resources:
          kinds:
          - Pod
    # 이번에는 레이블에 team: bravo라는 정보와 merge하는 변형을 수행
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            +(team): bravo
EOF

 

이제 레이블이 정의되지 않은 새 Pod를 생성해 봅니다.

kubectl run redis --image redis

 

생성된 Pod의 레이블을 확인합니다.

# kubectl get pod redis --show-labels
NAME    READY   STATUS              RESTARTS   AGE   LABELS
redis   0/1     ContainerCreating   0          7s    run=redis,team=bravo

 

Kyverno에 의해 team=bravo 레이블이 추가된 것을 확인할 수 있습니다. 이번에는 이미 team 레이블이 정의된 Pod를 생성해 봅니다.

kubectl run newredis --image redis -l team=alpha

 

이 Pod의 레이블을 다시 확인해 보면, 이미 레이블이 존재하므로 Kyverno가 정책에 정의된 값으로 덮어쓰지 않았음을 알 수 있습니다. 이와 같이 merge 기능은 이미 있는 레이블은 덮어쓰지 않습니다.

# kubectl get pod --show-labels newredis
NAME       READY   STATUS    RESTARTS   AGE   LABELS
newredis   1/1     Running   0          44s   team=alpha​

 

작업을 마친 후 정책을 삭제합니다.

kubectl delete clusterpolicy add-labels

3. 리소스 생성 (Generate Resources)

Kyverno는 정책에 저장된 정의를 바탕으로 새로운 쿠버네티스 리소스를 생성하는 기능이 있습니다. 생성 기능은 매우 강력하고 유연하며, 초기 생성뿐만 아니라 생성된 리소스를 지속적으로 동기화하는 기능도 제공합니다.

이번 가이드에서는 새로운 네임스페이스가 생성될 때 이미지 풀 시크릿(image pull secret)을 자동으로 생성하는 정책을 살펴봅니다. 먼저, 실제 시크릿을 모방한 테스트용 시크릿을 생성합니다.

kubectl -n default create secret docker-registry regcred \
  --docker-server=myinternalreg.corp.com \
  --docker-username=john.doe \
  --docker-password=Passw0rd123! \
  --docker-email=john.doe@corp.com

 

기본적으로 Kyverno는 최소 권한으로 설정되어 있어 시크릿과 같은 민감한 리소스에 접근할 수 없습니다. 클러스터 역할 집계(cluster role aggregation)를 통해 권한을 부여해야 합니다.

kubectl apply -f- << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kyverno:secrets:view
  labels:
    rbac.kyverno.io/aggregate-to-admission-controller: "true"
    rbac.kyverno.io/aggregate-to-reports-controller: "true"
    rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
  - ''
  resources:
  - secrets
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kyverno:secrets:manage
  labels:
    rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
  - ''
  resources:
  - secrets
  verbs:
  - create
  - update
  - delete
EOF

 

이제 다음 Kyverno 정책을 생성합니다. sync-secrets 정책은 새로 생성된 네임스페이스를 감지하여 방금 만든 시크릿을 해당 네임스페이스로 복제합니다.

kubectl create -f- << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: sync-secrets
spec:
  # 이번에는 Namespace 생성이 탐지되면 동작함
  rules:
  - name: sync-image-pull-secret
    match:
      any:
      - resources:
          kinds:
          - Namespace
    # Secret을 요청한 NS에 생성하는 규칙이 들어가 있으며 이것은 default에서 복제해옴
    generate:
      apiVersion: v1
      kind: Secret
      name: regcred
      namespace: "{{request.object.metadata.name}}"
      synchronize: true
      clone:
        namespace: default
        name: regcred
EOF

 

테스트를 위해 새 네임스페이스를 생성합니다.

kubectl create ns mytestns

 

 

새 네임스페이스에 regcred 시크릿이 있는지 확인합니다.

kubectl -n mytestns get secret

 

Kyverno가 default 네임스페이스의 소스 시크릿을 템플릿으로 사용하여 regcred 시크릿을 생성한 것을 볼 수 있습니다. 원본 시크릿을 수정하면 Kyverno가 생성된 모든 곳에 변경 사항을 동기화합니다.

마지막으로 정책을 삭제하여 정리합니다.

kubectl delete clusterpolicy sync-secrets