
Kustomize는 쿠버네티스 커뮤니티의 sig-cli 그룹이 제공하는 매니페스트 템플레이팅 도구이다. 별도의 템플릿 문법 없이 순수한 YAML 파일을 사용하여 쿠버네티스 리소스를 관리하는 것이 특징이다.
주요 기능: 환경별(development, staging, production 등)로 다른 매니페스트를 생성하거나, 특정 필드 값을 덮어쓰는 기능을 통해 효율적으로 매니페스트를 생성하고 관리한다.
Helm과의 차이점: Helm이 정해진 템플릿에 변수 값을 채워 넣어 결과물을 만드는 방식이라면, Kustomize는 원본(base) 매니페스트에 변경 사항을 덧씌우는(Overlay/Patch) 방식으로 동작한다.
kubectl 통합: 과거에는 별도의 명령어로 존재했지만, 현재는 kubectl의 하위 명령어(kubectl kustomize)로 통합되어 별도 설치 없이 바로 사용할 수 있다.
선언형(Declarative) 관리 : Kustomize는 쿠버네티스의 핵심 철학인 '선언형 관리'를 잘 보여주는 도구이다. 우리는 '무엇을(what)' 배포할 것인지(예: nginx 디플로이먼트, 로드밸런서 서비스)를 YAML 파일에 정의할 뿐, '어떻게(how)' 적용할지는 쿠버네티스와 Kustomize가 알아서 처리한다. 이는 명령어 기반의 '명령형(Imperative) 관리'보다 일관성 있고 예측 가능한 상태를 유지하는 데 유리하다.
먼저, 배포할 쿠버네티스 리소스 파일들을 준비한다. 예를 들어 resource-sample 디렉토리에 Deployment와 Service를 생성한다.
sample-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 1 # 기본 레플리카는 1로 설정
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
sample-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: sample-lb
spec:
type: LoadBalancer
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
nodePort: 30082
selector:
app: sample-app
이제 두 리소스 파일을 묶어주기 위한 kustomization.yaml 파일을 같은 디렉토리에 생성한다. resources 필드에 관리할 YAML 파일 목록을 지정한다.
kustomization.yaml
resources:
- sample-deployment.yaml
- sample-lb.yaml
빌드 결과 미리보기: apply 하기 전에 어떤 결과물이 생성될지 미리 확인할 수 있다.
# kustomization.yaml 파일이 있는 디렉토리를 지정한다.
kubectl kustomize resource-sample
클러스터에 적용: -k 옵션을 사용하여 Kustomize 설정을 클러스터에 바로 적용한다.
kubectl apply -k resource-sample
리소스 삭제: 적용과 마찬가지로 -k 옵션을 사용해 관련된 모든 리소스를 한 번에 삭제할 수 있다.
kubectl delete -k resource-sample
kustomization.yaml 파일에 다양한 필드를 추가하여 리소스를 유연하게 변경할 수 있다.
namespace 필드를 사용하면 resources에 포함된 모든 리소스에 특정 네임스페이스를 일괄적으로 부여할 수 있다.
kustomization.yaml
namespace: sample-namespace
resources:
- sample-deployment.yaml
- sample-lb.yaml
적용 및 확인
# 네임스페이스가 없다면 미리 생성한다.
kubectl create namespace sample-namespace
# kustomize로 적용한다.
kubectl apply -k resource-sample
# 해당 네임스페이스에서 Pod를 확인한다.
kubectl get pods -n sample-namespace

namePrefix와 nameSuffix를 이용하면 모든 리소스의 metadata.name에 공통된 접두사와 접미사를 붙일 수 있다. 환경별로 리소스를 구분할 때 유용하다.
kustomization.yaml
namePrefix: prefix-
nameSuffix: -suffix
resources:
- sample-deployment.yaml
- sample-lb.yaml
적용 시 prefix-sample-deployment-suffix 와 같은 이름으로 리소스가 생성된다.

