Helm Chart

Helm chart란?

Helm chart는 애플리케이션을 쿠버네티스 클러스터에 배포하는 데 필요한 모든 리소스를 포함하는 패키지이다. 패키지에는 배포, 서비스, 시크릿, 그리고 특정 애플리케이션의 상태를 정의하는 구성 맵의 다양한 YAML 설정 파일이 포함되어 있다.

Helm chart는 이러한 YAML 파일과 템플릿을 패키징한 것으로, 이를 통해 매개 변수화된 값에 따라 추가 설정 파일을 생성할 수 있다. 이러한 방식으로 다양한 환경에 맞게 설정 파일을 커스터마이징하거나 여러 배포에 재사용할 수 있는 설정 파일을 생성할 수 있다. 또한, 각 Helm chart를 개별적으로 버전 관리할 수 있기 때문에 서로 다른 설정의 여러 버전의 애플리케이션을 쉽게 관리할 수 있다.

Helm pagakage와 chart

Helm은 charts라는 packaging format을 사용한다. 패키지는 Helm chart를 패키지를 하는 것이고, 차트는 쿠버네티스의 리소스 yaml 파일을 템플릿으로 만들고, 메타 정보 파일 등을 압축하는 파일을 말한다.

  • 여기서 chart는 k8s resources를 describe하는 file들의 집합이다.
  • chart는 무언가를 배포하기 위해 사용된다.
    • ex) memcached pod, web app w/ HTTP servers, databases, etc.
  • chart는 특정 directory tree로 구성된 file들로 생성되어 있다.
    • 이 file들은 배포될 version의 archive로 packaging 될 수 있다.

chart 파일 생성 및 구조

chart 디렉터리 생성

helm 차트를 생성할 디렉터리를 만들고, helm create {directory} 명령어으로 기본 디렉터리를 생성한다.

% mkdir charts
% cd charts
% helm create app
Creating app

chart 파일 구조

생성된 기본 파일 구조는 아래와 같다.

% tree app
app
├── Chart.yaml                    # Chart에 대한 이름, 버전, 설명 등의 정보가 작성된 YAML 파일. (required)
├── charts                        # 이 Chart에 종속된 차트들을 포함하는 디렉터리. (optional)
├── templates                     # values와 결합될 때, 유효한 쿠버네티스 manifest 파일들이 생성될 템플릿 파일들의 디렉터리 (required)
│   ├── NOTES.txt                 # 간단한 사용법을 포함하는 텍스트 파일 (optional)
│   ├── _helpers.tpl              # template manifest 파일들에서 공유하는 변수 정의 (required)
│   ├── deployment.yaml           # *.yml 클러스터에 띄울 리소스 템플릿 파일들
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml                   # Chart에 템플릿에서 사용될 기본 환경 설정 변수들을 정의한 파일 (optional)

4 directories, 10 files

매니페스트 파일(manifest file)이란? 컴퓨팅에서 집합의 일부 또는 논리정연한 단위인 파일들의 그룹을 위한 메타데이터를 포함하는 파일이다.

Yaml 파일

chart.yaml

apiVersion: Helm Chart 자체의 API 버전 (required)
name: Chart 명 (required)
version: Chart 버전으로 SemVer(Semantic versioning)규칙을 준수해야 한다. (required)
         # (예:X.X.X 형식), SemVer 규칙 참조: https://semver.org/lang/ko/
kubeVersion: hart설치와 실행을 보장하는 최소 호환되는 쿠버네티스 버전의 SemVer 범위 (optional)
             # (예: ">=1.15.3")
description: Chart의 이 프로젝트에 대한 간략한 설명 (optional)
type: Chart 타입 (optional)
keywords:
  - Chart의 이 프로젝트에 대한 키워드 리스트 (optional)
    # Helm search 시 keyword도 같이 검색됨.
home: Chart 프로젝트 홈페이지의 URL (optional)
sources:
  - Chart의 이 프로젝트의 소스 코드 URL 리스트 (optional)
    # Chart repository 주소는 아님.
dependencies: # 차트 필요조건들의 리스트 (optional)
  - name: 차트명 (nginx)
    version: 차트의 버전 ("1.2.3")
    repository: 저장소 URL ("https://example.com/charts") 또는 ("@repo-name")
    condition: (optional) 차트들의 활성/비활성을 결정하는 boolean 값을 만드는 yaml 경로 (예시: subchart1.enabled)
    tags: # (optional)
      - 활성화 / 비활성을 함께하기 위해 차트들을 그룹화 할 수 있는 태그들
    enabled: (optional) 차트가 로드될수 있는지 결정하는 boolean
    import-values: # (optional)
      - ImportValues 는 가져올 상위 키에 대한 소스 값의 맵핑을 보유한다. 각 항목은 문자열이거나 하위 / 상위 하위 목록 항목 쌍일 수 있다.
    alias: (optional) 차트에 대한 별명으로 사용된다. 같은 차트를 여러번 추가해야할때 유용하다.
maintainers: # (optional)
  - name: 저작자(maintainer)의 이름 (각 maintainer마다 required)
    email: 저작자(maintainer)의 email (각 maintainer마다 optional)
    url: 저작자(maintainer)에 대한 URL (각 maintainer마다 optional)
