Kubernetes : Kustomize를 이용한 쿠버네티스 매니페스트 관리

JIWON·2025년 8월 11일

Kubernetes

목록 보기
27/32
post-thumbnail

1. Kustomize란?

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) 관리'보다 일관성 있고 예측 가능한 상태를 유지하는 데 유리하다.


2. 기본 사용법: 여러 매니페스트 결합하기

1) 리소스 파일 준비

먼저, 배포할 쿠버네티스 리소스 파일들을 준비한다. 예를 들어 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

2) kustomization.yaml 파일 생성

이제 두 리소스 파일을 묶어주기 위한 kustomization.yaml 파일을 같은 디렉토리에 생성한다. resources 필드에 관리할 YAML 파일 목록을 지정한다.

kustomization.yaml

resources:
- sample-deployment.yaml
- sample-lb.yaml

3) 빌드 및 적용

빌드 결과 미리보기: apply 하기 전에 어떤 결과물이 생성될지 미리 확인할 수 있다.

# kustomization.yaml 파일이 있는 디렉토리를 지정한다.
kubectl kustomize resource-sample

클러스터에 적용: -k 옵션을 사용하여 Kustomize 설정을 클러스터에 바로 적용한다.

kubectl apply -k resource-sample

리소스 삭제: 적용과 마찬가지로 -k 옵션을 사용해 관련된 모든 리소스를 한 번에 삭제할 수 있다.

kubectl delete -k resource-sample

3. Kustomize 주요 기능

kustomization.yaml 파일에 다양한 필드를 추가하여 리소스를 유연하게 변경할 수 있다.

1) 네임스페이스 일괄 지정

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

2) 공통 이름 접두사/접미사 부여

namePrefixnameSuffix를 이용하면 모든 리소스의 metadata.name에 공통된 접두사와 접미사를 붙일 수 있다. 환경별로 리소스를 구분할 때 유용하다.

kustomization.yaml

namePrefix: prefix-
nameSuffix: -suffix

resources:
- sample-deployment.yaml
- sample-lb.yaml

적용 시 prefix-sample-deployment-suffix 와 같은 이름으로 리소스가 생성된다.

3) 공통 레이블 및 어노테이션 설정

commonLabelscommonAnnotations를 사용하면 모든 리소스의 메타데이터에 공통 레이블과 어노테이션을 추가할 수 있다.

kustomization.yaml

commonLabels:
  label1: label1-val
commonAnnotations:
  annotation1: annotation1-val
  
# 기존
resources:
- ...

4) 이미지 변경

images 필드를 사용하면 특정 컨테이너 이미지의 이름, 태그 등을 손쉽게 변경할 수 있다. 이는 환경별로 다른 버전의 이미지를 배포할 때 매우 유용하다.

kustomization.yaml

images:
- name: nginx # 원본 이미지 이름
  newName: amsy810/echo-nginx # 변경할 이미지 이름
  newTag: v2.0 # 변경할 이미지 태그

resources:
- sample-deployment.yaml
- sample-lb.yaml

📌주의: name에 일치하는 모든 컨테이너 이미지가 변경되므로, 여러 Deployment에서 동일한 이름의 이미지를 사용 중이라면 모두 영향을 받는다.


4. 오버레이(Overlay)로 환경별 설정 덮어쓰기

Kustomize의 가장 주 기능은 오버레이(Overlay) 이다. 공통적인 설정을 base로 두고, 각 환경(staging, production 등)에 필요한 변경 사항만 overlay로 덮어쓰는 방식이다. 이를 통해 레플리카 수, CPU/메모리 자원 제한 등 환경에 따라 달라지는 세부 설정을 효율적으로 관리할 수 있다.

1) 디렉토리 구조 설정

먼저, 공통 리소스를 모아둘 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

2) Staging 환경 구성

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

basesample-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

3) Production 환경 구성

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 환경 빌드 결과 확인
결과를 보면 replicas10으로, 이미지 태그가 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에서 관리하여 코드 중복을 피하고 유지보수성을 크게 높일 수 있다.


5. ConfigMap과 Secret 동적 생성

Kustomize는 configMapGeneratorsecretGenerator를 이용해 ConfigMap과 Secret을 동적으로 생성하는 강력한 기능을 제공한다. 이를 통해 구성 데이터를 코드와 함께 버전 관리하고, 데이터가 변경될 때마다 새로운 리소스를 생성하여 롤링 업데이트를 자연스럽게 유도할 수 있다.

  • 해시 기반 이름 생성: 생성된 ConfigMap이나 Secret의 이름은 kustomization.yaml에 지정한 이름 뒤에 데이터의 해시(hash) 값이 접미사로 부여된다 (<이름>-<해시값>).

  • 불변성(Immutability): ConfigMap의 데이터가 변경되면, Kustomize는 기존 리소스를 수정하는 대신 새로운 해시 값을 가진 새 ConfigMap을 생성한다. 이전에 생성된 ConfigMap은 삭제되지 않고 그대로 남아있다.

  • 자동 참조 업데이트: 가장 중요한 특징으로, Kustomize는 새로 생성된 ConfigMap의 이름을 참조하고 있는 Deployment, Pod 등의 configMapRef 또는 valueFrom 필드를 자동으로 업데이트해준다. 따라서 우리는 데이터가 바뀌어도 Deployment의 YAML 파일을 수정할 필요가 없다.

1) 실습: 동적 ConfigMap 생성 및 적용

generate-sample 이라는 디렉토리를 생성하고 실습을 진행한다.

① sample-deployment.yaml 파일 생성

Pod의 환경 변수를 ConfigMap으로부터 주입받도록 envFromconfigMapRef를 설정한다. 여기서 namekustomization.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

② sample.txt 파일 생성

ConfigMap에 파일 형태로 포함시킬 데이터를 준비한다.

(●'◡'●) this is a testfile.

③ kustomization.yaml 파일 생성

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


6. 주요 kubectl Kustomize 명령어

Kustomize는 kubectl에 통합되어 다양한 하위 명령어를 통해 쉽게 사용할 수 있다.

kubectl kustomize <디렉토리>

  • 최종적으로 생성될 YAML 파일의 내용을 표준 출력(stdout)으로 보여준다.

  • kubectl kustomize build <디렉토리>와 동일한 역할을 한다.

kubectl apply -k <디렉토리>

  • Kustomize 빌드 결과물을 클러스터에 적용한다.

kubectl get -k <디렉토리>

  • Kustomize로 생성될 리소스들의 정보를 조회한다.

kubectl describe -k <디렉토리>

  • 리소스들의 상세한 정보를 조회한다.

kubectl delete -k <디렉토리>

  • Kustomize로 적용했던 모든 리소스를 한 번에 삭제한다.

kubectl kustomize build <디렉토리> -o <파일명.yaml>

  • 빌드 결과를 화면에 출력하는 대신, 지정된 파일로 저장한다.
    kubectl kustomize build generate-sample -o sample.yaml

0개의 댓글