들어가며
애플리케이션을 쿠버네티스에 본격적으로 배포하기 시작하면, 개발 단계에서는 접하지 못했던 어려운 점이 발생할 수 있습니다. 그 중 가장 흔히 맞닥뜨리는 2가지를 꼽아보면 다음과 같습니다.
•
애플리케이션을 구성하는 각 쿠버네티스 리소스 yaml 파일의 관리
•
애플리케이션이 배포되는 환경 또는 스테이지별 관리
Helm과 Kustomize는 이런 문제를 해결하기 위한 것으로, 쿠버네티스 애플리케이션 패키징 및 구성 도구로 사용되고 있습니다.
Helm과 Kustomize의 목적은 유사하지만, 각각의 장단점이 명확히 있어서 상황에 맞게 선택하여 사용하면 됩니다.
미리 설명하자면, Helm은 Chart(차트)를 통해 전체 애플리케이션을 패키징하고 배포하는 기능이 주기능이며, Kustomize는 쿠버네티스 오브젝트 매니페스트를 원하는 대로 변경/조합(customize)하여 환경 별로 애플리케이션의 배포를 구성하는 것이 주기능입니다.
이 문서에서는 Helm, Kustomize를 살펴보고 각각의 특징과 사용 목적, 그리고 간단한 사용 예시를 살펴보겠습니다.
Helm
Helm은 python의 pip 같은 패키지 매니저로, 쿠버네티스 애플리케이션을 패키징하고 배포를 도와주는데 초점이 맞추어져있습니다.
Helm을 이용하면 다른 누군가 패키징한 애플리케이션을 쿠버네티스 클러스터에 손쉽게 설치할 수 있으며, 나의 애플리케이션 역시 Helm Chart로 패키징할 수 있습니다.
Helm은 차트(Chart)라고 불리는 형태로 애플리케이션을 패키징하며, 차트는 애플리케이션의 배포, 구성 및 관리에 필요한 모든 리소스를 포함하게 됩니다.
차트는 템플릿화된 Kubernetes 매니페스트 파일들의 모음으로 구성되어 있으며, 배포를 위해 이러한 템플릿에 값들을 values.yaml 파일을 통해 매개변수화하여 전달할 수 있습니다.
Helm은 기본적으로는 차트를 설치하고 업그레이드하는 기능을 하며, 이를 위한 명령어와 기능 역시 제공합니다.
Architecture
Helm의 기본적인 아키텍처 및 흐름은 다음과 같습니다.
Chart 기본 구조
차트는 디렉터리 안에 manifest 파일들의 모음이며, 디렉터리명은 버전 정보가 없는 차트명으로 구성됩니다.
따라서, 아래 예시의 WordPress 를 설명하는 차트는 wordpress/ 디렉터리 하위에 구성됩니다.
디렉터리 안에서 Helm Chart는 다음과 같은 구조를 가집니다.
wordpress/
├── Chart.yaml # 차트에 대한 정보를 가진 YAML 파일
├── templates/ # values와 결합될 때, 유효한 쿠버네티스 manifest 파일들이 생성될 템플릿들의 디렉토리
├── values.yaml # 차트에 대한 기본 환경설정 값들
├── charts/ # 이 차트에 종속된 차트들을 포함하는 디렉토리
└── README.md # 옵션: README 파일
Bash
복사
Helm Chart는 가장 단순하게 다음 3가지로 구성됩니다.
•
Chart.yaml
◦
차트를 설명하는 메타데이터가 작성된 파일로 차트의 필수 구성요소
◦
차트의 이름, 버전, 제작자, 설명 등의 정보를 포함합니다.
•
templates/ 하위 manifest files
◦
애플리케이션의 모든 템플릿 파일이 저장되며 템플릿 엔진을 통해 이 디렉토리 안에 모든 파일이 전달됩니다.
◦
템플릿 파일은 yaml 형식으로, 일반적으로 Deployment, Service, ConfigMap 등의 쿠버네티스 오브젝트를 정의합니다.
◦
템플릿 내에서는 변수와 함수를 사용하여 동적으로 값을 할당할 수 있습니다.
•
values.yaml
◦
차트의 설정 값을 정의하는 파일입니다.
◦
이 파일에는 템플릿 내에서 사용되는 변수와 해당 값을 지정할 수 있습니다.
◦
차트 사용자는 이 파일을 수정하여 애플리케이션의 설정을 구성할 수 있습니다.
Chart 생성 방법
1.
차트 생성
$ helm create chart_name
Bash
복사
2.
생성된 차트 확인
chart_name/
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
└── values.yaml
Bash
복사
3.
tempates/ 하위에 쿠버네티스 manifest 작성 및 values.yaml 작성
Example
- Wordpress Helm chart: https://github.com/bitnami/charts/tree/main/bitnami/wordpress
Kustomize
쿠버네티스 환경을 운영하다보면, 같은 애플리케이션을 다른 클러스터에 배포해야 하는 경우가 있습니다.
예를 들면, 애플리케이션을 ST/QA/OP 환경에 각각 배포해야 하는 상황을 생각해보겠습니다.
각 배포 환경마다 애플리케이션의 환경변수나 설정 값의 변경이 필요한데, 이 때 대부분은 공통이며, 일부분만 변경이 발생 합니다.
이때 각 형상별로 배포 yaml 파일들을 구성하면, 일부만 변경되는 배포 파일 관리를 해야하기 때문에 비효율적이게 됩니다.
Kustomize는 상속개념을 적용하여 변경이 필요한 부분만 작성하는 방식으로 이런 문제를 해결합니다.
Kustomize는
•
쿠버네티스 애플리케이션에 대한 구성 관리를 위한 도구입니다.
Kustomize는 기존의 쿠버네티스 매니페스트 파일을 수정하거나 레이어로써 조합하여 애플리케이션의 배포를 구성할 수 있게 해줍니다.
•
애플리케이션의 특정 배포 환경에 맞게 구성을 쉽게 변경할 수 있으며, 반복적인 작업을 줄이고 중복을 피할 수 있는 장점이 있습니다.
•
단순한 Overlay 기능뿐만 아니라, 환경에 따라 변하는 값을 관리하기 위한 Patch 기능도 제공합니다.
Architecture
Kustomize 기본 구조
.
├── README.md
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlays
├── kic-qa
│ ├── deployment.yaml
│ └── kustomization.yaml
└── kic-st
├── deployment.yaml
└── kustomization.yaml
Bash
복사
•
base/ : 기본 배포 매니페스트 파일 디렉토리
•
overlays/phase/ : 각 환경별로 디렉토리(dev)를 만들고 변경할 내용이 정의된 kustomization.yaml 파일을 작성
kustomization.yaml 파일
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- {pathOrUrl}
- ...
patches:
- {pathOrUrl}
- ...
YAML
복사
kustomization.yaml 파일은 어떻게 파일을 생성하고 변경할지 방법을 기술하는 파일입니다.
여러가지를 파일에 기술할 수 있지만, 대표적으로 많이 사용되는 resources와 patches에 대해서 설명하겠습니다. 이 두가지만으로도 충분히 형상별 변경을 표현할 수 있습니다.
resources
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- myNamespace.yaml
- sub-dir/some-deployment.yaml
- ../../commonbase
- github.com/kubernetes-sigs/kustomize/examples/multibases?ref=v1.0.6
- deployment.yaml
- github.com/kubernets-sigs/kustomize/examples/helloWorld?ref=test-branch
YAML
복사
•
배포 구성에 포함될 쿠버네티스 리소스의 원본 매니페스트 파일들의 리스트
•
디렉토리 또는 파일들로 작성
patches
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: qa-deployment-fix.yaml
target:
kind: Deployment
name: lss-app
YAML
복사
•
patches 필드는 리소스를 수정하기 위한 파일을 지정합니다.
•
위 예제는 ../../base 디렉토리에 있는 yaml들에서 Deployment리소스이며 이름이 lss-app인 리소스 yaml에 qa-deployment-fix.yaml을 patch합니다.
사용법
.
├── README.md
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlays
├── kic-qa
│ ├── deployment.yaml
│ └── kustomization.yaml
└── kic-st
├── deployment.yaml
└── kustomization.yaml
Bash
복사
옆과 같이 kustomize 구성을 완료 한 뒤,
kubectl kustomize <path> 명령어를 사용하면, 각 base, overlays에 작성된 kustomization.yaml이 적용된 매니페스트들이 출력됩니다.
$ kubectl kustomize overlays/kic-qa
Bash
복사
apiVersion: v1
kind: Service
metadata:
name: lss
namespace: ns-lss
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: lss-app
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: lss-app
namespace: ns-lss
spec:
replicas: 1
revisionHistoryLimit: 1
selector:
matchLabels:
app: lss-app
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: lss-app
spec:
containers:
- env:
- name: OWNER
value: LSS
...
- name: serviceCode
value: SVC301
image: <image-repo>/tcn/lss/lss:latest
imagePullPolicy: Always
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- sleep 30
name: lss-app
readinessProbe:
failureThreshold: 3
httpGet:
path: /__health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
limits:
cpu: 200m
requests:
cpu: 200m
nodeSelector:
nodegroup: ng-service
serviceAccountName: sa-csr
terminationGracePeriodSeconds: 60
YAML
복사
그래서 Helm과 Kustomize 중에 뭘 쓰라는건가요?
사실 정답은 없습니다. (…)
쿠버네티스 클러스터에 어떤 애플리케이션을 주로 운영하는지, 클러스터를 어떤식으로 구성하고 사용하는지 등에 따라 어느 도구가 적합한지 달라지게 될테니까요. 아니면, 개인 선호도에 따라 달라질 수도 있습니다.
예를 들면, 저는 초기에는 Helm 을 편하다고 느껴서 선호했고, 직접 만든 서비스도 Helm으로 패키징했었습니다.
그러나 현재는 운영 중인 클러스터의 환경이 7개가 되어 클러스터 환경별 배포 구성 관리가 가장 중요해졌으며, 사용해보니 Helm 보다 manifest의 어느 부분을 수정하게 되는지 직관적으로 확인할 수 있어서 Kustomize를 더 선호하고, 많이 사용 중입니다.
아래는 지극히 주관적인 Helm 과 Kustomize를 요약 비교한 내용입니다.
이 내용을 참고하여 목적과 상황에 맞게 도구를 선택하여 배포를 구성하시되, 꼭 부탁드리고 싶은 내용은 두 도구를 모두 사용해보시고 직접 경험을 통해 더 적합한 도구를 선택하시는 것을 추천드립니다.
Helm | Kustomize | |
주목적 | - 애플리케이션 전체 패키지 관리 및 배포에 더 중점
- 차트를 쉽게 배포 및 업그레이드
- Public 공유하기에 적합 | - 환경별 배포 구성 관리에 적합
- 기존 매니페스트를 환경에 맞게 구성 변경하는데 특화 |
사용성 | - Helm 설치 필요Helm 명령어 숙지 필요 | - 쿠버네티스의 기본 기능으로 포함
- 별도의 설치과정이 필요 없이 kubectl로 바로 사용 가능 |
기능 | - Helm 명령어를 통해 버전관리, chart dependency 관리
- Chart Hook 등 다양한 기능 제공 | - template-free way to customize application configuration |
복잡성 | - 복잡함 | - 간단하고 직관적 |
단위 | - Chart
- 애플리케이션 전체 | - base + overlay
- 기존 매니페스트 + 각 환경별 수정이 필요한 애플리케이션의 일부 |