Kustomize - Patch 심화(inline vs 파일분리, dictionary, list 조작)

2026. 1. 8. 15:18·CKA

앞에서 “patch는 특정 리소스의 특정 필드만 정밀하게 바꾸는 수단”이라고 정리했습니다.
이번 내용은 그 패치를 실전에서 쓰게 되는 형태로 확장합니다.

  • 패치를 kustomization.yaml 안에 inline으로 쓰는 방법
  • 패치를 별도 파일로 분리해서 깔끔하게 관리하는 방법
  • 딕셔너리(map)(예: labels)에서 key를 replace/add/remove
  • 리스트(array)(예: containers)에서 item을 replace/add/remove

1) 패치 정의 방식: Inline vs Separate File

1-1) Inline(=kustomization.yaml 안에 직접 작성)

JSON 6902 패치에서 흔히 보던 방식입니다.

patches:
  - target:
      kind: Deployment
      name: api-deployment
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 5

장점: 파일 수가 적고 빠름
단점: 패치가 많아지면 kustomization.yaml이 난장판이 됨


1-2) Separate File(=패치 내용을 별도 파일로 분리)

패치가 많아질수록 이 방식이 유지보수에 유리합니다.

(A) JSON 6902 패치를 파일로 분리하는 형태(강의 흐름)

kustomization.yaml에는 target과 “파일 경로”만 두고, 패치 리스트는 파일에 둡니다.

아래 예시는 강의에서 설명한 “replica-patch.yaml에 patch 리스트를 둔다” 방식의 의도를 반영한 구성입니다.

kustomization.yaml

patches:
  - target:
      kind: Deployment
      name: api-deployment
    path: replica-patch.yaml

replica-patch.yaml

- op: replace
  path: /spec/replicas
  value: 5

주의: Kustomize 버전에 따라 patches에서 path:를 쓰는 형태/키가 달라 보일 수 있습니다. 팀에서는 “kubectl 내장 Kustomize vs standalone Kustomize” 버전을 통일하는 편이 안전합니다. (원리는 동일: target은 kustomization에서, patch 내용은 파일로 분리)

(B) Strategic Merge 패치는 원래 파일 분리가 자연스럽다

전통적으로는 patchesStrategicMerge에 파일을 나열합니다.

kustomization.yaml

patchesStrategicMerge:
  - label-patch.yaml

2) Dictionary(map) 조작 예: labels 변경(replace/add/remove)

예시는 Deployment의 Pod 템플릿 라벨을 바꾸는 케이스입니다.

대상 필드 경로:
spec.template.metadata.labels


2-1) JSON 6902로 label 값 replace (component: api → component: web)

원본(개념)

spec:
  template:
    metadata:
      labels:
        component: api

kustomization.yaml (inline)

patches:
  - target:
      kind: Deployment
      name: api-deployment
    patch: |-
      - op: replace
        path: /spec/template/metadata/labels/component
        value: web

포인트:

  • path 마지막에 key 이름(component)까지 내려가서 값을 교체합니다.

2-2) Strategic Merge로 label 값 replace (가독성 좋음)

kustomization.yaml

patchesStrategicMerge:
  - label-patch.yaml

label-patch.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  template:
    metadata:
      labels:
        component: web

포인트:

  • 원본을 복사해 오고 바뀌는 부분만 남긴다
  • Kustomize가 merge해서 “component만 web으로 변경”합니다.

2-3) JSON 6902로 label key 추가(add) (org: kodekloud 추가)

patches:
  - target:
      kind: Deployment
      name: api-deployment
    patch: |-
      - op: add
        path: /spec/template/metadata/labels/org
        value: kodekloud

결과:

  • 기존 component: api는 유지
  • 새로 org: kodekloud가 추가

2-4) Strategic Merge로 label key 추가(add)

label-patch.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  template:
    metadata:
      labels:
        org: kodekloud

결과:

  • 기존 labels와 merge되어 org가 추가됩니다.

2-5) JSON 6902로 label key 삭제(remove)

예: org 라벨 제거

patches:
  - target:
      kind: Deployment
      name: api-deployment
    patch: |-
      - op: remove
        path: /spec/template/metadata/labels/org

remove는 value가 필요 없습니다.


2-6) Strategic Merge로 label key 삭제(remove) = null로 설정

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  template:
    metadata:
      labels:
        org: null

Strategic merge에서 “키 삭제”를 표현할 때 자주 쓰는 패턴입니다.


3) List(array) 조작 예: containers 변경(replace/add/remove)

대상 필드 경로:
spec.template.spec.containers (리스트)


3-1) JSON 6902로 리스트 아이템 replace (0번 컨테이너 교체)

강의 포인트:

  • 리스트는 인덱스로 접근합니다.
  • 첫 번째 항목은 0

예: 첫 컨테이너의 name/image를 haproxy로 교체

patches:
  - target:
      kind: Deployment
      name: api-deployment
    patch: |-
      - op: replace
        path: /spec/template/spec/containers/0/name
        value: haproxy
      - op: replace
        path: /spec/template/spec/containers/0/image
        value: haproxy

강의에서는 “containers/0 전체를 value로 바꾼다”처럼 설명했는데, 실무에서는 보통처럼 필드 단위로 replace하는 편이 덜 위험합니다(원치 않는 필드 누락 방지).


3-2) Strategic Merge로 특정 컨테이너의 image만 교체(이 방식이 더 실무적)

container-image-patch.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  template:
    spec:
      containers:
        - name: nginx
          image: haproxy

