kustomize 를 활용한 helm chart 배포

Jaemyeong.Lee·2022년 7월 15일
3

kubernates 에 object 를 deploy 를 하기 위해서는 yaml 파일을 사용해야 하죠. 보통 kubectl apply 명령어을 사용하거나 argoCD 활용하여 배포를 할 경우에도 yaml 파일을 사용해서 배포하게 됩니다.

여기서 주목할 점은 yaml 파일을 만들어서 배포하는 경우 아래와 같은 불편함이 생깁니다.

  • yaml 파일을 직접 수정하다보니 pod spec, indent 등의 오류를 내기 쉽습니다.
  • 실제 배포에 필요한 object 를 모두 yaml 로 작성을 해야 합니다.
  • 누락된 object 가 있는지 알 수 없습니다.
  • probe, monitoring 등 세부적인 설정도 신경써서 작성해야 합니다.
  • 결국 pod 1개, 테스트용 deploy 같이 단순한 형태인 경우만 가능합니다.

제 생각에는 위 문제를 보완하기 위해서 helm chart 가 만들어진거 같습니다. helm release 명령어로 일련의 objects 를 한꺼번에 생성할 수도 있고, 한꺼번에 삭제할 수도 있으니까요. helm 를 이용한 배포 방법은 helm chart 와 values.yaml 의 내용으로 배포할 수 있습니다.

helm 배포, helm release

아래는 helm 을 사용하여 배포하는 방법입니다. 보다 자세한 설명은 링크를 참고하세요.

$ helm repo add bitnami https://charts.bitnami.com/bitnami

$ helm search repo bitnami
NAME                             	CHART VERSION	APP VERSION  	DESCRIPTION
bitnami/bitnami-common           	0.0.9        	0.0.9        	DEPRECATED Chart with custom templates used in ...
bitnami/airflow                  	8.0.2        	2.0.0        	Apache Airflow is a platform to programmaticall...
bitnami/apache                   	8.2.3        	2.4.46       	Chart for Apache HTTP Server
bitnami/aspnet-core              	1.2.3        	3.1.9        	ASP.NET Core is an open-source framework create...
# ... and many more

$ helm repo update    # Make sure we get the latest list of charts
$ helm install bitnami/mysql --generate-name
NAME: mysql-1612624192
LAST DEPLOYED: Sat Feb  6 16:09:56 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES: ...

$ helm list
NAME            	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART      	APP VERSION
mysql-1612624192	default  	1       	2021-02-06 16:09:56.283059 +0100 CET	deployed	mysql-8.3.0	8.0.23

$ helm uninstall mysql-1612624192
release "mysql-1612624192" uninstalled

helm release 배포도 나름 깔끔한 느낌이 듭니다.

이 글은 helm 을 배포하는데 helm template 과 kustomize 를 사용하는 배포 방법에 대해 소개해 드리려고 합니다. helm 배포 방식과 kustomize 를 사용한 방법이 어떤 차이와 이점이 있는지 비교해 보시기 바랍니다.

실습을 위해서는 아래 설치가 필요합니다.

설치가 다 됐으면 이제 시작해 보겠습니다.

첫번째 방법, helm template

첫번째 방법은 위에서 사용했던 helm release 를 이용해서 직접 배포하지 않고 helm chart 의 전체 내용을 yaml 형태로 만든 다음 kubectl apply -f 명령어를 사용하여 배포하는 방식입니다. 솔직히 helm chart 를 배포하면서 이 방법을 사용하시는 분은 거의 없을거란 생각이 드는데요. helm chart 를 직접 배포하면 되지 왜 yaml 파일을 만들어야 할까요?

