[Helm] Why helm?

김지환·2023년 1월 18일
0

Helm

목록 보기
1/1

Helm 을 쓰는 이유?

다양한 App에 따른 yaml 파일이 존재하고 각각의 배포환경에 따라서 더 많은 yaml 이 존재하기 때문에 이를 보다 효과적으로 관리하기 위해 사용함.

Helm 폴더 구조

helm 을 설치하고 helm create {chartname} 를 하면

├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

4 directories, 10 files

위와 같은 default 폴더 구조가 나온다.

Chart.yaml

chart.yaml 은 해당 chart 의 이름 버전정보 타입등을 기재한 명세서라고 할 수 있다.


apiVersion: v2
name: mychart
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 : required
차트의 api version 정보를 나타낸다

name : required

차트의 이름

description

차트에 대한 설명

type : optional

해당 chart 가 application 인지 Library 타입인지를 정의한다. application 이 흔히 배포할 수 있는 template을 가지고 있는 helm chart라고 볼 수 있고 library 는 단순 함수나 유틸리티 기능등을 제공하기 위해 만든 chart로 스스로 template 을 정의하고 있지 않기 때문에 배포가 불가능하다.

version : required

해당 chart 의 버전

appVersion : optional

차트가 배포하는 app의 버전.

values.yaml

helm 에서 사용할 수 있는 property 들을 정의해 놓는 곳.

values.yaml 에 정의된 파일들은 다음과 같이 가져와서 사용할 수 있다.

In value.yaml

foo:
  name: test
  description: test description
  val: 
   - a
   - b
   - c

values.yaml 에는 위와 같이 indent를 이용해서 각 value 들의 scope 를 만들 수 있다.

In some templates file

foo: {{- .Values.foo.name }} -> foo: test
description : {{ .Values.foo.description | quote }} -> description: "test description"
val: {{- .Values.foo.val | toYaml nindent4 }}
-> 
val: 
    - a
    - b
    - c

.Values 를 통해서 values.yaml 에 접근하고 dot 을 이용해서 내부 field 들에 접근할 수 있다.

charts

또 다른 chart 들을 가지고 있을 수 있으며 해당 차트들에 정의된 function, utility 등을 main chart 에서 사용할 수 있다.

이 때 charts 폴더 안에 있는 chart 들이 Library 타입으로 정의될 수 있다. ( application으로 사용할 수도 있음 )

charts.yaml 파일에 dependencies field 에 정의될 수 있다.

dependencies:
- name: common
  repository: https://charts.bitnami.com/bitnami
  tags:
  - bitnami-common
  version: 2.x.x

위와 같이 정의가 돼있기 때문에 bitnami repo를 받을 때 bitnami-common chart도 같이 하위에 받아지게 된다.

templates

templates 폴더에 우리가 실질적으로 사용할 resource 들을 정의하게 된다.
templates 폴더에 파일을 작성할 때 몇가지 규칙이 있다.

  1. .yaml 확장자를 이용할 것 ( .tpl 타입도 허용 )
  2. file 들은 대쉬 notation을 사용 camelcase 는 사용할 수 없다.
  3. 각 resource 각각 자신의 파일에 정의가 되야함
  4. file name 에서 resource 의 타입을 알 수 있도록 작성 e.g.) foo-pod.yaml, foo-pv.yaml

위의 규칙을 따르면서 template file 을 작성해주어야한다.

templates 폴더에는 .tpl 확장자를 사용하는 _helpers.tpl 파일이 존재한다.
template 작성을 할 때 도움이 되는 다양한 helpers들을 등록하고 이를 재사용할 수 있게 해준다.

해당 파일에 값을 정의하고 chart 내에서 사용을 하는 방식은 아래와 같다.

{{- define "mychart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "mychart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

위와 같이 define, end 를 이용하여 값을 정의하고

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "mychart.fullname" . }}

include를 이용하여 값을 가져올 수 있다. include 뒤에 . 의 의미는 가져오는 객체의 scope를 정의하는 것이다. 따로 아무 표시를 안하게 되면 전체 scope를 모두 가져오게 되고 .Values, .Release 이런식으로 폭을 좁히면 해당 scope 에서만 값을 가져오게 된다.

