Skip to content

필사 모드: Helm Chart 작성과 배포 자동화 완벽 가이드

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

1. Helm이란?

Helm은 Kubernetes의 패키지 매니저입니다. 복잡한 Kubernetes 리소스를 하나의 **Chart**로 패키징하여 설치, 업그레이드, 롤백을 간편하게 관리할 수 있습니다.

왜 Helm인가?

- 반복적인 YAML 작성 제거

- 환경별 설정 분리 (dev/staging/production)

- 버전 관리와 롤백

- 의존성 관리

2. Chart 디렉토리 구조

mychart/

├── Chart.yaml # Chart 메타데이터

├── Chart.lock # 의존성 잠금 파일

├── values.yaml # 기본 설정값

├── values-prod.yaml # 프로덕션 오버라이드

├── templates/ # Kubernetes 매니페스트 템플릿

│ ├── _helpers.tpl # 공통 헬퍼 함수

│ ├── deployment.yaml

│ ├── service.yaml

│ ├── ingress.yaml

│ ├── hpa.yaml

│ ├── configmap.yaml

│ ├── secret.yaml

│ ├── serviceaccount.yaml

│ ├── NOTES.txt # 설치 후 안내 메시지

│ └── tests/

│ └── test-connection.yaml

├── charts/ # 의존성 Chart

└── .helmignore # 패키징 제외 파일

Chart.yaml 작성

apiVersion: v2

name: my-web-app

description: A production-ready web application

type: application

version: 1.2.0 # Chart 버전 (SemVer)

appVersion: '3.1.0' # 앱 버전

maintainers:

- name: youngjukim

email: fjvbn2003@gmail.com

dependencies:

- name: postgresql

version: '12.x.x'

repository: 'https://charts.bitnami.com/bitnami'

condition: postgresql.enabled

- name: redis

version: '17.x.x'

repository: 'https://charts.bitnami.com/bitnami'

condition: redis.enabled

3. values.yaml 설계 패턴

values.yaml - 기본 설정

replicaCount: 2

image:

repository: myregistry.io/my-web-app

tag: '' # Chart appVersion 사용

pullPolicy: IfNotPresent

service:

type: ClusterIP

port: 80

targetPort: 8080

ingress:

enabled: true

className: nginx

annotations:

cert-manager.io/cluster-issuer: letsencrypt-prod

hosts:

- host: app.example.com

paths:

- path: /

pathType: Prefix

tls:

- secretName: app-tls

hosts:

- app.example.com

resources:

limits:

cpu: 500m

memory: 256Mi

requests:

cpu: 100m

memory: 128Mi

autoscaling:

enabled: false

minReplicas: 2

maxReplicas: 10

targetCPUUtilizationPercentage: 80

postgresql:

enabled: true

auth:

database: myapp

username: appuser

redis:

enabled: false

4. Templates 작성

\_helpers.tpl - 공통 헬퍼

{{- 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 "mychart.labels" -}}

helm.sh/chart: {{ include "mychart.chart" . }}

app.kubernetes.io/name: {{ include "mychart.name" . }}

app.kubernetes.io/instance: {{ .Release.Name }}

app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}

app.kubernetes.io/managed-by: {{ .Release.Service }}

{{- end }}

{{- define "mychart.selectorLabels" -}}

app.kubernetes.io/name: {{ include "mychart.name" . }}

app.kubernetes.io/instance: {{ .Release.Name }}

{{- end }}

deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: {{ include "mychart.fullname" . }}

labels:

{{- include "mychart.labels" . | nindent 4 }}

spec:

{{- if not .Values.autoscaling.enabled }}

replicas: {{ .Values.replicaCount }}

{{- end }}

selector:

matchLabels:

{{- include "mychart.selectorLabels" . | nindent 6 }}

template:

metadata:

annotations:

checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}

labels:

{{- include "mychart.selectorLabels" . | nindent 8 }}

spec:

containers:

- name: {{ .Chart.Name }}

image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"

imagePullPolicy: {{ .Values.image.pullPolicy }}

ports:

- name: http

containerPort: {{ .Values.service.targetPort }}

protocol: TCP

livenessProbe:

httpGet:

path: /healthz

port: http

initialDelaySeconds: 15

readinessProbe:

httpGet:

path: /ready

port: http