commonLabels와 commonAnnotations를 사용하면 모든 리소스의 메타데이터에 공통 레이블과 어노테이션을 추가할 수 있다.
kustomization.yaml
commonLabels:
label1: label1-val
commonAnnotations:
annotation1: annotation1-val
# 기존
resources:
- ...
images 필드를 사용하면 특정 컨테이너 이미지의 이름, 태그 등을 손쉽게 변경할 수 있다. 이는 환경별로 다른 버전의 이미지를 배포할 때 매우 유용하다.
kustomization.yaml
images:
- name: nginx # 원본 이미지 이름
newName: amsy810/echo-nginx # 변경할 이미지 이름
newTag: v2.0 # 변경할 이미지 태그
resources:
- sample-deployment.yaml
- sample-lb.yaml
📌주의: name에 일치하는 모든 컨테이너 이미지가 변경되므로, 여러 Deployment에서 동일한 이름의 이미지를 사용 중이라면 모두 영향을 받는다.
Kustomize의 가장 주 기능은 오버레이(Overlay) 이다. 공통적인 설정을 base로 두고, 각 환경(staging, production 등)에 필요한 변경 사항만 overlay로 덮어쓰는 방식이다. 이를 통해 레플리카 수, CPU/메모리 자원 제한 등 환경에 따라 달라지는 세부 설정을 효율적으로 관리할 수 있다.
먼저, 공통 리소스를 모아둘 resource-sample 디렉토리와 환경별 오버레이를 위한 staging, production 디렉토리를 구성한다.
sample
├── production
│ ├── kustomization.yaml
│ └── patch-replicas.yaml
├── resource-sample
│ ├── kustomization.yaml
│ ├── patch-replicas.yaml
│ ├── sample-deployment.yaml
│ └── sample-lb.yaml
└── staging
├── kustomization.yaml
└── patch-replicas.yaml
staging/kustomization.yaml
bases: 공통 설정이 있는 base 디렉토리의 상대 경로를 지정한다.
patchesStrategicMerge: base에 덮어쓸 내용을 담은 패치(patch) 파일을 지정한다.
images: Staging 환경에 맞는 이미지 태그(staging)를 설정한다.
bases:
- ../resource-sample
patchesStrategicMerge:
- patch-replicas.yaml
images:
- name: nginx
newTag: staging
staging/patch-replicas.yaml
base의 sample-deployment에서 replicas 수만 3개로 변경하는 패치 파일이다. apiVersion, kind, metadata.name을 명시하여 어떤 리소스를 변경할지 정확히 지정해야 한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
kustomize edit fix 명령어를 수행하면 알아서 문제되는 부분 수정해준다


