Container Orchestration/Kubernetes

Helm Chart 작성방법

Somaz 2023. 5. 18. 20:46
728x90
반응형

Overview

지난시간에는 Helm이 무엇인지에 대해 공부해보았다.

2023.05.16 - [Container Orchestration/Kubernetes] - Helm 이란? (Kubernetes Package manager)

 

이번시간에는 Helm Chart 작성 방법에 대해서 공부해보려고 한다.

 

https://insight.infograb.net/blog/2022/03/14/gitlab-helm-package-registry/

 

 


Helm Chart 작성방법

 

Helm CLI가 설치되어 있으면, helm create 명령을 실행하여 새로운 차트를 생성할 수 있다.

 

다음은 Helm Chart의 기본 구조이다.

$ helm create somaz
Creating somaz

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

3 directories, 10 files

 

bash_completion 등록을 해본다. 리눅스 기준으로 작성한다.

 

공식사이트에 설명이 되어있다.

$ vi ~/.bashrc
# 맨 마지막에
sudo bash -c 'helm completion bash > /etc/bash_completion.d/helm'

 

Helm Chart Install 

-f 옵션을 주고 overide.values.yaml을 사용하여 Install 할 수 있다.

helm install -f <오버라이딩 파일경로> <Release 이름> <차트경로>

ex)
helm install -f myvalues.yaml myredis ./redis

 

helm install(또는 upgrade)할 때 --set을 사용하면 values.yaml 필드를 오버라이딩 할 수 있다.

helm install --set <오버라이딩 필드>=<값> <Release 이름> <차트경로>

ex)
helm install --set image=redis:latest myredis ./redis
  • 위와 같이 작성하면 image 필드가 redis:latest로 변경이 된다.
image: redis:stable -> image: redis:latest

 


Helm Chart 문법

 

먼저 Helm Chart의 주요 구성요소에 대해서 확인해보겠다.

 

helm 설치 후 helm create 명령어를 사용해 Sample Chart를 생성할 수 있다.

$ helm create somaz

$ cd somaz

$ ls
Chart.yaml  charts  templates  values.yaml

$ ls templates/
NOTES.txt  _helpers.tpl  deployment.yaml  hpa.yaml  ingress.yaml  service.yaml  serviceaccount.yaml  tests

 

Chart.yaml

차트 자체에 대한 메타데이터가 포함된 기본 파일이다. name, version, description, home, keywords, sources, 등과 같은 필드가 포함된다. dependencies는 package.json(Node.js에서) 또는 pom.xml(Maven에서)과 약간 비슷하다고 볼 수 있다.

 

values.yaml

차트의 기본 구성 값을 작성한다. 다양한 환경에 대해 다양한 값으로 템플릿을 매개변수화할 수 있는 곳이다.

해당 파일의 작성한 값들을 기준으로 template의 yaml 파일로 오버라이딩 된다.

 

templates

값과 결합될 때 유효한 Kubernetes 매니페스트 파일을 생성하는 템플릿의 디렉터리이다. 템플릿은 Go 템플릿 언어를 사용한다. 

 


 

아래는 templates의 deployment.yaml 예시이다.

$ cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "somaz.fullname" . }}
  labels:
    {{- include "somaz.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "somaz.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "somaz.selectorLabels" . | nindent 8 }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "somaz.serviceAccountName" . }}
      securityContext:
        {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.service.port }}
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}

 

간단히 문법에 대해서 설명해보자면,

조건절은 {{- if }} 혹은 {{- if not }} {{ end }} 로 사용할 수 있고

{{- with 키 }} {{ end }} 는 with 절 안에서는 구조상 해당 키 아래의 값들을 사용하겠다는 의미이다.

{{- toYaml 키 }} 는 키의 값을 그대로 Yaml 로 프린트해준다.

이제 간단히 실습을 진행해본다.

 

아래는 values.yaml 파일 예시이다.

$ cat values.yaml
# Default values for somaz.
# 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: "latest"

imagePullSecrets: []
nameOverride: ""
fullnameOverride: "somaz-nginx"

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

ingress:
  enabled: false
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

namespace: somaz
  • default로 주어지는 sample values.yaml 파일이다.
  • 수정한 부분은 image tag와 밑에 namespace : somaz만 추가해 주었다.

 

이제 간단하게 --dry-run과 --debug 명령어를 사용해 helm chart 설치 결과가 어떻게 나오는지 확인해본다.

$ helm install -f values.yaml somaz-nginx . --dry-run --debug
install.go:200: [debug] Original chart version: ""
install.go:217: [debug] CHART PATH: /home/somaz/somaz
...
HOOKS:
---
# Source: somaz/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "somaz-nginx-test-connection"
  labels:
    helm.sh/chart: somaz-0.1.0
    app.kubernetes.io/name: somaz
    app.kubernetes.io/instance: somaz-nginx
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['somaz-nginx:80']
  restartPolicy: Never
MANIFEST:
---
# Source: somaz/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: somaz-nginx
  labels:
    helm.sh/chart: somaz-0.1.0
    app.kubernetes.io/name: somaz
    app.kubernetes.io/instance: somaz-nginx
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
---
# Source: somaz/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: somaz-nginx
  labels:
    helm.sh/chart: somaz-0.1.0
    app.kubernetes.io/name: somaz
    app.kubernetes.io/instance: somaz-nginx
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: somaz
    app.kubernetes.io/instance: somaz-nginx
---
# Source: somaz/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: somaz-nginx
  labels:
    helm.sh/chart: somaz-0.1.0
    app.kubernetes.io/name: somaz
    app.kubernetes.io/instance: somaz-nginx
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: somaz
      app.kubernetes.io/instance: somaz-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: somaz
        app.kubernetes.io/instance: somaz-nginx
    spec:
      serviceAccountName: somaz-nginx
      securityContext:
        {}
      containers:
        - name: somaz
          securityContext:
            {}
          image: "nginx:latest"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}
...

 

확실하게 공부를 해보고 싶다면, 자신의 작성한 yaml 파일에 맞게 template을 조금씩 변경해준뒤 잘 적용되는지 해당 명령어로 확인해보면 된다!


Reference

https://insight.infograb.net/blog/2022/03/14/gitlab-helm-package-registry/

 

https://helm.sh/

 

https://devocean.sk.com/blog/techBoardDetail.do?ID=163262 

 

728x90
반응형