이 방법의 장점은 다음과 같습니다.

  • helm chart 와 values.yaml 을 수정하면서 배포될 yaml 파일을 미리 검토해 볼 수 있습니다.
  • 배포하기 전에 kubectl diff -f temp.yaml 명령어로 이미 배포된 항목을 있을 경우 변경되는 내용을 미리 검토해 볼 수 있습니다.
  • kubectl apply -f temp.yaml --dry-run=server/client 명령어로 실제 배포에 문제가 없는지 미리 검토해 볼 수 있습니다.
  • helm release 방식의 장점과 yaml 파일 방식의 장점을 동시에 취할 수 있습니다.

자 이제 실제 배포 작업을 수행해 보겠습니다. helm release 방식과 비교해 보시고 위 장점도 확인해보세요. 아래 작업은 argoCD 를 설치하는 과정입니다.

## helm repoistory 를 등록합니다.
$ helm repo add argo https://argoproj.github.io/argo-helm
"argo" has been added to your repositories

## helm template 으로 temp.yaml 파일을 생성합니다.
$ helm template my-argocd argo/argo-cd > temp.yaml
created temp.yaml

## temp.yaml 파일의 내용을 확인합니다.
$ cat temp.yaml
...실제 배포에 사용될 yaml 파일을 확인할 수 있습니다...

## kubectl apply 로 배포합니다.
$ kubectl apply -f temp.yaml -n my-argocd
deployment.apps/my-argocd-application-controller created
deployment.apps/my-argocd-repo-server created
deployment.apps/my-argocd-server created
deployment.apps/my-argocd-dex-server created
deployment.apps/my-argocd-redis created

## pod 확인
$ kubectl get pod -n my-argocd
NAME                                                READY   STATUS    RESTARTS   AGE
my-argocd-application-controller-844b4d5947-rt45c   1/1     Running   0          39s
my-argocd-dex-server-556657c7f4-xbjr8               1/1     Running   0          38s
my-argocd-redis-88db9fff8-wxrx4                     1/1     Running   0          38s
my-argocd-repo-server-66c569469c-b4q7x              1/1     Running   0          39s
my-argocd-server-674ffff767-5gzch                   1/1     Running   0          38s

replicas 를 변경하기 위해 아래 내용으로 my-values.yaml 파일을 생성합니다.

# my-values.yaml
controller:
  replicas: 2
server:
  replicas: 2

수정한 my-values.yaml 을 적용하여 배포합니다. 여기서는 kubectl diff 명령어와 --dry-run 옵션을 사용하여 배포전에 이미 배포된 항목과 비교해 보려고 합니다.

## my-values.yaml 로 temp.yaml 파일을 생성합니다.
$ helm template my-argocd argo/argo-cd -f my-values.yaml > temp.yaml
created temp.yaml

## temp.yaml 파일의 내용에서 replicas: 부분을 확인합니다.
$ cat temp.yaml | grep replicas: -B 20
...replicas 값이 변경된 것을 확인합니다...
  
## kubectl diff 명령어로 이전 배포 항목과 비교합니다.
$ kubectl diff -f temp.yaml -n my-argocd > diff.yaml
created diff.yaml

## diff.yaml 파일을 확인합니다. 차이점을 - + 로 표시해 줍니다.
$ cat diff.yaml
...중략...
-  replicas: 1
+  replicas: 2 
...중략...
-  replicas: 1
+  replicas: 2 
...중략...

## --dry-run=client 옵션으로 yaml 파일 validation 을 체크합니다.
$ kubectl apply -f temp.yaml -n my-argocd --dry-run=client
...중략...
deployment.apps/my-argocd-application-controller configured (dry run)
deployment.apps/my-argocd-repo-server configured (dry run)
deployment.apps/my-argocd-server configured (dry run)
deployment.apps/my-argocd-dex-server configured (dry run)
deployment.apps/my-argocd-redis configured (dry run)

