263. Kustomize - Problem Statement and Ideology

Kustomize란?

“원본 YAML을 건드리지 않고, 환경별로 ‘덧붙이기(overlay)‘로 변형만 해주는 도구”

Helm과 무엇이 다른가?

  • Helm = 템플릿 방식: {{ .Values.x }} 같은 플레이스홀더를 작성. 강력하지만 템플릿 언어 학습 필요
  • Kustomize = 패치 방식: 원본 YAML은 그대로 두고 “이 필드만 이렇게 바꿔라” 를 별도 파일에 작성

Kustomize 철학:

  • 순수 YAML 유지 — Git diff에서 읽기 쉬움
  • kubectl에 내장 (kubectl apply -k) — 별도 설치 없음
  • base/overlay 구조로 환경 차이만 명시적으로 표시

왜 Kustomize인가?

  • 동일한 앱을 dev / staging / prod 환경에 배포할 때 YAML이 중복됨
  • 환경별로 이미지 태그, 레플리카 수, 리소스 제한이 달라야 함
  • Helm처럼 템플릿 언어를 배울 필요 없이 순수 YAML 유지

Base YAML (공통 리소스 정의) → 환경별 overlay로 분기:

  • dev overlay (replicas: 1, debug 이미지)
  • staging overlay (replicas: 2)
  • prod overlay (replicas: 5, 리소스 제한 추가)

264. Kustomize vs Helm

항목KustomizeHelm
접근 방식순수 YAML 패치템플릿 언어 (Go Template)
학습 곡선낮음높음
kubectl 통합내장 (kubectl apply -k)별도 설치 필요
패키지 배포없음Chart 저장소 배포 가능
복잡한 로직제한적강력 (if/loop/함수)
적합한 상황환경별 설정 관리재사용 가능한 앱 패키지

265. Installation / Setup

# kubectl에 내장 (v1.14+)
kubectl version --client   # kustomize 포함 여부 확인
 
# 독립 설치 (최신 버전)
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
 
# 버전 확인
kustomize version

266. The kustomization.yaml File

기본 구조

# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
# 관리할 리소스 목록
resources:
  - deployment.yaml
  - service.yaml
  - configmap.yaml
# kustomize 빌드 (YAML 출력만)
kustomize build ./
 
# 클러스터에 적용
kustomize build ./ | kubectl apply -f -
# 또는
kubectl apply -k ./

267. Kustomize Output

# 렌더링된 YAML 확인 (적용 전 미리보기)
kustomize build ./base
kustomize build ./overlays/prod
 
# 특정 리소스만 확인
kustomize build ./ | grep -A10 "kind: Deployment"

268. Kustomize ApiVersion & Kind

# kustomization.yaml 필수 헤더 (kustomize v2.1+)
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

apiVersionkind를 명시하지 않아도 동작하지만, 명시하는 것이 권장됨


269-270. Managing Directories

디렉토리 구조 (Base + Overlays 패턴)

my-app/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   └── service.yaml
└── overlays/
    ├── dev/
    │   └── kustomization.yaml
    ├── staging/
    │   └── kustomization.yaml
    └── prod/
        └── kustomization.yaml

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
resources:
  - deployment.yaml
  - service.yaml

overlays/dev/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
# base 디렉토리 참조
resources:
  - ../../base
 
# dev 환경 전용 설정 (패치/트랜스포머 등)
namePrefix: dev-
# dev 환경 빌드
kustomize build overlays/dev
 
# prod 환경 적용
kubectl apply -k overlays/prod

272-274. Common Transformers

Transformer란?

“리소스 전반에 걸쳐 일괄 변형을 적용하는 선언”

Patch와의 차이:

  • Patch: 특정 리소스의 특정 필드 수정 (세밀)
  • Transformer: 모든 리소스에 공통 변형 적용 (일괄)

예: “이 overlay의 모든 리소스에 env=prod 라벨 붙이기” 같은 전역 변경.

주요 Transformer 목록

Transformer역할
namePrefix / nameSuffix모든 리소스 이름에 접두/접미사 추가
namespace모든 리소스에 namespace 지정
commonLabels모든 리소스에 공통 라벨 추가
commonAnnotations모든 리소스에 공통 어노테이션 추가
images이미지 이름/태그 교체
replicas레플리카 수 변경
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
resources:
  - ../../base
 
# 모든 리소스 이름 앞에 "prod-" 추가
namePrefix: prod-
 
# 모든 리소스에 namespace 지정
namespace: production
 
# 공통 라벨
commonLabels:
  env: production
  team: backend
 
