Prologue
일반적으로 Kubernetes Manifest 파일은 정적인 형태입니다. 따라서 데이터를 수정하기 위해선 파일 자체를 수정해야 합니다. 잘 관리를 한다면야 큰 어려움은 없겠지만, 문제는 CI/CD 등 자동화된 파이프라인을 구축해서 애플리케이션 라이프사이클을 관리할 때 발생합니다.
보통 애플리케이션 이미지를 새로 빌드하게 되면, 빌드 넘버가 변경됩니다. 이렇게 되면 새로운 이미지를 사용하기 위해 Kubernetes Manifest의 Image도 변경되어야 합니다. 하지만 Kubernetes Manifest를 살펴보면, 이를 변경하기 쉽지 않다는 것을 깨닫게 됩니다. Image Tag가 별도로 존재하지 않고 Image 이름에 붙어있기 때문입니다. 이를 자동화 파이프라인에서 변경하려면, sed
명령어를 쓰는 등의 힘든 작업을 (눈물의 똥꼬쇼를)해야 합니다.
Image Tag는 굉장히 단적인 예제입니다. 이 외에도 배포하는 이름에 따라 ConfigMap을 바꿔주고, 또 배포할 때마다 큰 틀은 같지만 조금씩 다른 형태로 데이터를 배포해야 할 때, 매번 Manifest를 수정하는 것은 너무나 비효율적입니다.
Helm Chart는 이런 어려움을 단번에 해결해줍니다. 물론 차트를 처음 만들 때는 번거롭긴 합니다. 필요로 하는 데이터를 template 형태로 작성해서 관리하고 있어야 하고, 단순히 배포만 하면 끝나던 것이 아니라, Helm 차트 자체를 관리해야 하는 노고도 추가됩니다. 그럼에도 불구하고 Helm Chart는 훌륭한 도구이며, 개인적인 의견으론 반드시 사용해야 하는(!) 도구라고 생각합니다.
이번 포스트에선 Helm Chart를 직접 생성해보면서 어떻게 Helm Chart를 만들고 관리할 수 있는지 알아보겠습니다.
Helm Chart
이번 포스트를 진행하기 위해 wookiist
라는 이름의 차트를 만들어보며 설명해보겠습니다.
Chart 생성
helm create
명령을 사용해서 차트를 생성합니다. helm create
명령을 이용해 만든 차트는 nginx
를 예제로 사용하고 있습니다. 다음과 같이 정상적으로 생성되었는지 확인해봅니다.
$ helm create wookiist
$ ls -al wookiist
total 24
drwxr-xr-x 7 jaewook staff 224 6 18 13:15 .
drwxr-xr-x 9 jaewook staff 288 6 18 13:15 ..
-rw-r--r-- 1 jaewook staff 349 6 18 13:15 .helmignore
-rw-r--r-- 1 jaewook staff 1144 6 18 13:15 Chart.yaml
drwxr-xr-x 2 jaewook staff 64 6 18 13:15 charts
drwxr-xr-x 10 jaewook staff 320 6 18 13:15 templates
-rw-r--r-- 1 jaewook staff 1875 6 18 13:15 values.yaml
Chart.yaml 수정
Chart.yaml
파일을 살펴보겠습니다.
apiVersion: v2
name: wookiist
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"
apiVersion
, name
, description
, type
, version
, appVersion
필드를 입력 받습니다. 위 데이터는 helm create
를 수행하면 자동으로 생성되는 데이터입니다. Chart.yaml
파일에는 차트의 기본적인 정보가 담기게 되므로, 실사용할 때는 잘 작성해두어야 합니다. 다만, 이 포스트에서는 Helm 차트를 직접 생성해본다는 데에 의의를 두고 있으므로, 심도 있게 다루지는 않겠습니다. 후에 다른 포스트에서 이 파일에 들어갈 수 있는 정보를 좀 더 다뤄보겠습니다.
values.yaml 수정
values.yaml
파일을 살펴보겠습니다. 사실 살펴볼 것도 없이 굉장히 명확합니다. 이 파일에 기록되는 데이터는 후에 설명 드릴 template 디렉터리 밑에 위치한 Manifest Template 파일들과 결합하여 실제 Kubernetes Manifest를 만들게 됩니다.
# Default values for wookiist.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
# 이하 생략 ...
replicaCount
는 Pod를 몇 개 띄울지 지정하는 필드입니다. Deployment의spec.replicas
에 대응하는 값입니다.image.repository
는spec.template.spec.containers.image
의 image tag를 제외한 앞 부분에 대응하는 값입니다.
Template 수정
Template 디렉터리에는 Kubernetes Manifest로 변환할 템플릿 파일들이 위치합니다. 이 파일들은 이 Chart를 통해 생성될 서비스의 전체 오브젝트에 해당합니다. 만약 ConfigMap을 생성해야 한다면, ConfigMap.yaml 을 생성해서 정의에 맞게끔 수정하여 넣어 두면 되는 식입니다. 또한 helm create
를 통해서 생성했을 때의 Deployment 템플릿에는 들어있지 않은 필드를 추가해야 하는 경우 기존에 정의된 값들과 비슷하게 정의하면 됩니다. volume
이나 env
등등이 이에 해당합니다. env
를 예로 들면 이렇습니다.
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value }}
{{- end }}
위 내용을 Deployment 파일에 추가해주면 됩니다. 물론, Deployment 파일의 형식은 지켜주셔야 합니다. env
필드는 spec.template.spec.containers.env
에 위치해야 합니다. 추가로 range
는 해당 값이 리스트 형태로 정의되어 있을 때, 해당 리스트를 순회하면서 하나씩 데이터를 넣어주게 됩니다. 일종의 for문이라고 생각하시면 됩니다.
여기서 정의한 .Values.env
에 대응할 수 있도록 values.yaml
파일에도 env
필드를 추가해주어야 합니다. 예를 들어, values.yaml
에 다음과 같이 정의해두었다면, helm으로 Kubernetes Manifest를 생성했을 때, env
필드가 채워져서 들어가게 됩니다.
env:
- name: "IP"
value: "192.168.1.1"
- name: "PORT"
value: "8080"
중요한 것은 Helm을 사용하게 되면, Kubernetes Manifest의 직접 수정 없이 모든 것을 변수의 형태로 외부에서 정의할 수 있다는 것입니다.
Chart 활용하기
지금까지 생성한 차트를 활용하면 helm template
을 이용해서 Kubernetes Manifest를 직접 생성해서 apply할 수도 있고, helm install
을 이용해서 helm으로 애플리케이션을 배포할 수 있습니다.
참고
마무리
이렇게 오늘은 아주 간단하게만 helm chart를 생성하는 방법을 알아보았습니다. 너무 간단하게만 소개드린 것 같아 조금은 조심스러운 마음입니다. 추후 글을 추가로 올려서 자세한 방법을 소개해드리겠습니다.
여기까지 따라오시느라 고생 많으셨습니다. 만약 이 글이 도움이 되셨다면 글 좌측 하단의 하트❤를 눌러주시면 감사하겠습니다.
혹시라도 글에 이상이 있거나, 이해가 가지 않으시는 부분, 또는 추가적으로 궁금하신 내용이 있다면 주저 마시고 댓글💬을 남겨주세요! 빠른 시간 안에 답변을 드리겠습니다 😊
'IT > Kubernetes' 카테고리의 다른 글
[Kubernetes] 깔끔하게 kubeadm reset 하기 (0) | 2021.06.22 |
---|---|
[Kubernetes] kubeadm을 이용해 Kubernetes 클러스터를 구축해보자 (8) | 2021.06.21 |
[Kubernetes] kubectx를 활용해서 멀티 클러스터를 관리하자 (2) | 2021.06.13 |
[Kubernetes] Kubernetes 인증서가 만료되었을 때 해결 방법 (4) | 2021.06.07 |
[Kubernetes] Helm으로 Statefulset의 spec upgrade가 안 되는 경우 (0) | 2021.05.12 |