## --dry-run=server 옵션으로 yaml 파일이 배포되는 시점의 validation 을 체크합니다.
$ kubectl apply -f temp.yaml -n my-argocd --dry-run=server
...중략...
deployment.apps/my-argocd-application-controller configured (server dry run)
deployment.apps/my-argocd-repo-server unchanged (server dry run)
deployment.apps/my-argocd-server configured (server dry run)
deployment.apps/my-argocd-dex-server unchanged (server dry run)
deployment.apps/my-argocd-redis unchanged (server dry run)
  • --dry-run=server 옵션은 label selector, pvc spec 변경 등 pod 가 실행중인 상태에서 변경할 수 없는 리소스를 체크해 줍니다.
  • label selector, pvc spec 변경이 필요한 경우에는 기존 리소스를 먼저 삭제하고 배포해야 합니다.
## 최종 yaml 파일을 배포합니다.
$ kubectl apply -f temp.yaml -n my-argocd
deployment.apps/my-argocd-application-controller configured
deployment.apps/my-argocd-repo-server unchanged
deployment.apps/my-argocd-server configured
deployment.apps/my-argocd-dex-server unchanged
deployment.apps/my-argocd-redis unchanged

## pod count 변화 확인
$ kubectl get pod -n my-argocd
NAME                                                READY   STATUS              RESTARTS   AGE
my-argocd-application-controller-844b4d5947-5g6pn   1/1     Running             0          12m
my-argocd-application-controller-844b4d5947-wvwrj   0/1     ContainerCreating   0          2s
my-argocd-dex-server-556657c7f4-8wsn6               1/1     Running             0          12m
my-argocd-redis-88db9fff8-jztjj                     1/1     Running             0          12m
my-argocd-repo-server-66c569469c-4n79h              1/1     Running             0          12m
my-argocd-server-674ffff767-c8b2r                   0/1     ContainerCreating   0          2s
my-argocd-server-674ffff767-dt6r4                   1/1     Running             0          12m

kubectl delete -f temp.yaml 명령어로 배포된 리소스를 삭제할 수 있습니다.

## kubectl delete 사용
## 이전에 배포했던 temp.yaml 파일을 사용해야 합니다.
$ kubectl delete -f temp.yaml -n my-argocd
...중략...
deployment.apps "my-argocd-application-controller" deleted
deployment.apps "my-argocd-repo-server" deleted
deployment.apps "my-argocd-server" deleted
deployment.apps "my-argocd-dex-server" deleted
deployment.apps "my-argocd-redis" deleted
  • namesapce 를 삭제하는 방법도 있으나, customresorcedefinition, cluterrole, clusterrolebinding 등 namespace 범위밖에 있는 리소스가 있기 때문에 이전에 배포했던 temp.yaml 파일을 사용해서 삭제하도록 합니다.

두번째 방법, kustomize

두번째 방법은 helm template 과 kustomize 기능을 결합하는 방식입니다. 왜 kustomize 를 같이 써야 하는지? 이 방법에는 어떤 이점이 있을까요?

첫번째 방법인 helm template 의 단점은 아래와 같습니다.

  • helm template 으로 생성된 temp.yaml 파일을 values.yaml 을 이용해서 생성하기 때문에 helm chart 가 생성한 내용만 배포할 수 있습니다.
  • 예를들면 values.yaml 내용을 보시면 imagePullSecrets: 항목이 있습니다. docker-repo 인증을 위해 secret name 을 입력해야 하는데요. secret 을 미리 생성해야 배포시 에러가 발생하지 않게 됩니다.
  • imagePullSecrets 처럼 pvc, configmap, secret 등 미리 생성된 object 를 써야 하는 경우가 많이 발생합니다.

위와 같은 상황에선 kubectl apply -f temp.yaml -f serets.yml 처럼 파일명을 여러개 사용하면 가능하지만 kustomize 를 사용하면 관리가 쉬워집니다. 그리고 helm repo 를 등록하는 과정도 필요없게 됩니다.

자 이제 kusomize 를 이용해서 배포를 해보겠습니다. my-values.yaml 파일은 위에서 사용한 것을 그대로 사용합니다.

