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

Kyverno 마스터 클래스: YAML을 요리하는 두 가지 방법, 패치 방식의 차이점과 실습 🧩

by gasbugs 2026. 1. 6.

안녕하세요! 쿠버네티스 운영의 마법사, Kyverno 마스터 시리즈의 여덟 번째 시간입니다. 🧙‍♂️

지난 시간까지는 잘못된 요청을 "차단"하는 방패(Validation)를 배웠다면, 오늘은 사용자의 요청을 더 완벽하게 "다듬어주는" 요술 지팡이, mutate 규칙에 대해 깊이 있게 다뤄보겠습니다.

"모든 Pod에 보안 레이블을 일일이 넣기 귀찮은데 자동으로 들어갔으면 좋겠다", "개발자가 깜빡한 사이드카 컨테이너를 자동으로 넣어줄 순 없을까?" 이런 고민을 하셨다면 오늘 포스팅이 정답이 될 것입니다. 15분 동안 리소스 변형(Mutation)의 정수를 맛보시죠! 🚀


🏗️ 1. mutate 규칙이란 무엇인가요?

mutate 규칙은 쿠버네티스 리소스가 API 서버에 저장되기 직전에 데이터를 자동으로 수정하거나 추가하는 기능을 합니다.

  • 기본값 설정: 필수적인 설정이 누락되었을 때 자동으로 채워줍니다.
  • 보안 강화: 권장되는 보안 설정을 강제로 주입합니다.
  • 자동화: 사이드카 주입, 레이블링 등 반복적인 작업을 자동화합니다.

🛠️ 2. 리소스를 고치는 두 가지 기술: Strategic Merge vs JSONPatch

Kyverno에서 리소스를 변형하는 방법은 크게 두 가지가 있습니다. 상황에 맞는 적절한 도구를 선택하는 것이 고수의 비결입니다.

① patchStrategicMerge (직관적인 방식) 🧩

쿠버네티스 리소스의 구조를 그대로 따라가며 값을 덮어쓰거나 추가하는 방식입니다. 가장 많이 사용되며 읽기가 매우 쉽습니다.

  • 특징: YAML 구조를 그대로 복사해서 넣으면 됩니다. 리스트(List)의 경우 특정 키(예: name)를 기준으로 병합됩니다.
  • 비유: 레고 블록 위에 새로운 블록을 덧씌우는 것과 같습니다.

② patchesJson6902 (정교한 방식) 📍

일반적으로 JSONPatch라고 부르며, 특정 경로(Path)를 지정하여 수정, 삭제, 추가 명령을 내리는 방식입니다.

  • 특징: 배열의 특정 인덱스에 값을 넣거나, 필드를 삭제하는 등 아주 세밀한 작업이 가능합니다.
  • 비유: 수술실에서 메스를 들고 특정 부위만 정밀하게 수술하는 것과 같습니다.

💻 3. 실습 1: patchStrategicMerge로 기본 레이블 주입하기

모든 Pod이 생성될 때 managed-by: kyverno라는 레이블이 자동으로 붙게 만들어 봅시다.

YAML
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-labels
spec:
  rules:
  - name: add-labels
    match:
      any:
      - resources:
          kinds:
          - Pod
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            managed-by: kyverno
            env: "{{request.namespace}}" # 변수 활용도 가능!

분석: 이 정책은 사용자가 레이블을 넣지 않아도 Kyverno가 가로채서 metadata.labels 안에 해당 값들을 쏙 넣어줍니다.


📍 4. 실습 2: JSONPatch로 컨테이너 설정 정밀 수정하기

이번에는 조금 더 어렵게, 첫 번째 컨테이너의 이미지 풀 정책(imagePullPolicy)을 항상 Always로 강제 변경해 보겠습니다.

YAML
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: force-image-pull-policy
spec:
  rules:
  - name: set-always
    match:
      any:
      - resources:
          kinds:
          - Pod
    mutate:
      patchesJson6902: |-
        - op: replace
          path: "/spec/containers/0/imagePullPolicy"
          value: "Always"

분석: op: replace 명령어를 통해 /spec/containers/0/ 경로에 있는 값을 강제로 바꿉니다. 만약 해당 경로에 값이 없다면 에러가 날 수 있으므로 주의가 필요합니다.


📊 5. 한눈에 비교하는 차이점

구분 patchStrategicMerge patchesJson6902 (JSONPatch)
가독성 매우 높음 (YAML 구조와 동일) 낮음 (경로 기반 표기법)
복잡도 단순 추가/수정에 적합 삭제, 특정 인덱스 수정 등 정밀 작업에 적합
동작 원리 맵(Map) 기반의 병합 RFC 6902 표준 명령 실행
주요 사용처 레이블 추가, 어노테이션 주입 컨테이너 리스트의 특정 요소 수정

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

  1. 가급적 Strategic Merge를 쓰세요: 유지보수가 훨씬 쉽습니다. JSONPatch는 꼭 필요한 경우(예: 특정 리스트 중간에 값을 삽입해야 할 때)에만 사용하세요.
  2. mutate 후 validate 연쇄 작용: Kyverno는 리소스를 변형한 후, 그 결과물이 다른 보안 정책(validate)을 통과하는지도 다시 확인합니다. 따라서 변형 정책이 보안을 해치지 않도록 설계해야 합니다.
  3. 기존 값 보호: 이미 리소스에 값이 있는 경우 덮어쓸지 말지를 결정할 수 있습니다. Strategic Merge에서 +(field) 문법을 사용하면 기존 값을 보존할 수 있습니다.
  4. 멱등성(Idempotency): 정책이 여러 번 적용되어도 결과가 같아야 합니다. 특히 리스트에 아이템을 추가할 때 중복으로 들어가지 않는지 테스트가 필요합니다.

🌟 마치며

오늘은 사용자의 실수를 바로잡고 클러스터의 표준을 자동으로 맞추어주는 mutate 규칙에 대해 알아보았습니다.

  • Strategic Merge로 쉽고 빠르게 기본값을 채우고,
  • JSONPatch로 정밀하게 리소스를 가공하는 법을 익히셨습니다. 🛠️

이 mutate 기능은 특히 Platform Engineering 팀에서 개발자들의 경험(DevX)을 개선하는 데 아주 강력한 도구가 됩니다. "안 돼"라고 차단만 하는 관리자보다는, "부족한 부분은 내가 채워줄게"라고 말하는 스마트한 관리자가 되어보세요! 💪

다음 시간에는 "사이드카 컨테이너 자동 주입 및 공통 레이블 부여"라는 주제로 오늘 배운 mutate를 실무 끝판왕급으로 활용하는 예제를 다뤄보겠습니다. 궁금한 점은 댓글로 남겨주세요! 😊