동일한 쿠버네티스 리소스를 개발, 운영, 테스트 등의 여러 환경에 배포하다보면, 각 환경별로 몇몇 설정값을 다르게 해야할 경우가 있다.
예를 들어, 환경별로 환경변수의 내용이나 설정 값들이 달라지거나, 사용할 이미지의 버전이 다르거나...
이러한 상황에서 각 리소스들의 Yaml을 전부 따로 만들어서 수정해주게 되면, 일부만 변경된 리소스 파일이 생겨나기에 관리에 비효율적이게 된다.
Kustomize를 통해 이러한 상황에서 리소스에서 필요한 부분만을 변경해서 사용할 수 있다.
Kustomize
쿠버네티스 리소스의 설정을 직접 변경하지 않고, 필드를 재정의해서 새로운 리소스로 생성할 수 있는 CLI 도구
Kustomize는 객체지향 프로그래밍에서 사용했던것과 같이 '상속'의 개념을 통해 리소스들의 필드를 재정의해서 새로운 리소스로 만들어낸다.
기본이 될 base 리소스 파일을 '상속'받아, 변경할 내용을 담은 patch를 적용함으로써 새로운 리소스를 만들게 되는 동작구조를 가진다.
Kustomization
이러한 patch 파일은 kustomization 파일로, 쿠버네티스 오브젝트 파일 형식으로 작성되는 yml 파일이다.
파일명은 kustomization.yml 로 지정되어야 사용할 수 있으며, 이 파일은 한 디렉토리 내에서 유일해야한다.
(kutomization을 적용할 경우, 자동적으로 지정한 경로내에서 'kustomization.yaml', 'kustomization.yml', 'Kustomization' 들을 탐색한다.)
kustomization 파일은 아래와 같이 4가지 필드가 기본이 된다.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# kustomize를 적용할 기본(base) 리소스 파일
resources:
- {pathOrUrl}
- ...
# 아래 3가지는 base를 기반으로 kustomize가 수행할 작업에 대한 내용
generators:
- {pathOrUrl}
- ...
transformers:
- {pathOrUrl}
- ...
validators:
- {pathOrUrl}
- ...
이들 외에도 다양한 필드들이 지원되고, 그 중 가장 많이 사용되는 필드는 resource와 patches가 된다.
- resource : 어떤 파일을 kustomize 대상으로 지정할 지 설정하는 필드
- 디렉토리나 파일명을 지정할 수 있고, github repository와 같은 원격 URL도 지정가능하다.
- patches : resource로 지정된 파일을 어떻게 수정할 지 내용을 작성하는 필드
적용가능한 다양한 필드에 대해서는 공식 Docs를 참조
Overlays
Kustomize에서 리소스들을 환경별로 구분하기 위해 사용하는 개념으로, base 리소스를 상속받아 사용할 수 있도록 보통 아래와 같이 디렉토리를 구성해 사용한다.
.
├── base
│ ├── base-nginx.yaml
│ └── kustomization.yaml
└── overlays
├── dev
│ ├── dev-patches.yaml
│ └── kustomization.yaml
└── test
├── test-patches.yaml
└── kustomization.yaml
base 디렉토리에는 모든 환경에서 공통으로 사용할 리소스들을 담는다. 즉, base는 다른 kustomization의 참조 대상이 되는 것이다.
(overlay에 존재하는 kustomization도 다른 kustomization의 base가 될 수 있다.)
overlays에서는 적용할 환경별로 구분한 뒤, 각 환경에 맞는 patch 내용(kustomization 파일)들을 담는다. overlay는 base 없이는 사용할 수 없다.
이러한 구조를 통해 조금 더 환경별로 직관적으로 확인할 수 있고, base 리소스의 재사용성을 높일 수 있다.
실습
먼저, 간단하게 nginx deployment를 두 환경(dev / test)에 배포하는 상황을 구성해본다.
두 환경에 각각 다른 설정을 적용한 deployment를 적용하고자 할 때, yaml 파일을 일일히 수정하는 것이 아닌 Kustomize를 이용해 적용할 수 있다는 것이다.
이 상황에서 2개의 환경에 적용할 리소스를 생성하는 Kustomization 파일들은 아래와 같이 작성할 수 있다.
### base/kustomization.yml
resources:
- base-nginx.yml
### overlays/dev/kustomization.yml
resources:
- ../../base
replicas:
- name: nginx
count: 3
### overlays/test/kustomization.yml
resources:
- ../../base
replicas:
- name: nginx
count: 2
kustomization 파일에 직접 patch 내용을 적을 수도 있고, patch 내용을 적은 yml 파일을 patches 필드를 통해 불러오는 방식도 가능하다.
### overlays/dev/dev-patches.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
### overlays/dev/kustomization.yml
resources:
- ../../base
patches:
- path: dev-patches.yaml
위와 같이 kustomization들을 구성한 뒤 아래 명령어로 kustomization된 리소스 yml 내용을 확인할 수 있다.
(kustomize는 쿠버네티스 1.14 버전부터 kubectl에 내장되어 지원하기 시작했다.)
# kubectl kustomize [kustomization 파일 경로]
kubectl kustomize overlays/dev
kubectl kustomize overlays/test
# kustomize된 내용을 적용
kubectl kustomize overlays/dev | kubectl apply -f -
다음으로 pod에 적용할 ConfigMap을 kustomize를 통해 환경별로 다르게 적용해보도록한다.
환경별로 다른 API 키나 config를 적용하는 상황 등에서 사용될 수 있다.
ConfigMap 리소스를 생성하는데에는 configMapGenerator 필드를 사용할 수 있다.
이를 통해 ConfigMap 내용을 pod의 환경변수로 삽입할 수 있다.
### overlays/dev/kustomization.yml
resources:
- ../../base
configMapGenerator:
- name: env-vars # base에 지정된 configMap의 이름과 동일하게 지정
envs:
- dev.env # dev.env 파일 내용을 바탕으로 configMap이 생성
### dev.env
APIKEY=1234abcd
ENV_SET=dev
### overlays/test/kustomization.yml
resources:
- ../../base
configMapGenerator:
- name: env-vars
envs:
- test.env
### test.env
APIKEY=abcd1234
ENV_SET=test
Kustomize와 Helm
리소스 코드의 재사용성을 추구한다는 점에서 Kustomize는 Helm과 함께 비교될 수 있다. 하지만 이 둘은 추구하는 원칙과 동작 방식에서 차이가 있다는 것을 알아두어야 한다.
예를 들어, Chart에서 템플릿에 정의된 필드의 값들을 수정할 수 있지만, 필드를 새로 추가하거나 삭제하는 등의 행동은 할 수 없다.
반면, Kustomize는 새로운 필드를 추가하고 삭제할 수 있다.
따라서 운영하는 환경에 적합하다고 판단되는 것을 사용하거나, 이 둘을 함께 사용하는 등 자유롭게 선택할 수 있을 것이다.
특징 | Kustomize | Helm |
목적 | 쿠버네티스 리소스 구성 관리 | App을 배포하는 패키지 매니저 |
구성 컴포넌트 | base, overlays, patch | Chart |
동작방식 | base를 기반으로 Patch 방식을 통해 환경별 설정 구성 | Go 기반 템플릿을 이용해 템플릿 변수 값을 수정하며 적용 |
버전관리 | X | Chart에 버전을 지정해 관리 가능 |