[Daily morning study] Kubernetes Kustomize - 환경별 설정 오버레이 관리
#daily morning study
Kustomize란
Kustomize는 Kubernetes 리소스 파일을 템플릿 없이 커스터마이징할 수 있게 해주는 도구다. kubectl v1.14부터 기본 내장되어 있어 별도 설치 없이 kubectl apply -k 명령으로 바로 사용할 수 있다.
Helm과 달리 Go 템플릿 문법을 쓰지 않고, 원본 YAML을 그대로 유지하면서 오버레이(overlay) 방식으로 환경별 차이를 관리한다. 원본 YAML을 직접 수정하지 않기 때문에 가독성이 높고 Git diff도 깔끔하다.
핵심 개념
Base와 Overlay
Kustomize의 구조는 두 레이어로 나뉜다.
- Base: 공통 리소스 정의 (Deployment, Service 등 기본 YAML)
- Overlay: Base를 참조하면서 환경별 차이만 덮어쓰는 레이어
k8s/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ └── service.yaml
└── overlays/
├── dev/
│ └── kustomization.yaml
├── staging/
│ └── kustomization.yaml
└── prod/
├── kustomization.yaml
└── replica-patch.yaml
kustomization.yaml
각 디렉토리에는 kustomization.yaml이 있어야 한다. 이 파일이 어떤 리소스를 포함할지, 어떤 패치를 적용할지 정의한다.
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
주요 기능
1. namePrefix / nameSuffix
모든 리소스 이름에 접두사나 접미사를 자동으로 붙여준다. 같은 클러스터 내에서 환경별로 리소스를 구분할 때 유용하다.
overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: dev-
commonLabels:
env: dev
이렇게 하면 my-app Deployment는 dev-my-app으로 배포된다.
2. patches (전략적 병합 패치)
특정 필드만 덮어쓰고 싶을 때 패치를 사용한다. 두 가지 방식이 있다.
Strategic Merge Patch: 기존 YAML 구조를 그대로 써서 변경 부분만 기술
# overlays/prod/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
JSON 6902 Patch: RFC 6902 포맷으로 더 세밀하게 패치
# overlays/prod/kustomization.yaml
patches:
- target:
kind: Deployment
name: my-app
patch: |-
- op: replace
path: /spec/replicas
value: 3
- op: replace
path: /spec/template/spec/containers/0/resources/limits/memory
value: "1Gi"
3. images
이미지 태그를 한 곳에서 관리할 수 있다. CI/CD에서 배포할 때 이미지 태그만 교체하는 패턴에 잘 맞는다.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
images:
- name: my-app
newTag: v1.3.5
CLI에서 직접 태그를 주입하는 것도 가능하다.
kustomize edit set image my-app:v1.3.5
4. configMapGenerator / secretGenerator
ConfigMap과 Secret을 kustomization.yaml 안에서 직접 생성할 수 있다. 파일 내용이 바뀌면 새 해시가 생성되어 자동으로 롤링 업데이트가 트리거된다.
configMapGenerator:
- name: app-config
literals:
- LOG_LEVEL=debug
- DB_HOST=dev-db.internal
files:
- config/app.properties
secretGenerator:
- name: app-secrets
envs:
- .env.dev
해시 자동 생성을 원하지 않으면 options를 추가한다.
generatorOptions:
disableNameSuffixHash: true
5. vars (변수 참조)
다른 리소스의 값을 참조해서 주입할 수 있다. Service의 이름을 Deployment 환경변수에 자동으로 넣는 등의 패턴에서 사용한다.
vars:
- name: SERVICE_NAME
objref:
kind: Service
name: my-app
apiVersion: v1
fieldref:
fieldpath: metadata.name
실제 prod 오버레이 예시
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namePrefix: prod-
commonLabels:
env: production
images:
- name: my-app
newTag: v2.1.0
patches:
- path: replica-patch.yaml
configMapGenerator:
- name: app-config
literals:
- LOG_LEVEL=warn
- DB_HOST=prod-db.internal
# overlays/prod/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5
template:
spec:
containers:
- name: my-app
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "1Gi"
빌드와 배포
# 최종 YAML 미리보기 (실제 적용 안 함)
kubectl kustomize overlays/prod
# 직접 적용
kubectl apply -k overlays/prod
# 삭제
kubectl delete -k overlays/prod
Helm vs Kustomize 비교
| 항목 | Helm | Kustomize |
|---|---|---|
| 방식 | Go 템플릿 | YAML 오버레이 |
| 학습 곡선 | 높음 | 낮음 |
| 패키지 배포 | 지원 (Chart) | 미지원 |
| 원본 YAML 가독성 | 낮음 (템플릿 섞임) | 높음 |
kubectl 내장 | 미지원 | 지원 |
| 시크릿 관리 | Helm Secrets 플러그인 | secretGenerator |
Helm은 외부 차트를 그대로 가져와 배포하거나 패키지로 배포할 때 유리하고, Kustomize는 자체 개발 서비스의 환경별 구성을 직접 관리할 때 깔끔하게 쓸 수 있다. 둘을 함께 쓰는 방식도 많다 — Helm으로 외부 의존성(Prometheus, Nginx Ingress 등)을 설치하고, Kustomize로 자체 서비스를 관리하는 식이다.
ArgoCD와의 연동
ArgoCD는 Kustomize를 기본 지원하므로 Application 정의에서 바로 사용할 수 있다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-prod
spec:
source:
repoURL: https://github.com/org/k8s-configs
path: overlays/prod
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
이 구성으로 Git에 오버레이가 커밋되면 ArgoCD가 자동으로 감지해서 클러스터에 동기화한다.
정리
Kustomize는 템플릿 없이 원본 YAML을 유지하면서 환경별 차이를 명확하게 관리할 수 있다. 특히 dev/staging/prod 환경 분리, 이미지 태그 교체, 환경 변수 주입처럼 반복적인 작업을 일관되게 처리하는 데 강점이 있다. ArgoCD나 Flux 같은 GitOps 도구와 결합하면 선언적 배포 파이프라인을 간결하게 구성할 수 있다.