## kustomization.yaml 파일을 생성하고 아래 내용을 작성합니다.
helmCharts:
  - name: argo-cd
    repo: https://argoproj.github.io/argo-helm
    version: 3.26.5
    releaseName: my-argocd
    namespace: my-argocd
    valuesFile: my-values.yaml 
    includeCRDs: true # CustomResourceDefinition 이 있을 경우 true
## kustomize build 명령어로 배포용 yaml 파일을 생성합니다.
$ kustomize build . --enable-helm > temp.yaml
created temp.yaml

## temp.yaml 파일의 내용을 확인합니다.
$ cat temp.yaml
...yaml 전체를 확인합니다...

## 최종 yaml 파일을 배포합니다.
$ kubectl apply -f temp.yaml -n my-argocd
...생략...
deployment.apps/my-argocd-application-controller created
deployment.apps/my-argocd-dex-server created
deployment.apps/my-argocd-redis created
deployment.apps/my-argocd-repo-server created
deployment.apps/my-argocd-server created

## pod  확인
$ kubectl get pod -n my-argocd
NAME                                                READY   STATUS    RESTARTS   AGE
my-argocd-application-controller-57b9d9f584-ctctl   1/1     Running   0          25s
my-argocd-application-controller-57b9d9f584-rq5qz   1/1     Running   0          25s
my-argocd-dex-server-b8cdffbbc-dcksr                1/1     Running   0          25s
my-argocd-redis-7b46b74bc9-4dbgc                    1/1     Running   0          25s
my-argocd-repo-server-5745dc9456-grg79              1/1     Running   0          25s
my-argocd-server-b598c7865-5jd8t                    1/1     Running   0          24s
my-argocd-server-b598c7865-b92gt                    1/1     Running   0          24s

혹시 kustomize 를 써보신 분이라면 kubectl apply -k . 명령어로 배포가 가능하다는 걸 아실겁니다. 한번 배포를 해보겠습니다.

$ kubectl apply -k .
error: json: unknown field "includeCRDs"
# kubectl apply -k 로는 배포가 되지 않습니다.
# 이유는 kustomize build 에서 --enable-helm 옵션이 필요하기 때문입니다.

이제 kustomzie 에 대한 장점을 사용해보도록 하겠습니다. 위에서 예시로 들었던 imagePullSecrets 을 미리 만들어서 넣어주는 작업을 해보겠습니다.
예시를 위해 id, password 로 작성했습니다. 실제 동작하지는 않으니 imagePullSecrets 을 my-values.yaml 에 넣지 마세요.

## 아래와 같은 secret 을 추가로 배포하기 위해 my-secret.yaml 파일을 생성합니다.
# my-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: my-argocd-secret
type: Opaque
stringData:
  id: someid
  password: somepassword

## kustomization.yaml 파일에 my-secret.yaml 리소스를 추가한다.
helmCharts:
  - name: argo-cd
    repo: https://argoproj.github.io/argo-helm
    version: 3.26.5
    releaseName: my-argocd
    namespace: my-argocd
    valuesFile: my-values.yaml 
    includeCRDs: true

resources:
  - my-secret.yaml
## kustomize build 명령어로 배포용 yaml 파일을 생성합니다.
$ kustomize build . --enable-helm > temp.yaml
created temp.yaml

## temp.yaml 파일의 내용을 확인합니다.
$ cat temp.yaml | grep my-argocd-secret -A 3 -B 3
# 아래와 유사한 출력을 볼 수 있습니다.
apiVersion: v1
kind: Secret
metadata:
  name: my-argocd-secret
stringData:
  id: someid
  password: somepassword
type: Opaque

## kubectl diff 명령어로 이전 배포 항목과 비교합니다.
$ kubectl diff -f temp.yaml -n my-argocd
# 아래와 유사한 출력을 볼 수 있습니다.
+apiVersion: v1
+data:
+  id: YmFy
+  password: YmFy
+kind: Secret
+metadata:
+  name: my-argocd-secret
+  namespace: my-argocd
+type: Opaque