icon: 아이콘으로 사용될 SVG나 PNG 이미지 URL이며, 카탈로그에서 차트 표시시 사용됨. (optional)
appVersion: Chart를 이용해 서비스되는 앱의 버전 (optional)
            # Chart를 이용해 서비스되는 앱의 버전이며 SemVer형식을 따르지 않아도 됨.
deprecated: 차트의 deprecated된 차트인지 여부를 boolean(true/false)로 명시 (optional)
annotations:
  example: 키로 매핑된 주석들의 리스트 (optional).

values.yaml

template에서 사용은 {{ .Values.image.tag }}와 같은 형태로 사용한다. 이는 들여 쓰기(indentation) 유의하여 작성해야 한다.

templates 폴더에 배포할 resource 정의

기본적으로 deployment, service, serviceaccount,ingress 가 존재한다.

필요에 따라 persistentvolume, configmap 등을 정의

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.name  }}
  labels:
    app: {{ .Values.name  }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      name: {{ .Values.name }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        name: {{ .Values.name  }}
    spec:
      containers:
    - name: {{ .Chart.Name }}
      image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
      imagePullPolicy: {{ .Values.image.pullPolicy }}
      ports:
        - name: http
          containerPort: {{ .Values.container.port  }}
          protocol: TCP
      envFrom:
        - configMapRef:
            name: {{ .Values.config.name  }}
      volumeMounts:
        - mountPath: {{ .Values.container.mountpath  }}
          name: {{ .Values.container.volumename }}

  volumes:
    - name: {{ .Values.container.volumename }}
      persistentVolumeClaim:
        claimName: {{ .Values.PVC.name }}

helm의 template 문법

템플릿 파일은 Go 템플릿 작성에 대한 표준 규약을 따른다.(텍스트/템플릿 Go 패키지 문서)

{{ }}로 변수를 사용한다.

  • .Values
    • values.yaml 파일에서 정의된 변수
  • .Charts
    • Charts.yaml 파일에서 정의 된 변수
    • Chart의 버전은 Chart.Version으로, 메인테이너는 Chart.Maintainers로 받아올 수 있다.
  • .Release
    • 배포할 때에 할당한 정보들을 사용
      • 예를 들면, --namespeace test로 install 할시에 .Release.Namespace에 test로 할당된다.
    • Release.Name: 릴리즈의 이름(Chart 이름 아님)
    • Release.Namespace: Chart가 릴리즈된 네임스페이스
    • Release.Service: 릴리즈를 수행하는 서비스
    • Release.IsUpgrade: 현재 업그레이드나 롤백중이면 true로 설정된다.
    • Release.IsInstall: 현재 설치중이면 true로 설정된다.
  • include...
    • _helpers.tpl 파일에서 정의된 변수
  • with ~ end
    • 변수에 대한 scope을 정하는 문법으로 해당 구간은 . 가 설정한 변수에 속함을 정의
    • (예: 아래 코드를 보면 .drink 는 .Values.favorite.drink를 의미한다.)
      {{- with .Values.favorite }}
        drink: {{ .drink | default "tea" | quote }}
        food: {{ .food | upper | quote }}
      {{- end }}
      
  • toYaml
    • 해당 변수를 yaml형식으로 변경
  • quote
    • string 타입으로 변경

Chart 검사하기

정의한 chart가 문법적으로 이상이 없는지 확인할 수 있다.

helm lint {Chart.yaml 위치}

이는 단지 문법적 오류만 점검할 뿐 문제없이 설치된다는 의미가 아니다.

templates을 기반으로 변수들 참조하여 리소스 배포시 결과 미리보기를 할 수 있다.

helm template {Chart.yaml 위치}

해당 과정을 통해 배포하고자하는 형태가 맞나 확인 가능하다.

chart를 시험 설치하여 오류 확인할 수 있다.

helm install {release name} {Chart.yaml 위치}  --debug --dry-run
  • --dry-run: 실제 클러스터에 설치 하지 않고 chart를 시험 설치하는 옵션
  • --debug: 배포를 위한 manifest 파일 내용을 보여준다.

chart 생성하고 repo에 등록하기

helm repository는 차트 저장소의 각 차트의 대한 정보를 담고 있는 index.yaml 파일이 있어야 한다.

index.yaml이 존재하는 폴더에서 아래와 같은 명령어를 통해 패키징하여 chart 생성한다.

helm package {Chart.yaml 위치

Chart.yaml에 정의한 {name}-{version}.tgz로 압축 파일이 생성한다.

저장소에 등록하지 않고 생성한 압축파일로 로컬에서 사용할거라면 helm install {name}으로 가능하다

chart를 생성하였으니 차트정보를 담고있는 index파일 업데이트

helm repo index {index.yaml 경로}

GitHub repository인 경우 git push를 진행한 후,

helm repo update

chart 목록을 repository에서 다시 가져와 업데이트를 진행한다.

업데이트되었는지 검색하여 확인을 진행한다.

helm search repo {차트명}

검색 단어는 키워드 정도로 해당단어가 포함돠는 차트와 차트의 repository 목록이 출력된다.

생성한 Chart를 이용해 설치하기

생성한 차트를 아래 명령어로 설치한다.

helm install {배포할 이름} {레포지토리명/chart명} -n {네임스페이스}

참고




최종 수정 : 2024-03-09