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

Kyverno 정책의 정교한 설계: Match/Exclude와 Any/All 완벽 가이드 🎯

by gasbugs 2026. 1. 5.

안녕하세요! 클러스터 보안의 정교한 설계자, Kyverno 시리즈의 네 번째 시간입니다. 👷‍♀️

지난 시간에는 Policy와 ClusterPolicy의 차이점을 명확히 이해했습니다. 이제 정책을 작성할 때 "어떤 리소스에, 어떤 조건에서 이 정책을 적용할 것인가?"를 정의하는 가장 핵심적인 블록인 `Match`와 `Exclude`에 대해 깊이 파고들어 보겠습니다.

이 블록들을 얼마나 잘 활용하느냐에 따라 정책의 정확성과 효율성이 결정됩니다. 오늘 10분만 투자해서 Kyverno 정책 작성의 마스터가 되어보세요! 🚀


🏗️ 1. Match와 Exclude 블록: 정책의 조준경 🎯

Match와 Exclude는 Kyverno 정책이 어떤 리소스에 적용될지(Match), 그리고 어떤 리소스를 제외할지(Exclude)를 결정하는 필터 역할을 합니다. 이 둘은 같은 구조를 가지며, 정책의 spec.rules 아래에 정의됩니다.

🔹 Match 블록 (포함 조건)

정책을 적용할 리소스의 조건을 정의합니다. 여기에 명시된 모든 조건이 일치해야 정책이 트리거됩니다.

🔸 Exclude 블록 (제외 조건)

Match 조건에 일치하더라도 Exclude 조건에 일치하면 정책 적용에서 제외됩니다. 이는 특정 예외 상황을 처리할 때 유용합니다.


💻 2. Resource 기반 Match / Exclude: 가장 기본적인 필터링

가장 흔하게 사용되는 필터링 방식으로, 리소스의 종류, 이름, 네임스페이스, 레이블 등을 기준으로 합니다.

① kinds: 리소스 종류 지정 📦

어떤 종류의 쿠버네티스 리소스에 정책을 적용할지 명시합니다.

  • Pod, Deployment, ConfigMap, Secret 등

② names: 리소스 이름 지정 📛

특정 이름의 리소스에만 적용하거나 제외할 때 사용합니다.

  • 와일드카드(*) 사용 가능 (test-* 등)

③ namespaces: 네임스페이스 지정 🏘️

특정 네임스페이스 안의 리소스에만 적용하거나 제외할 때 사용합니다.

  • kube-system처럼 중요한 시스템 네임스페이스를 제외할 때 필수!

④ labelSelector: 레이블 기반 필터링 🏷️

리소스에 붙어있는 레이블을 기준으로 필터링합니다.

⑤ annotationSelector: 어노테이션 기반 필터링 📝

리소스에 붙어있는 어노테이션을 기준으로 필터링합니다.

코드로 보는 Resource 기반 필터링 예시

YAML
# 예시: "production" 네임스페이스의 "nginx" 이름을 가진 Pod 중,
#       "env: dev" 레이블을 가진 Pod을 제외하고 정책 적용
rules:
- name: example-policy
  match:
    any:
    - resources:
        kinds: ["Pod"]
        namespaces: ["production"]
        names: ["nginx-*"]
  exclude:
    any:
    - resources:
        labelSelector:
          matchLabels:
            env: dev

👥 3. User 및 Role 기반 Match / Exclude: 행위자 기반 필터링

어떤 사용자가, 어떤 서비스 어카운트나 그룹으로 리소스를 생성하는지에 따라 정책을 적용합니다.

① users: 특정 사용자 지정 🧑‍💻

특정 사용자(kubernetes-admin 등)나 서비스 어카운트(system:serviceaccount:default:default)를 기준으로 합니다.

② roles: 역할(Role) 기반 지정 🎭

특정 Role이나 ClusterRole을 가진 사용자를 기준으로 합니다.

③ clusterRoles: 클러스터 역할(ClusterRole) 기반 지정 👑

클러스터 전체 ClusterRole을 가진 사용자를 기준으로 합니다.

코드로 보는 User / Role 기반 필터링 예시

YAML
# 예시: "kube-admin" 사용자가 생성하는 리소스에 대해서는 정책을 제외
#       (관리자 예외 처리)
rules:
- name: exclude-admin-user
  exclude:
    any:
    - subjects:
      - kind: User
        name: kube-admin
    - subjects:
      - kind: Group # Kubernetes 그룹 (ex: system:masters)
        name: system:masters

🤝 4. Any와 All 연산자를 활용한 복합 로직 처리

Match와 Exclude 블록 내에서 여러 조건을 조합할 때 Any와 All 연산자를 사용합니다. 이는 논리 연산의 OR과 AND 개념과 동일합니다.

🔹 Any: OR 조건 (하나라도 참이면 True)

any 아래에 나열된 조건 중 하나라도 일치하면 전체 any 블록은 True가 됩니다.

YAML
# 예시: "production" OR "staging" 네임스페이스 중 하나라도 일치하면 Match
match:
  any:
  - resources:
      namespaces: ["production"]
  - resources:
      namespaces: ["staging"]

🔸 All: AND 조건 (모두 참이어야 True)

all 아래에 나열된 조건들이 모두 일치해야 전체 all 블록은 True가 됩니다.

YAML
# 예시: "Pod" 이면서 AND "app=nginx" 레이블을 가진 리소스에 Match
match:
  all:
  - resources:
      kinds: ["Pod"]
  - resources:
      labelSelector:
        matchLabels:
          app: nginx

💡 Any와 All의 혼합 사용

두 연산자를 중첩하여 복잡한 조건을 만들 수 있습니다.