## 최종 yaml 파일을 배포합니다.
$ kubectl apply -f temp.yaml -n my-argocd
...중략...
secret/my-argocd-secret created
...중략...

여기까지 helm chart 와 kustomize 를 사용하여 배포 작업을 해봤습니다. 어떠신가요? 장점이 보이시나요? 제 개인적으로는 아주 유용하게 사용하고 있습니다.

kustomize 추가기능

kustomize 추가 기능으로 helm chart 를 여러개 묶어서 배포하는 방법을 알려드리겠습니다. 아래 예시는 argoCD 가 redis 를 사용하고 있는데요. 내장 redis 대신 추가로 redis 를 설치해서 사용하도록 설정을 해보겠습니다.

## 2개의 helm chart 를 배포하는 kustomization.yaml 을 각각 생성합니다.
## 아래와 같은 폴더 구조를 생성합니다.
./root
  ./argocd
    kustomization.yaml
    my-values.yaml
  ./argocd-redis
    kustomization.yam
    my-values.yaml
  kustomization.yaml

## ./argocd/kustomization.yaml
helmCharts:
  - name: argo-cd
    repo: https://argoproj.github.io/argo-helm
    version: 3.26.5
    releaseName: my-argocd
    namespace: my-argocd
    valuesFile: my-values.yaml
    includeCRDs: true

## ./argocd-redis/kustomization.yaml
helmCharts:
  - name: redis
    repo: https://charts.bitnami.com/bitnami
    version: 16.4.0
    releaseName: my-argocd-redis
    namespace: my-argocd
    valuesFile: my-values.yaml
    includeCRDs: false

## ./kustomization.yaml
bases:
  - argocd
  - argocd-redis
## ./root 폴더에서 kustomize 명령을 실행합니다.
$ kustomize build . --enable-helm > temp.yaml
created temp.yaml

## temp.yaml 파일을 확인합니다.
$ cat temp.yaml
...생략...

## 최종 yaml 파일을 배포합니다.
## my-argocd-redis-master 가 추가로 배포된 것을 확인할 수 있습니다.
$ kubectl apply -f temp.yaml -n my-argocd
...중략...
deployment.apps/my-argocd-application-controller created
deployment.apps/my-argocd-dex-server created
deployment.apps/my-argocd-redis created
deployment.apps/my-argocd-repo-server created
deployment.apps/my-argocd-server created
tatefulset.apps/my-argocd-redis-master created

## pod  확인
## my-argocd-redis-master 가 추가로 배포된 것을 확인할 수 있습니다.
$ kubectl get pod -n my-argocd
NAME                                                READY   STATUS    RESTARTS   AGE
my-argocd-application-controller-57b9d9f584-2gp82   1/1     Running   0          30s
my-argocd-application-controller-57b9d9f584-8jbw6   1/1     Running   0          30s
my-argocd-dex-server-b8cdffbbc-n4jln                1/1     Running   1          29s
my-argocd-redis-7b46b74bc9-v5nsg                    1/1     Running   0          29s
my-argocd-redis-master-0                            1/1     Running   0          28s
my-argocd-repo-server-5745dc9456-47g9g              1/1     Running   0          29s
my-argocd-server-b598c7865-j55wb                    1/1     Running   0          28s
my-argocd-server-b598c7865-kw6lz                    1/1     Running   0          28s

argoCD 내장 redis 외에 추가로 my-argocd-redis-master-0 pod 가 실행중인 것을 볼 수 있습니다. argoCD 내장 redis 는 cluster 설치가 안되므로 별도로 redis cluster 를 설치해야 할 경우 사용할 수 있는 방법입니다.

마지막으로

마지막으로 kustomize 는 다양한 기능을 가지고 있으니 꼭 한번 가이드를 확인해보시기 바랍니다. kustomize 가이드

.감사합니다.

0개의 댓글