kustomization.yaml 파일이 자동으로 고쳐져 있음그러고 나서 sample 폴더에서
kubectl kustomize staging 명령어를 실행해서 확인해보면 replicas : 3 로 바뀐것을 확인할 수 있다.
apiVersion: v1
kind: Service
metadata:
name: sample-lb
spec:
ports:
- name: http-port
nodePort: 30082
port: 8080
protocol: TCP
targetPort: 80
selector:
app: sample-app
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- image: nginx:staging
name: nginx-container
Staging과 동일한 방식으로 Production 환경을 구성한다. 여기서는 레플리카 수를 10개로 설정한다.
production/kustomization.yaml 생성
bases:
- ../resource-sample
patchesStrategicMerge:
- patch-replicas.yaml
images:
- name: nginx
newTag: production
production/patch-replicas.yaml 생성
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 10
Production 환경 빌드 결과 확인
결과를 보면 replicas가 10으로, 이미지 태그가 production 으로 올바르게 변경된 것을 확인할 수 있다.
kubectl kustomize production
apiVersion: v1
kind: Service
metadata:
name: sample-lb
spec:
ports:
- name: http-port
nodePort: 30082
port: 8080
protocol: TCP
targetPort: 80
selector:
app: sample-app
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 10 # 확인
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- image: nginx:production
name: nginx-container
이처럼 Kustomize의 오버레이 기능을 사용하면 공통 리소스는 base에서 한 번만 관리하고, 각 환경에 필요한 최소한의 변경사항만 overlays에서 관리하여 코드 중복을 피하고 유지보수성을 크게 높일 수 있다.
Kustomize는 configMapGenerator와 secretGenerator를 이용해 ConfigMap과 Secret을 동적으로 생성하는 강력한 기능을 제공한다. 이를 통해 구성 데이터를 코드와 함께 버전 관리하고, 데이터가 변경될 때마다 새로운 리소스를 생성하여 롤링 업데이트를 자연스럽게 유도할 수 있다.
해시 기반 이름 생성: 생성된 ConfigMap이나 Secret의 이름은 kustomization.yaml에 지정한 이름 뒤에 데이터의 해시(hash) 값이 접미사로 부여된다 (<이름>-<해시값>).
불변성(Immutability): ConfigMap의 데이터가 변경되면, Kustomize는 기존 리소스를 수정하는 대신 새로운 해시 값을 가진 새 ConfigMap을 생성한다. 이전에 생성된 ConfigMap은 삭제되지 않고 그대로 남아있다.
자동 참조 업데이트: 가장 중요한 특징으로, Kustomize는 새로 생성된 ConfigMap의 이름을 참조하고 있는 Deployment, Pod 등의 configMapRef 또는 valueFrom 필드를 자동으로 업데이트해준다. 따라서 우리는 데이터가 바뀌어도 Deployment의 YAML 파일을 수정할 필요가 없다.
generate-sample 이라는 디렉토리를 생성하고 실습을 진행한다.
Pod의 환경 변수를 ConfigMap으로부터 주입받도록 envFrom과 configMapRef를 설정한다. 여기서 name은 kustomization.yaml에서 지정할 ConfigMap의 원본 이름(generated-configmap)을 가리킨다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas:
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.16
envFrom:
- configMapRef:
name: generated-configmap
ConfigMap에 파일 형태로 포함시킬 데이터를 준비한다.
(●'◡'●) this is a testfile.
configMapGenerator를 사용하여 ConfigMap을 정의한다.
literals: KEY=VALUE 형식의 데이터를 직접 정의한다.
files: 지정된 파일을 읽어 파일명을 key로, 파일 내용을 value로 하는 데이터를 생성한다.
resources:
- sample-deployment.yaml
configMapGenerator:
- name: generated-configmap
literals:
- KEY1=VAL1
files:
- ./sample.txt
kubectl kustomize 명령으로 최종적으로 생성될 YAML을 미리 확인한다.
jw@master:~/sample$ kubectl kustomize generate-sample
# 실행결과
apiVersion: v1
data:
KEY1: VAL1
sample.txt: |+
(●'◡'●) this is a testfile.
kind: ConfigMap
metadata:
name: generated-configmap-97k5fbgh44
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: null
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- envFrom:
- configMapRef: null
name: generated-configmap
image: nginx:1.16
name: nginx-container
결과에서 볼 수 있듯이, ConfigMap의 이름에 해시값이 추가되었고, Deployment의 configMapRef.name 또한 해시값이 포함된 새 이름으로 자동 업데이트된 것을 확인할 수 있다. 이것이 Kustomize 제너레이터의 핵심 동작 방식이다.
-k 옵션으로 빌드 및 적용을 한 번에 수행한다.
kubectl apply -k generate-sample

Kustomize는 kubectl에 통합되어 다양한 하위 명령어를 통해 쉽게 사용할 수 있다.
kubectl kustomize <디렉토리>
최종적으로 생성될 YAML 파일의 내용을 표준 출력(stdout)으로 보여준다.
kubectl kustomize build <디렉토리>와 동일한 역할을 한다.
kubectl apply -k <디렉토리>
kubectl get -k <디렉토리>
kubectl describe -k <디렉토리>
kubectl delete -k <디렉토리>
kubectl kustomize build <디렉토리> -o <파일명.yaml>
kubectl kustomize build generate-sample -o sample.yaml