https://helm.sh/ko/docs/topics/charts/
헬름은 charts
라는 패키지 포맷을 사용한다. charts
는 kubernetes resource와 관련된 set들을 설명하는 파일의 모음일 뿐이다.
charts
는 특정한 디렉터리 구조를 가진 파일들로 생성되는데, 이 파일들은 배포할 버전이 지정된 아카이브로 패키지화 될 수 있다.
가령, helm pull chartrepo/chartname
명령을 사용하면 .tgz
파일로 charts 파일이 나오는 것을 알 수 있다.
charts
는 디렉터리 안에 파일들의 모음으로 구성된다. 디렉터리는 버전명이 없고, 차트명만 가진다.
charts
를 만드는 방법은 다음과 같다.
helm create mychart
mychart
라는 charts가 만들어졌고 내부는 다음과 같다.
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
이는 기본적으로 제공되는 디렉터리 구조인데, 좀 더 일반적으로 사용되는 디렉터리 구조는 다음과 같다.
mychart/
Chart.yaml # 차트에 대한 정보를 가진 YAML 파일
LICENSE # 옵션: 차트의 라이센스 정보를 가진 텍스트 파일
README.md # 옵션: README 파일
values.yaml # 차트에 대한 기본 환경설정 값들
values.schema.json # 옵션: values.yaml 파일의 구조를 제약하는 JSON 파일
charts/ # 이 차트에 종속된 차트들을 포함하는 디렉터리
crds/ # 커스텀 자원에 대한 정의
templates/ # values와 결합될 때, 유효한 쿠버네티스 manifest 파일들이 생성될 템플릿들의 디렉터리
templates/NOTES.txt # 옵션: 간단한 사용법을 포함하는 텍스트 파일
헬름은 charts/
와 crds/
, templates/
디렉터리와 나열된 파일들을 사용한다.
Chart.yaml
파일은 차트 파일의 필수요소이다. 다음과 같은 필드를 가진다.
apiVersion: 차트 API 버전 (필수)
name: 차트명 (필수)
version: SemVer 2 버전 (필수)
kubeVersion: 호환되는 쿠버네티스 버전의 SemVer 범위 (선택)
description: 이 프로젝트에 대한 간략한 설명 (선택)
type: 차트 타입 (선택)
keywords:
- 이 프로젝트에 대한 키워드 리스트 (선택)
home: 프로젝트 홈페이지의 URL (선택)
sources:
- 이 프로젝트의 소스코드 URL 리스트 (선택)
dependencies: # 차트 필요조건들의 리스트 (optional)
- name: 차트명 (nginx)
version: 차트의 버전 ("1.2.3")
repository: 저장소 URL ("https://example.com/charts") 또는 ("@repo-name")
condition: (선택) 차트들의 활성/비활성을 결정하는 boolean 값을 만드는 yaml 경로 (예시: subchart1.enabled)
tags: # (선택)
- 활성화 / 비활성을 함께하기 위해 차트들을 그룹화 할 수 있는 태그들
enabled: (선택) 차트가 로드될수 있는지 결정하는 boolean
import-values: # (선택)
- ImportValues 는 가져올 상위 키에 대한 소스 값의 맵핑을 보유한다. 각 항목은 문자열이거나 하위 / 상위 하위 목록 항목 쌍일 수 있다.
alias: (선택) 차트에 대한 별명으로 사용된다. 같은 차트를 여러번 추가해야할때 유용하다.
maintainers: # (선택)
- name: maintainer들의 이름 (각 maintainer마다 필수)
email: maintainer들의 email (각 maintainer마다 선택)
url: maintainer에 대한 URL (각 maintainer마다 선택)
icon: 아이콘으로 사용될 SVG나 PNG 이미지 URL (선택)
appVersion: 이 앱의 버전 (선택). SemVer인 필요는 없다.
deprecated: 차트의 deprecated 여부 (선택, boolean)
annotations:
example: 키로 매핑된 주석들의 리스트 (선택).
모든 chart들은 버전 번호를 가져야하며 이는 sementic versioning을 준수한다. helm 2이상부터는 버전 번호를 release마커로 사용한다. 저장소에 있는 패키지들은 이름과 버전으로 구분된다.
가령 version: 1.2.3
인 nginx
chart는 다음과 같이 이름이 지어진다.
nginx-1.2.3.tgz
apiVersion
필드는 helm3인 경우 v2가 만들어진다. 이전 helm 버전의 chart는 apiVersion
이 v1
으로 되어있는데 helm3에 의해 설치가 가능하다.
v1
에서 v2
로 변경하는 방법은 다음과 같다.
1. 종속성을 정의하는 dependencies
필드는 v1
chart를 위해 독립된 requirements.yaml
파일로 위치시키기
2. type
필드는 어플리케이션과 라이브러리 차트를 식별
type
는 chart 타입을 정의하는데 application
과 library
두 타입이 있다. Application
은 기본 타입이며 온전하게 작동할 수 있는 표준 차트이다. library charts
는 차트 빌더에 유틸리티나 함수를 제공한다. library chart는 설치가 불가능하고 어떤 리소스 오브젝트도 갖지 않는다는 점에서 application chart와 다르다.
application의 버전을 명시하는 방법이다. sementic버저닝을 지원하며 1.2.3
과 같은 버전을 적으면 이를 토대로 chart의 이름을 만든다.
kubernetes version에 대한 sementic version 제약 조건을 걸 수 있다.
and, or연산으로 버저닝을 다음과 같이 표현할 수 있다.
>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0
이외에도 와일드 카드와 물결로 버전을 표현할 수 있다.
helm chart에는 0개 이상의 다른 차트를 dependency로 가지고 있을 수 있다. 이들은 Chart.yaml
에 dependencies
필드를 사용하여 직접 연결되거나 charts/
디렉터리로 가져와서 수동으로 관리할 수 있다.
만약 현재 charts에서 dependency로 apache
와 mysql
을 사용한다면 다음과 같이 쓸 수 있다.
dependencies:
- name: apache
version: 1.2.3
repository: https://example.com/charts
- name: mysql
version: 3.2.1
repository: https://another.example.com/charts
repository
필드는 chart repo의 완전한 URL로 반드시 로컬환경에서 helm repo add
를 사용해서 추가되어야 한다.
URL대신 저장소의 이름을 사용할 수 있다.
helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com
다음과 같이 fantastic-charts
라는 repo를 추가하였다면, repository
에 repo이름으로 적을 수 있다.
dependencies:
- name: awesomeness
version: 1.0.0
repository: "@fantastic-charts"
종속성을 정의하면 helm dependency update
를 실행하여 종속성 파일을 charts/
디렉터리 안에 다운로드 받을 수 있다.
helm dep up foochart
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "local" chart repository
...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "example" chart repository
...Successfully got an update from the "another" chart repository
Update Complete. Happy Helming!
Saving 2 charts
Downloading apache from repo https://example.com/charts
Downloading mysql from repo https://another.example.com/charts
helm dependency update <chart-directory>
가 chart를 가져올 때, chart를 아카이브 형태로 charts/
디렉터리에 저장한다. 위의 경우 다음과 같이 저장된다.
charts/
apache-1.2.3.tgz
mysql-3.2.1.tgz
dependency에 alias
를 붙여서 같은 chart라고 다른 이름의 여러 chart를 만들 수 있다.
...
dependencies:
- name: subchart
repository: http://localhost:10191
version: 0.1.0
alias: new-subchart-1
- name: subchart
repository: http://localhost:10191
version: 0.1.0
alias: new-subchart-2
- name: subchart
repository: http://localhost:10191
version: 0.1.0
helm dependency update <chart-directory>
를 실행하면 다음과 같이 pkg가 나오게 된다.
subchart
new-subchart-1
new-subchart-2
dependency들은 조건에 따라 배포를 할지 안할 지를 결정할 수 있는데, 이는 values.yaml
에 있는 configuration 값을 dependecies
의 condition
이나 tags
에 설정함으로서 실행할 수 있다.
가령, mychart
의 values.yaml
이 다음과 같다고 하자.
subchart1:
enabled: true
tags:
front-end: false
back-end: true
subchart1.enabled
와 tags.front-end
, tags.back-end
를 이용하여 dependency를 배포할 지 안할 지 결정할 수 있다.
...
dependencies:
- name: subchart1
repository: http://localhost:10191
version: 0.1.0
condition: subchart1.enabled, global.subchart1.enabled
tags:
- front-end
- subchart1
- name: subchart2
repository: http://localhost:10191
version: 0.1.0
condition: subchart2.enabled,global.subchart2.enabled
tags:
- back-end
- subchart2
위 예에서 tags.front-end
는 false
이지만 subchart1.enabled
는 true
이다. 때문에 subchart1
은 실행되며, subchart2
는 subchart2.enabled
가 없지만 tags.back-end
가 true
여서 실행된다.
tag와 condition을 정리하면 다음과 같다.
1. values
에 condition이 셋팅되어 있다면 tags
의 내용보다 우선 순위를 갖는다.
2. tags
는 어떤 tag
라도 true
라면 해당 dependency는 활성화된다.
3. tag
와 condition
의 값은 최상단 부모의 values
에 의해 셋팅되어야 한다.
4. values
의 tags
의 key는 최상단 레벨의 key이여야 한다.
helm chart에는 template를 적용하여 동적으로 값을 설정할 수 있는데 이는 sprig라는 라이브러리를 사용하여 50개 정도의 addon template 함수와 몇 가지 특수 함수가 추가된 go template language로 작성되었다.
https://github.com/Masterminds/sprig
모든 template 파일은 chart
directory의 templates
디렉터리 안에 저장된다. helm이 차트를 렌더링할 때 템플릿 엔진을 통해 이 디렉터리 안에 모든 파일을 전달한다.
템플릿에 대한 values
는 2가지 방법으로 제공된다.
1. chart개발자는 chart의 안에 values.yaml
이라 부르는 파일을 제공할 수 있다.
2. chart사용자는 값을 포함한 YAML 파일을 제공할 수 있으며 helm install
커맨드 라인으로 제공받을 수 있다.
사용자가 커스텀 값을 사용한다면 chart의 values.yaml
파일에 있는 값을 덮어쓴다.
template 파일은 go template 작성에 대한 규약을 따른다.
https://pkg.go.dev/text/template
다음의 template가 적용된 Chart.yaml
파일을 보도록하자
apiVersion: v1
kind: ReplicationController
metadata:
name: deis-database
namespace: deis
labels:
app.kubernetes.io/managed-by: deis
spec:
replicas: 1
selector:
app.kubernetes.io/name: deis-database
template:
metadata:
labels:
app.kubernetes.io/name: deis-database
spec:
serviceAccount: deis-database
containers:
- name: deis-database
image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }}
imagePullPolicy: {{ .Values.pullPolicy }}
ports:
- containerPort: 5432
env:
- name: DATABASE_STORAGE
value: {{ default "minio" .Values.storage }}
위의 예시를 보면 containers
로 deis-database
의 image
와 imagePullPolicy
, env.value
부분에 템플릿이 사용된 것을 볼 수 있다. 정리하면 다음과 같다.
values.yaml
파일의 imageRegistry
값을 사용하겠다.values.yaml
파일의 dockerTag
값을 사용하겠다.values.yaml
파일의 pullPolicy
값을 사용하겠다.values.yaml
파일의 storage
값을 사용하겠다. 단, 값이 없다면 default로 minio
이다.그럼 values.yaml
은 다음과 같이 정의되어야 한다.
imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "s3"
해당 values.yaml
파일은 helm install
로 release 생성 시에 custom values 파일와 병합될 수 있다. 가령 customer가 myvalues.yaml
이라는 파일을 만들고 이를 chart를 배포할 때 적용했다고 하자.
storage: "gcs"
다음의 명령어로 helm install
시에 myvalues.yaml
파일을 적용할 수 있다.
helm install --generate-name --values=myvalues.yaml <repo/chart>
기본 values.yaml
과 custome value인 myvalues.yaml
파일이 병합된 결과는 다음과 같다.
imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "gcs"
병합된 것이지, 덮어쓴 것은 아니다. 즉, 다른 필드들의 값도 침범하진 않는다는 것이다.
참고로, 어떤 template라도 안에서 .Values
오브젝트를 사용하여 접근이 가능하다.
values
파일은 최상위 chart에 대한 값과 chart의 charts/
디렉터리에 포함된 차트 중 어떤 것이라도 정의할 수 있다. 즉 values.yaml
에 dependency에서 사용하는 값들을 정의할 수 있다는 것이다.
chart의 dependency가 mysql
, apache
라면 다음과 같이 설정할 수 있다.
title: "My WordPress Site" # sent to the wordpress template
mysql:
max_connection: 100 # sent to mysql
password: "secret"
apache:
port: 8080 # passed to apache
이제 template에서 .Values.mysql.password
로 dependency의 value에 접근이 가능하다. 다만, dependency에서는 부모인 chart의 values에 접근할 수 없다는 것을 명심하자.
이를 가능하게 해주는 것이 바로 values.yaml
의 global
key이다.
title: "My WordPress Site" # Sent to the WordPress template
global:
app: MyWordPress
mysql:
max_connections: 100 # Sent to MySQL
password: "secret"
apache:
port: 8080 # Passed to Apache
모든 chart에서 .Values.global.app
을 접근할 수 있다.
이제 mysql
템플릿은 app
을 {{ .Values.global.app }}
로 접근할 수 있다. apache
에서도 마찬가지이다.
global
key로 설정하여 label
과 같은 metadata
속성을 셋팅하는 것 같은 일에 유용하다.
kubernetes는 새로운 kubernetes object의 새로운 타입을 정의하는 것에 대한 매커니즘을 제공한다. 사용자 지정 정의(CRDs)를 사용해서 쿠버네티스 개발자는 커스텀 리소스 타입을 정의할 수 있다.
helm3에서 CRDs는 특별한 객체 종류로 다뤄진다. CRDs는 chart의 나머지보다 먼저 설치되고 몇몇 제한이 적용된다.
CRD yaml파일은 chart안의 crds/
디렉터리에 위치해야한다. 다수의 CRDs
는 같은 파일에 위치할 수 있다. helm은 CRD 디렉터리의 모든 파일을 kubernetes로 load하려고 시도한다.
CRD
파일은 template화 될 수 없다. 순수 YAML 문서여야 한다. helm이 새로운 chart를 설치할 때 CRDs를 업로드하고 API 서버에 의해 이용해지도록 CRD가 만들때까지 정지되며, 그 이후 템플릿 엔진이 시작되어 나머지 chart를 렌더링하고 kubernetes가 업로드하기 때문이다. 순서 때문에 CRD 정보는 helm teamplte의 Capabilites
object에서 이용 가능하고, helm template은 CRDs
에서 정의된 object의 새로운 인스턴스를 만들어낼 수 있다.
가령 charts에서 crds/
디렉터리에 CronTab
에 대한 CRD를 가진다면 templates/
디렉터리 안에 CronTab
종류의 인스턴스를 생성할 수 있다.
crontabs/
Chart.yaml
crds/
crontab.yaml
templates/
mycrontab.yaml
crontab.yaml
파일은 반드시 template명령없이 CRD를 포함해야한다.
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
CRD에서의 제약사항은 다음과 같다.
1. CRDs는 helm을 통해 절대 재설치 불가능하다. helm은 crds/
디렉터리에 CRDs
가 존재한다는 것을 알아낸다면 helm은 install이나 upgrade를 시도하지 않는다.
2. CRDs는 helm을 통해 절대 upgrade나 rollback이 불가능하다. helm은 오직 설치 작업시에만 CRDs를 생성한다.
3. CRDs는 helm에 의해 절대 삭제될 수 없다. CRD를 자동으로 지우는 것은 모든 클러스터 안의 네임스페이스에 영향을 주는 CRDs내용의 모든 것을 삭제한다. 따라서 helm은 CRDs를 삭제하지 않는다.
helm
은 charts를 관리하기위한 몇 가지 유용한 툴을 제공한다.
mychart
라는 chart를 만드는 방법은 다음과 같다.
helm create mychart
mychart
라는 helm chart가 있다면 이를 package하는 방법은 다음과 같다.
helm package mychart
chart에 포맷팅이나 information에 대한 issue가 있는 지 없는 지 검사할 수 있는 방법을 제공해준다.
helm lint mychart
chart repository는 HTTP server로 하나 또는 그 이상의 chart들을 가진다. helm
이 local chart directory들을 관리하는데 사용되는 반면에, chart는 공유하는 관점에서 가장 선호되는 방법이 바로 chart repository이다.
chart repository는 http server로 yaml file을 제공하고 tar file과 HTTP GET 요청에 대한 응답을 사용할 수 있다.
repository는 특별한 파일인 index.yaml
파일로 설정될 수 있다.
client 입장에서는 helm repo
명령어로 repository를 관리할 수 있지만, remote repository server에 charts를 업로드하는 방법에 대해서는 제공하지 않는다.
helm create
명령어는 --starter
라는 옵션을 받을 수 있는데 이는 "starter chart"를 지정할 수 있게 해준다.
starter는 regular chart들로 $XDG_DATA_HOME/helm/starters
에 지정되어있어서 해당 경로에 chart를 만들어놓으면 starter로 등록할 수 있다.