전제:

  • 원본 containers에 name: nginx가 존재해야 의미가 명확해집니다.
  • Strategic merge는 컨테이너를 name 기준으로 merge하는 동작이 기대됩니다(쿠버네티스 오브젝트에서 흔한 merge key 패턴).

3-3) JSON 6902로 리스트 아이템 add (컨테이너 추가)

강의 포인트:

  • path 끝의 -는 “리스트 끝에 append” 의미
patches:
  - target:
      kind: Deployment
      name: api-deployment
    patch: |-
      - op: add
        path: /spec/template/spec/containers/-
        value:
          name: haproxy
          image: haproxy
  • 앞에 넣고 싶으면 containers/0
  • 두 번째로 넣고 싶으면 containers/1 … 이런 식으로 인덱스를 지정할 수도 있습니다.

3-4) Strategic Merge로 컨테이너 추가(add)

add-container-patch.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  template:
    spec:
      containers:
        - name: haproxy
          image: haproxy

merge 결과:

  • 원본의 web/nginx 컨테이너 유지
  • patch의 haproxy 컨테이너 추가

3-5) JSON 6902로 리스트 아이템 remove (인덱스로 삭제)

강의 포인트:

  • 삭제는 인덱스 지정이 필요
  • 두 번째 컨테이너면 1
patches:
  - target:
      kind: Deployment
      name: api-deployment
    patch: |-
      - op: remove
        path: /spec/template/spec/containers/1

주의:

  • 인덱스 기반 삭제는 “순서가 바뀌면 다른 컨테이너를 지울 위험”이 있습니다.
  • 컨테이너가 늘거나 순서가 바뀌기 쉬운 환경이라면 이 방식은 운영 사고로 이어질 수 있습니다.

3-6) Strategic Merge로 리스트 아이템 delete: $patch: delete

강의에서 나온 특수 지시문이 이겁니다.

delete-container-patch.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  template:
    spec:
      containers:
        - name: database
          $patch: delete

의미:

  • containers 리스트에서 name: database인 항목을 찾아 삭제하라

실무적으로는:

  • 인덱스 기반 삭제보다 안전한 편입니다(“database라는 이름”을 기준으로 삭제).

4) 실무 팁: 어떤 방식이 언제 더 안전한가?

JSON 6902가 좋은 경우

  • “정확히 그 경로를 바꾸겠다”가 명확할 때
  • 단일 값 변경(예: /spec/replicas) 같이 경로가 짧고 확실할 때
  • patch 동작을 코드처럼 엄격하게 관리하고 싶을 때

Strategic Merge가 좋은 경우(많이 선호)

  • 사람이 읽기 쉽고, 리뷰가 편함
  • labels/env/resources 같은 구조를 YAML 형태로 자연스럽게 수정 가능
  • 리스트에서 “name 기준”으로 merge/delete를 표현할 수 있어 더 안전한 경우가 많음

5) 항상 마지막에 확인: 렌더링 결과 검증

kubectl kustomize ./k8s | less
kubectl diff -k ./k8s

패치는 “타겟 매칭 실수”가 가장 위험하니, diff 습관이 중요합니다.


정리

  • 패치는 inline으로 쓰거나, 별도 파일로 분리할 수 있다(패치가 많으면 분리 추천).
  • dictionary(labels) 조작:
    • JSON 6902: replace/add/remove + path .../labels/<key>
    • Strategic merge: 필요한 부분만 남긴 YAML로 merge, 삭제는 null
  • list(containers) 조작:
    • JSON 6902: 인덱스(0, 1) 또는 append(-) 사용
    • Strategic merge: name 기준 merge, 삭제는 $patch: delete
  • 실무에서는 “가독성/안정성” 때문에 strategic merge를 더 선호하는 경우가 많다.

 

 

**참고

만약에 metadata.name을 strategic merge에서 변경하고 싶다면? -> JSON6902사용

그리고 name: web, image: nginx을 name: haproxy, image: haproxy로 바꾸고싶다면? -> JSON6902사용

 

 

Access the lab  here: https://learn.kodekloud.com/user/courses/udemy-labs-certified-kubernetes-administrator-with-practice-tests/module/f868dfbe-80b2-44cf-97e7-d00fc0d91307/lesson/919f7a3a-8ba1-4c84-a363-2108c51fff1d

'CKA' 카테고리의 다른 글

Kustomize - Components  (0) 2026.01.08
Kustomize - Overlays  (0) 2026.01.08
Kustomize - Patch  (0) 2026.01.08
Kustomize - Transformers  (0) 2026.01.08
Kustomize - 여러 디렉토리 관리  (0) 2026.01.08
'CKA' 카테고리의 다른 글
  • Kustomize - Components
  • Kustomize - Overlays
  • Kustomize - Patch
  • Kustomize - Transformers
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (118)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      락
      프록시 팩토리
      자바
      조회 성능 최적화
      log trace
      @discriminatorvalue
      gesingleresult
      @discriminatorcolumn
      양방향 맵핑
      JPQL
      jpq
      김영한
      빈 후처리기
      Target
      reentarantlock
      페치 조인
      Thread
      단방향 맵핑
      jdk 동적 프록시
      typequery
      cglib
      스레드
      hibernate5module
      버퍼
      @within
      프록시
      고급
      WAS
      @args
      requset scope
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    Kustomize - Patch 심화(inline vs 파일분리, dictionary, list 조작)
    상단으로

    티스토리툴바