YAML
# 예시: "production" 네임스페이스에 있으면서 "Pod" 이거나 OR "Deployment"인 리소스
match:
  all: # AND 조건
  - resources:
      namespaces: ["production"]
  - any: # OR 조건
    - resources:
        kinds: ["Pod"]
    - resources:
        kinds: ["Deployment"]

🛡️ Kyverno 종합 예제 정책 (ClusterPolicy)

이 정책은 클러스터 전체에서 1) 특정 레이블이 없는 Pod 생성을 차단하되, 2) 관리자 그룹이나 특정 네임스페이스, 혹은 특정 레이블을 가진 리소스는 예외로 처리하는 복잡한 로직을 담고 있습니다.

YAML
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: comprehensive-pod-security
  annotations:
    policies.kyverno.io/title: "Match, Exclude, and Complex Logic Example"
    policies.kyverno.io/description: "Example policy using any/all logic with resource and subject filters."
spec:
  # 'Enforce'는 규칙 위반 시 생성을 즉시 차단합니다.
  validationFailureAction: Enforce
  # 이미 실행 중인 리소스에 대해서도 백그라운드 스캔을 수행합니다.
  background: true
  rules:
  - name: check-team-and-env-labels
    # [Match 블록] 정책 적용 대상 설정
    match:
      all: # 아래 조건이 '모두' 만족해야 함 (AND)
      - resources:
          kinds:
          - Pod
      - any: # 아래 조건 중 '하나라도' 만족하면 됨 (OR)
        - resources:
            namespaces:
            - production
            - staging
    
    # [Exclude 블록] 정책 예외 대상 설정
    exclude:
      any: # 아래 조건 중 '하나라도' 해당하면 정책 적용 제외 (OR)
      - subjects:
        - kind: Group
          name: system:masters # 클러스터 관리자 그룹 예외
      - resources:
          namespaces:
          - kube-system
          - kyverno
          - "test-*" # 'test-'로 시작하는 모든 네임스페이스 예외
          labelSelector:
            matchLabels:
              allow-unlabeled: "true" # 특정 레이블이 있으면 예외

    # [Validate 블록] 실제 검증 규칙
    validate:
      message: "The labels 'team' and 'env' are mandatory for production/staging pods."
      pattern:
        metadata:
          labels:
            team: "?*" # 'team' 레이블이 반드시 존재해야 함
            env: "?*"  # 'env' 레이블이 반드시 존재해야 함

📋 코드 상세 분석 (Logic Breakdown)

  1. Match - All & Any 조합:
    • kinds: [Pod] (AND) namespaces: [production, staging]
    • 즉, production 또는 staging 네임스페이스에 생성되는 Pod만 이 정책의 감시 대상이 됩니다.
  2. Exclude - 다양한 예외 처리:
    • 권한 기반: system:masters 권한을 가진 사용자(관리자)가 리소스를 생성할 때는 이 규칙이 무시됩니다.
    • 네임스페이스 기반: 시스템 핵심인 kube-system, kyverno와 테스트용인 test-* 네임스페이스는 검사하지 않습니다.
    • 레이블 기반: 특정 Pod에 allow-unlabeled: "true"라는 레이블을 명시적으로 붙였다면 예외로 인정해 줍니다.
  3. Validate - 패턴 매칭:
    • ?*: Kyverno에서 "비어있지 않은 문자열이 반드시 존재해야 함"을 의미하는 와일드카드입니다.

🚀 테스트 방법

이 정책이 잘 작동하는지 확인하려면 다음 두 가지 파일을 작성해 보세요.

  • 실패 케이스: production 네임스페이스에 team 레이블 없이 Pod 배포 시도 → 생성 차단됨
  • 성공 케이스 1: production 네임스페이스에 team: dev, env: prod 레이블 포함 후 배포 → 생성 성공
  • 성공 케이스 2: test-zone 네임스페이스에 레이블 없이 Pod 배포 → 제외(Exclude) 대상이므로 성공
  • 성공 케이스 3: 관리자 권한으로 레이블 없이 배포 → 제외(Exclude) 대상이므로 성공

 

 

🚀 5. 운영자를 위한 실무 팁 (Best Practices)

  1. 명확한 범위 설정: 정책은 필요한 리소스에만 적용되도록 Match 조건을 최대한 구체적으로 작성하세요. 너무 넓은 범위는 예상치 못한 부작용을 일으킬 수 있습니다.
  2. kube-system 제외 필수: Exclude 블록을 사용하여 Kyverno, kube-system, kube-public 등 클러스터 시스템 관련 네임스페이스는 반드시 정책 적용에서 제외하세요. 자칫 클러스터 자체가 멈출 수 있습니다.
  3. 관리자 예외 처리: exclude.subjects를 사용하여 클러스터 관리자(예: system:masters 그룹)에게는 일부 정책을 적용하지 않도록 예외를 두는 것이 편리합니다.
  4. background: true 확인: Match 조건을 변경했을 때, 이미 배포된 리소스에 대한 정책 적용 여부를 확인하려면 background: true 설정을 잊지 마세요.

🌟 마치며

오늘은 Kyverno 정책의 핵심 조준경인 `Match`와 `Exclude` 블록을 상세히 분석하고, `Any`와 `All` 연산자를 활용하여 복잡한 조건을 만드는 방법을 배웠습니다.

이 블록들을 자유자재로 다룰 수 있다면, 여러분은 클러스터의 특정 부분에만 정확하게 원하는 보안 규칙을 적용할 수 있는 강력한 능력을 갖게 될 것입니다. 💪

다음 시간에는 "변수(Variables) 활용: Admission Review 및 ConfigMap 데이터 참조"를 통해 더욱 동적이고 유연한 정책을 만드는 방법을 알아보겠습니다. 궁금한 점은 언제든 댓글로 남겨주세요! 😊