Helm 주요 명령어

helm show

차트의 정보를 보고 싶을 때 사용할 수 있다.

sub command 로는

  • all : 모든 yaml 파일을 읽어준다.
  • chart : chart.yaml을 읽어준다.
  • crds : crds 폴더를 읽어준다. ( 사용자 정의 리소스 )
  • readme : readme 를 읽어준다.
  • values : values 파일을 읽어준다.
helm show all {path} -> helm show all .

helm repo

helm hub 에서 repository 와 커뮤니케이션할 때 사용된다.

sub command 로는

  • add : 차트 repository에 추가한다.
  • list: 차트 repository의 list를 보여준다.
  • remove: 차트 repository에서 지우기.
  • update: local chart 를 repository 차트로 업데이트

Artifact Hub 나 repo 에 등록되어 있는 chart를 볼 때 사용하는 명령어

helm search hub

helm search repo 

helm install

chart 를 최초 배포할 때 사용하는 명령어이다.

helm install [name] [chart] [flag]

-f 를 사용하여 custom value 파일을 주입시킬 수도 있다.

helm install mychart bitnami/tomcat -f custom-values.yaml

helm uninstall

배포되어 있는 앱을 내릴 때 사용한다.

helm uninstall name

helm upgrade

helm install을 진행하고 다시 재배포 하기 위해서는 install 명령어를 사용할 수 없다. install 을 사용하기 위해서는 uninstall을 하고 사용할 수가 있다.

따라서 재배포를 위해서는 upgrade 명령어를 사용하면 된다.

helm upgrade

helm template

templates 의 yaml 파일들에 실제로 적용될 값들을 주입하여서 그 결과값을 보여주는 명령어이다. 값을 테스트해볼 때 유용하게 사용할 수 있다.

helm template .

helm pull

repository에서 helm chart 를 local directory로 가져오고 싶을 때 사용할 수 있다.

helm pull [chart URL | repo/chartname] [...] [flags]

Helm Chart Tips

1. helm install, upgrade 분기처리의 불편함

helm install 을 사용할 때 이미 release 돼어 있다면 에러가 발생하게 된다. 이 때는 helm upgrade를 이용해서 재배포를 해줘야한다.

이를 위해 배포 로직을 짤 때 분기처리가 필요함.

이를 방지하기 위해서 다음의 명령어로 해결이 가능하다.

helm upgrade chart -n foo --install

upgrade 시도했다가 배포된 내용이 없을 시에 자체적으로 install 명령어를 실행해준다.

2. Pod 가 완전 가동이 됐음을 확인하고 싶을 때

helm upgrade chart -n foo --install --wait 

위 명령을 통해서 default 로 5분동안 pod 의 정상 running 상태를 수신하게 된다. timeout 시간은 --timeout 시간 ( e.g. 10m ) 옵션을 통해서 수정이 가능하다.

helm upgrade chart -n foo --install --wait --timeout 10m

2. configMap, secret update 를 하고 pod 재기동 기능

일반적으로 configMap, secret 등을 변경하고 반영을 하기 위해서는 pod 를 재배포 시켜주어야하는 작업을 추가로 해줘야한다.

하지만 아래와 같이 annotation을 추가해준다면 configMap 혹은 변경을 감지하고 싶은 파일이 변경 됐을 때 마다 그 값을 불러와 인코딩하여서 pod 에 annotation을 추가하기 때문에 pod에 변경사항이 생기게 되고 재배포가 자동으로 이루어지게 된다.

kind: Deployment
spec:
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

위와 유사한 방식으로 매 배포 마다 새로 pod 를 재배포 시키고 싶다면

kind: Deployment
spec:
  template:
    metadata:
      annotations:
        rollme: {{ randAlphaNum 5 | quote }}
[...]

랜덤 string 생성을 통해서 매번 재배포를 만들 수도 있다. 위와 같은 방식은 dev 환경에서 image 에 대한 tag 가 latest일 경우 변경사항을 일일이 적용하기 어려울 때 다음과 같은 방식을 사용할 수 있다.

profile
Developer

0개의 댓글