helm을 배워보자 2일차 - Charts 기본

0

helm

목록 보기
2/8

Chart

https://helm.sh/ko/docs/topics/charts/

헬름은 charts라는 패키지 포맷을 사용한다. charts는 kubernetes resource와 관련된 set들을 설명하는 파일의 모음일 뿐이다.

charts는 특정한 디렉터리 구조를 가진 파일들로 생성되는데, 이 파일들은 배포할 버전이 지정된 아카이브로 패키지화 될 수 있다.

가령, helm pull chartrepo/chartname명령을 사용하면 .tgz파일로 charts 파일이 나오는 것을 알 수 있다.

chart 파일 구조

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

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.3nginx chart는 다음과 같이 이름이 지어진다.

nginx-1.2.3.tgz

apiVersion 필드

apiVersion 필드는 helm3인 경우 v2가 만들어진다. 이전 helm 버전의 chart는 apiVersionv1으로 되어있는데 helm3에 의해 설치가 가능하다.

v1에서 v2로 변경하는 방법은 다음과 같다.
1. 종속성을 정의하는 dependencies 필드는 v1 chart를 위해 독립된 requirements.yaml 파일로 위치시키기
2. type 필드는 어플리케이션과 라이브러리 차트를 식별

type는 chart 타입을 정의하는데 applicationlibrary 두 타입이 있다. Application은 기본 타입이며 온전하게 작동할 수 있는 표준 차트이다. library charts는 차트 빌더에 유틸리티나 함수를 제공한다. library chart는 설치가 불가능하고 어떤 리소스 오브젝트도 갖지 않는다는 점에서 application chart와 다르다.

appVersion 필드

application의 버전을 명시하는 방법이다. sementic버저닝을 지원하며 1.2.3과 같은 버전을 적으면 이를 토대로 chart의 이름을 만든다.

kubeVersion

kubernetes version에 대한 sementic version 제약 조건을 걸 수 있다.

and, or연산으로 버저닝을 다음과 같이 표현할 수 있다.

>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0

이외에도 와일드 카드와 물결로 버전을 표현할 수 있다.

chart dependency

helm chart에는 0개 이상의 다른 차트를 dependency로 가지고 있을 수 있다. 이들은 Chart.yamldependencies 필드를 사용하여 직접 연결되거나 charts/ 디렉터리로 가져와서 수동으로 관리할 수 있다.

만약 현재 charts에서 dependency로 apachemysql을 사용한다면 다음과 같이 쓸 수 있다.

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 값을 dependeciescondition이나 tags에 설정함으로서 실행할 수 있다.

가령, mychartvalues.yaml이 다음과 같다고 하자.

subchart1:
  enabled: true
tags:
  front-end: false
  back-end: true

subchart1.enabledtags.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-endfalse이지만 subchart1.enabledtrue이다. 때문에 subchart1은 실행되며, subchart2subchart2.enabled가 없지만 tags.back-endtrue여서 실행된다.

tag와 condition을 정리하면 다음과 같다.
1. values에 condition이 셋팅되어 있다면 tags의 내용보다 우선 순위를 갖는다.
2. tags는 어떤 tag라도 true라면 해당 dependency는 활성화된다.
3. tagcondition의 값은 최상단 부모의 values에 의해 셋팅되어야 한다.
4. valuestags의 key는 최상단 레벨의 key이여야 한다.

template와 값

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 }}

위의 예시를 보면 containersdeis-databaseimageimagePullPolicy, env.value 부분에 템플릿이 사용된 것을 볼 수 있다. 정리하면 다음과 같다.

  1. {{ .Values.imageRegistry }}: values.yaml 파일의 imageRegistry값을 사용하겠다.
  2. {{ .Values.dockerTag }}: values.yaml파일의 dockerTag값을 사용하겠다.
  3. {{ .Values.pullPolicy }}: values.yaml파일의 pullPolicy값을 사용하겠다.
  4. {{ default "minio" .Values.storage }}: values.yaml파일의 storage값을 사용하겠다. 단, 값이 없다면 default로 minio이다.

그럼 values.yaml은 다음과 같이 정의되어야 한다.

  • values.yaml
imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "s3"

해당 values.yaml파일은 helm install로 release 생성 시에 custom values 파일와 병합될 수 있다. 가령 customer가 myvalues.yaml이라는 파일을 만들고 이를 chart를 배포할 때 적용했다고 하자.

  • myvalues.yaml
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.yamlglobal 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속성을 셋팅하는 것 같은 일에 유용하다.

사용자 지정 리소스(CRDs - custom Resource Definitions)

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를 포함해야한다.

  • crds/crontab.yaml
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를 삭제하지 않는다.

charts를 관리하기위해 helm 사용하기

helm은 charts를 관리하기위한 몇 가지 유용한 툴을 제공한다.

mychart라는 chart를 만드는 방법은 다음과 같다.

helm create mychart

mychart라는 helm chart가 있다면 이를 package하는 방법은 다음과 같다.

helm package mychart

chart에 포맷팅이나 information에 대한 issue가 있는 지 없는 지 검사할 수 있는 방법을 제공해준다.

helm lint mychart

chart repositories

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를 업로드하는 방법에 대해서는 제공하지 않는다.

chart starter packs

helm create 명령어는 --starter라는 옵션을 받을 수 있는데 이는 "starter chart"를 지정할 수 있게 해준다.

starter는 regular chart들로 $XDG_DATA_HOME/helm/starters에 지정되어있어서 해당 경로에 chart를 만들어놓으면 starter로 등록할 수 있다.

0개의 댓글