initialDelaySeconds: 5

resources:

{{- toYaml .Values.resources | nindent 12 }}

envFrom:

- configMapRef:

name: {{ include "mychart.fullname" . }}-config

5. Helm Hooks

Hook을 사용하면 릴리스 라이프사이클의 특정 시점에 작업을 실행할 수 있습니다:

templates/pre-install-job.yaml

apiVersion: batch/v1

kind: Job

metadata:

name: {{ include "mychart.fullname" . }}-db-migrate

annotations:

"helm.sh/hook": pre-install,pre-upgrade

"helm.sh/hook-weight": "-5"

"helm.sh/hook-delete-policy": before-hook-creation

spec:

template:

spec:

restartPolicy: Never

containers:

- name: migrate

image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"

command: ["python", "manage.py", "migrate"]

envFrom:

- secretRef:

name: {{ include "mychart.fullname" . }}-db-secret

backoffLimit: 3

Hook 종류

| Hook | 실행 시점 |

| ------------ | ----------------- |

| pre-install | 설치 전 |

| post-install | 설치 후 |

| pre-upgrade | 업그레이드 전 |

| post-upgrade | 업그레이드 후 |

| pre-rollback | 롤백 전 |

| pre-delete | 삭제 전 |

| test | helm test 실행 시 |

6. CI/CD 파이프라인 연동

GitHub Actions + Helm

.github/workflows/deploy.yml

name: Deploy Helm Chart

on:

push:

branches: [main]

jobs:

deploy:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

- name: Configure AWS credentials

uses: aws-actions/configure-aws-credentials@v4

with:

role-to-assume: ${{ secrets.AWS_ROLE_ARN }}

aws-region: ap-northeast-2

- name: Update kubeconfig

run: aws eks update-kubeconfig --name my-cluster

- name: Install Helm

uses: azure/setup-helm@v3

with:

version: v3.14.0

- name: Helm lint

run: helm lint ./charts/my-web-app

- name: Helm upgrade

run: |

helm upgrade --install my-app ./charts/my-web-app \

--namespace production \

--create-namespace \

-f ./charts/my-web-app/values-prod.yaml \

--set image.tag=${{ github.sha }} \

--wait --timeout 5m

helm template로 로컬 검증

렌더링된 매니페스트 확인

helm template my-release ./mychart -f values-prod.yaml

특정 값 오버라이드

helm template my-release ./mychart --set replicaCount=3

kubeval로 유효성 검증

helm template my-release ./mychart | kubeval --strict

7. Chart 테스트

templates/tests/test-connection.yaml

apiVersion: v1

kind: Pod

metadata:

name: "{{ include "mychart.fullname" . }}-test"

annotations:

"helm.sh/hook": test

spec:

containers:

- name: curl

image: curlimages/curl:8.5.0

command: ['curl']

args: ['{{ include "mychart.fullname" . }}:{{ .Values.service.port }}/healthz']

restartPolicy: Never

테스트 실행

helm test my-release -n production

8. 퀴즈

- **version**: Chart 자체의 버전입니다. Chart 구조, 템플릿, values가 변경될 때 올립니다. SemVer를 따릅니다.

- **appVersion**: Chart가 배포하는 애플리케이션의 버전입니다. 앱 코드가 변경될 때 올립니다.

예: Chart version 1.2.0이 appVersion 3.1.0을 배포할 수 있습니다.

**hook-weight**는 같은 타입의 hook이 여러 개 있을 때 실행 순서를 결정합니다. 낮은 숫자가 먼저 실행됩니다.

예: weight -5인 DB 마이그레이션이 weight 0인 캐시 초기화보다 먼저 실행됩니다.

ConfigMap이 변경되면 sha256sum이 바뀌어 Pod의 annotation이 달라집니다. 이로 인해 Deployment가 rolling update를 트리거합니다.

ConfigMap만 변경하면 기본적으로 Pod가 재시작되지 않는 문제를 해결하는 패턴입니다.

현재 단락 (1/237)

Helm은 Kubernetes의 패키지 매니저입니다. 복잡한 Kubernetes 리소스를 하나의 **Chart**로 패키징하여 설치, 업그레이드, 롤백을 간편하게 관리할 수 있습니...

작성 글자: 0원문 글자: 5,852작성 단락: 0/237