# 공통 어노테이션
commonAnnotations:
  managed-by: kustomize

commonLabels 주의

이 라벨은 Pod 템플릿의 metadata.labels 뿐만 아니라 Selector에도 추가됨. Deployment/Service의 selector가 바뀌면서 기존 Pod와 매칭 안 되는 사고 발생 가능. 안전하게 “표시용 라벨만” 붙이고 싶으면 labels 필드(v5+) 또는 patch로 처리.

Image Transformer

# 이미지 태그 변경 (CI/CD에서 자주 사용)
images:
  - name: nginx                      # 현재 이미지 이름
    newName: my-registry/nginx       # 새 이미지 이름 (선택)
    newTag: "1.21.6"                 # 새 태그
 
  - name: my-app
    newTag: "v2.0.1"

276-280. Patches

Patch 개념

  • Base YAML의 특정 필드만 덮어쓰기
  • 두 가지 방식: Strategic Merge Patch / JSON 6902 Patch

Strategic Merge Patch

# kustomization.yaml
patches:
  - path: replica-patch.yaml
# replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment    # 패치할 대상 리소스 이름
spec:
  replicas: 5            # 이 필드만 덮어씀

JSON 6902 Patch (인라인 방식)

# kustomization.yaml
patches:
  - target:
      kind: Deployment
      name: my-deployment
    patch: |-
      - op: replace          # 작업: replace / add / remove
        path: /spec/replicas
        value: 5
      - op: replace
        path: /spec/template/spec/containers/0/image
        value: nginx:1.21.6

Patch 작업 유형

작업설명
replace기존 값 교체
add새 필드/항목 추가
remove필드 삭제

278-279. Patches Dictionary vs List

Dictionary (맵) 패치

# 맵 구조의 필드 패치 (spec.resources.limits 등)
patches:
  - target:
      kind: Deployment
      name: my-deployment
    patch: |-
      - op: replace
        path: /spec/template/spec/containers/0/resources/limits/memory
        value: "512Mi"

List (배열) 패치

# 배열에 항목 추가
patches:
  - target:
      kind: Deployment
      name: my-deployment
    patch: |-
      - op: add
        path: /spec/template/spec/containers/0/env/-   # "-"는 배열 끝에 추가
        value:
          name: ENV_VAR
          value: "production"

281-282. Overlays

환경별 Overlay 예시

# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
resources:
  - ../../base
 
namePrefix: prod-
namespace: production
 
commonLabels:
  env: prod
 
patches:
  - target:
      kind: Deployment
      name: my-deployment
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 5
      - op: replace
        path: /spec/template/spec/containers/0/resources/limits/memory
        value: "1Gi"
 
images:
  - name: my-app
    newTag: "v2.1.0"
# 각 환경 배포
kubectl apply -k overlays/dev
kubectl apply -k overlays/staging
kubectl apply -k overlays/prod
 
# 환경 비교 (diff)
kubectl diff -k overlays/prod

283-284. Components

Component란?

“여러 Overlay가 선택적으로 가져다 쓸 수 있는 재사용 가능한 변경 묶음”

Patch vs Component 구분:

PatchComponent
위치overlay 안별도 디렉토리
재사용해당 overlay에서만여러 overlay에서 import
kindKustomizationComponent
용도이 환경에서만 바꾸기기능 단위로 묶어 선택 활성화

예: “모니터링 설정”을 dev와 prod에 선택적으로 적용:

  • 단순 Patch로 하면 → dev/prod 각각 동일한 코드 반복

  • Component로 만들면 → 한 번 정의 후 components: 에 넣기만 하면 적용

  • 여러 Overlay에서 선택적으로 재사용 가능한 설정 묶음

  • 예: “모니터링 설정”, “캐시 설정” 등을 컴포넌트로 분리

# components/monitoring/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component              # Component 타입 사용
 
resources:
  - servicemonitor.yaml
 
patches:
  - target:
      kind: Deployment
    patch: |-
      - op: add
        path: /spec/template/metadata/annotations/prometheus.io~1scrape
        value: "true"
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
 
resources:
  - ../../base
 
# 필요한 컴포넌트만 선택적으로 포함
components:
  - ../../components/monitoring
  - ../../components/cache

Kustomize 전체 구조 요약

  • base/ — 공통 YAML
  • components/ — 선택적 기능 묶음 (monitoring, cache 등)
  • overlays/dev/namePrefix: dev-, replicas 1
  • overlays/prod/namePrefix: prod-, replicas 5, monitoring component 포함

base → 각 overlay로 흐르고, components는 overlay에서 선택적으로 포함.