Di episode ini kita akan coba bahas Helm Charts untuk packaging dan deploying Kubernetes application. Kita akan mempelajari bagaimana create, customize, dan deploy Helm chart, manage dependency, dan best practice untuk Helm.

Catatan
Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 37 di bawah ini
Di episode sebelumnya, kita menjelajahi Pod Security Context, yang mengontrol pengaturan keamanan untuk Pod dan container. Sekarang kita akan mendalami Helm Charts, yang menyederhanakan packaging dan deploying aplikasi Kubernetes.
Catatan: Disini saya akan menggunakan Kubernetes Cluster yang di install melalui K3s.
Helm adalah package manager untuk Kubernetes. Ini memungkinkan Anda mendefinisikan, install, dan upgrade aplikasi Kubernetes yang kompleks menggunakan chart. Pikirkan Helm chart seperti Docker image untuk Kubernetes - mereka package semuanya yang diperlukan untuk menjalankan aplikasi. Daripada manage puluhan file YAML secara manual, Helm memungkinkan Anda template dan version deployment Anda.
Helm chart adalah koleksi file yang mendeskripsikan serangkaian resource Kubernetes. Ini pada dasarnya adalah package yang di-template yang dapat dikustomisasi dan di-deploy ke cluster.
1. Simplify Deployment
Package aplikasi kompleks menjadi single deployable unit.
2. Reusability
Share chart di seluruh tim dan organisasi.
3. Templating
Gunakan variable dan logic untuk customize deployment.
4. Versioning
Track dan manage berbagai versi aplikasi.
5. Dependency Management
Manage dependency antara aplikasi.
6. Rollback Capability
Easily rollback ke versi sebelumnya.
Typical Helm chart memiliki struktur ini:
my-chart/
├── Chart.yaml
├── values.yaml
├── values-prod.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── configmap.yaml
│ ├── ingress.yaml
│ └── _helpers.tpl
├── charts/
│ └── dependency-chart/
└── README.mdMetadata tentang chart:
apiVersion: v2
name: my-app
description: A Helm chart for my application
type: application
version: 1.0.0
appVersion: "1.0"
keywords:
- app
- kubernetes
maintainers:
- name: Your Name
email: your@email.comDefault configuration value:
replicaCount: 3
image:
repository: myapp
tag: "1.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
targetPort: 8080
ingress:
enabled: true
className: nginx
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256MiKubernetes manifest dengan template variable:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-app.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 12 }}helm create my-appIni membuat basic chart structure dengan example file.
helm lint my-appValidate chart untuk error.
helm template my-app ./my-appMenunjukkan rendered YAML tanpa install.
helm install my-release ./my-app --dry-run --debugSimulate installation tanpa actually deploy.
helm install my-release ./my-appInstall chart dengan default value.
helm install my-release ./my-app -f values-prod.yamlInstall dengan custom value dari file.
helm install my-release ./my-app \
--set replicaCount=5 \
--set image.tag=2.0Override specific value dari command line.
helm install my-release ./my-app -n production --create-namespaceInstall di specific namespace.
helm list
helm list -n productionMenunjukkan semua installed release.
helm status my-release
helm get values my-release
helm get manifest my-releaseMenunjukkan release status dan configuration.
helm upgrade my-release ./my-appUpgrade ke versi baru.
helm rollback my-release 1Rollback ke previous revision.
helm uninstall my-releaseRemove release dari cluster.
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo updateAdd Helm repository dan update index.
helm search repo bitnami
helm search repo bitnami/nginxSearch chart di repository.
helm install my-nginx bitnami/nginxInstall chart dari repository.
# String function
{{ .Values.name | upper }}
{{ .Values.name | lower }}
{{ .Values.name | quote }}
# Conditional
{{ if .Values.enabled }}
enabled: true
{{ end }}
# Loops
{{ range .Values.items }}
- {{ . }}
{{ end }}
# Default value
{{ .Values.name | default "default-name" }}
# Include template
{{ include "my-app.labels" . }}{{/*
Expand the name of the chart.
*/}}
{{- define "my-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "my-app.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 }}
{{/*
Common labels
*/}}
{{- define "my-app.labels" -}}
helm.sh/chart: {{ include "my-app.chart" . }}
{{ include "my-app.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "my-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}apiVersion: v2
name: my-app
version: 1.0.0
dependencies:
- name: postgresql
version: "12.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "17.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabledhelm dependency update ./my-appDownload dan update chart dependency.
postgresql:
enabled: true
auth:
username: myapp
password: secret
database: myapp_db
redis:
enabled: true
auth:
enabled: falseapiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "web-app.fullname" . }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ include "web-app.name" . }}
template:
metadata:
labels:
app: {{ include "web-app.name" . }}
spec:
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ include "web-app.fullname" . }}-secret
key: database-url
resources:
{{- toYaml .Values.resources | nindent 12 }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "web-app.fullname" . }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.port }}
selector:
app: {{ include "web-app.name" . }}{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "web-app.fullname" . }}
spec:
ingressClassName: {{ .Values.ingress.className }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "web-app.fullname" . }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}Problem: Chart tidak reusable.
# JANGAN LAKUKAN INI - Hardcoded value
image: myapp:1.0
replicas: 3Solusi: Gunakan template variable:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
replicas: {{ .Values.replicaCount }}Problem: Chart gagal jika value tidak disediakan.
# JANGAN LAKUKAN INI - No default value
image: "{{ .Values.image }}"Solusi: Provide default:
image: "{{ .Values.image | default "nginx:latest" }}"Problem: Resource memiliki inconsistent name.
# JANGAN LAKUKAN INI - Inconsistent naming
metadata:
name: my-app
---
metadata:
name: myappSolusi: Gunakan helper template:
metadata:
name: {{ include "my-app.fullname" . }}Problem: Chart memiliki error ketika di-deploy.
Solusi: Selalu test sebelum deploy:
helm lint ./my-app
helm template ./my-app
helm install --dry-run --debug ./my-appProblem: User tidak tahu bagaimana menggunakan chart.
Solusi: Document value dan usage:
# My App Helm Chart
## Installation
```bash
helm install my-release ./my-app
```
## Configuration
| Parameter | Description | Default |
|-----------|-------------|---------|
| replicaCount | Number of replicas | 3 |
| image.repository | Image repository | myapp |
| image.tag | Image tag | 1.0 |version: 1.2.3
appVersion: "2.0.1"Document semua available value dengan comment:
# Number of replicas
replicaCount: 3
# Image configuration
image:
# Image repository
repository: myapp
# Image tag
tag: "1.0"
# Image pull policy
pullPolicy: IfNotPresentCreate reusable template helper:
{{- define "my-app.fullname" -}}
{{- .Release.Name }}-{{ .Chart.Name }}
{{- end }}Selalu validate sebelum deploy:
helm lint ./my-app
helm template ./my-appDeploy ke specific namespace:
helm install my-release ./my-app -n production --create-namespaceTrack chart version di version control:
git tag chart-v1.0.0Create comprehensive README:
# Chart Documentation
## Value
- `replicaCount`: Number of replicas (default: 3)
- `image.repository`: Image repository (default: myapp)
- `image.tag`: Image tag (default: 1.0)Execute action di specific point di release lifecycle:
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-app.fullname" . }}-pre-install
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-weight": "-5"
spec:
template:
spec:
containers:
- name: pre-install
image: busybox
command: ['sh', '-c', 'echo "Pre-install hook"']
restartPolicy: Neverpre-install - Before installpost-install - After installpre-upgrade - Before upgradepost-upgrade - After upgradepre-delete - Before deletepost-delete - After deletepre-rollback - Before rollbackpost-rollback - After rollbackPada episode 38 ini, kita telah membahas Helm Charts di Kubernetes secara mendalam. Kita sudah belajar bagaimana create, customize, dan deploy Helm chart, manage dependency, dan follow best practice.
Key takeaway:
Helm chart menyederhanakan Kubernetes deployment dan membuat aplikasi lebih reusable dan maintainable.
Catatan
Untuk kalian yang ingin melanjutkan ke episode selanjutnya, bisa click thumbnail episode 38 di bawah ini