1. Pengenalan Helm
Helm adalah package manager resmi untuk Kubernetes. Sama seperti apt atau npm mengelola paket di sistem operasi atau Node.js, Helm mengelola paket aplikasi di Kubernetes. Paket-paket ini disebut chart — sekumpulan file YAML yang didefinisikan untuk menginstal, memperbarui, atau menghapus aplikasi di cluster Kubernetes.
Dengan hanya satu perintah helm install, Anda bisa mendeployseluruh stack aplikasi — termasuk Deployment, Service, ConfigMap, Secret, Ingress, dan resource Kubernetes lainnya — tanpa perlu menulis puluhan bahkan ratusan file YAML secara manual.
Mengapa Helm Penting?
| Manfaat | Penjelasan |
|---|---|
| Packaging | Mengemas semua Kubernetes manifests menjadi satu unit yang bisa di-share dan di-install ulang |
| Templating | Variable dan conditionals memungkinkan satu chart dikonfigurasi untuk banyak environment |
| Release Management | Setiap instalasi Helm disebut release, memungkinkan rollback dan history |
| Repositori | Berbagi chart melalui repository seperti ArtifactHub atau ChartMuseum |
| Dependency Management | Chart bisa memiliki sub-chart sebagai dependency, mirip npm package.json |
| Rollback | Sangat mudah melakukan rollback ke versi sebelumnya jika ada masalah |
/"No. Buat chart baru dengan nama 'web-app'"/
/"Chart.yaml"/
/".helmignore"/
charts/
/"templates/"/
/"deployment.yaml"/
/"service.yaml"/
/"serviceaccount.yaml"/
/"hpa.yaml"/
/"ingress.yaml"/
/"_helpers.tpl"/
/"NOTES.txt"/
tests/
/"test-connection.yaml"/
/"values.yaml"/
Langkah 2: Edit Chart.yaml
apiVersion: v2
name: web-app
description: Chart Helm untuk aplikasi web BeebaneLabs
type: application
version: 0.1.0
appVersion: "1.0.0"
maintainers:
- name: BeebaneLabs
email: dev@beebanelabs.com
Langkah 3: Konfigurasi Values
# values.yaml untuk aplikasi web
replicaCount: 2
image:
repository: beebanelabs/web-app
pullPolicy: IfNotPresent
tag: "1.0.0"
serviceAccount:
create: true
name: ""
annotations: {}
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: nginx
annotations: {}
hosts:
- host: web-app.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
Langkah 4: Buat Deployment Template
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "web-app.fullname" . }}
labels:
{{- include "web-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "web-app.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "web-app.selectorLabels" . | nindent 8 }}
spec:
serviceAccountName: {{ include "web-app.serviceAccountName" . }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
Langkah 5: Build, Test, dan Install
# Lint chart (validasi syntax)
helm lint web-app/
# Render template (preview output YAML)
helm template my-release web-app/
# Dry-run install
helm install my-release web-app/ --dry-run --debug
# Install chart
helm install my-release web-app/ \
--set image.tag=1.0.0 \
--set replicaCount=3
# Package chart untuk distribusi
helm package web-app/
# Install test
helm test my-release
_helpers.tpl: Template Helpers
{{/*
Expand the name of the chart.
*/}}
{{- define "web-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "web-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 "web-app.labels" -}}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
{{ include "web-app.selectorLabels" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "web-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "web-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
8. Helm Template Functions
Helm menggunakan engine templating Go yang sangat powerful. Memahami fungsi-fungsi template memungkinkan Anda membuat chart yang lebih dinamis dan fleksibel.
Fungsi Dasar
# Akses values
{{ .Values.image.repository }}
{{ .Values.replicaCount }}
# Akses chart metadata
{{ .Chart.Name }}
{{ .Chart.Version }}
# Akses release info
{{ .Release.Name }}
{{ .Release.Namespace }}
# Default value (jika kosong, pakai default)
{{ .Values.image.tag | default "latest" }}
# Conditional (if/else)
{{- if .Values.ingress.enabled }}
# Ingress configuration
{{- end }}
# Range (loop)
{{- range .Values.ingress.hosts }}
- host: {{ .host }}
{{- end }}
# With (scope change)
{{- with .Values.resources }}
resources:
limits:
cpu: {{ .limits.cpu }}
{{- end }}
# toYaml (convert ke yaml)
{{ toYaml .Values.resources | nindent 10 }}
# quote & squote
{{ .Values.image.repository | quote }}
# printf (format string)
{{ printf "%s-%s" .Release.Name .Chart.Name }}
# required (wajib diisi)
{{ required "Image repository wajib diisi!" .Values.image.repository }}
# fail (hentikan rendering dengan error)
{{ fail "Error: ingress host harus diisi" }}
Fungsi Sprig (Tambahan Helm)
Helm mendukung library Sprig yang menyediakan ratusan fungsi tambahan:
# String manipulation
{{ .Values.name | upper }} # "HELLO"
{{ .Values.name | lower }} # "hello"
{{ .Values.name | title }} # "Hello"
{{ .Values.name | trunc 5 }} # "Hello" (truncate)
{{ .Values.name | replace "o" "0" }} # "Hell0"
# Lists & Dicts
{{ list "a" "b" "c" }} # [a b c]
{{ dict "key1" "val1" "key2" "val2" }}
{{ keys .Values.config }} # list semua keys
{{ hasKey .Values.config "debug" }} # true/false
# Math
{{ add 1 2 }} # 3
{{ mul 2 3 }} # 6
{{ div 10 3 }} # 3
{{ mod 10 3 }} # 1
{{ add 1 2 3 }} # 6
# Encoding
{{ "hello" | b64enc }} # base64 encode
{{ "aGVsbG8=" | b64dec }} # base64 decode
# Crypto
{{ sha256sum "hello" }} # SHA256 hash
# Type conversion
{{ int64 .Values.replicas }}
{{ toString .Values.port }}
# Semua fungsi Sprig
# https://masterminds.github.io/sprig/
Kondisional Lanjutan
# if/else if/else
{{- if eq .Values.env "production" }}
replicas: 5
{{- else if eq .Values.env "staging" }}
replicas: 2
{{- else }}
replicas: 1
{{- end }}
# not, and, or
{{- if and .Values.ingress.enabled .Values.tls.enabled }}
# TLS ingress
{{- end }}
{{- if or .Values.debug .Values.verbose }}
logLevel: debug
{{- end }}
{{- if not .Values.serviceAccount.create }}
# Use existing service account
{{- end }}
# ne (not equal), contains, has
{{- if ne .Values.image.tag "latest" }}
imagePullPolicy: IfNotPresent
{{- end }}
{{- if contains "prod" .Release.Name }}
resources:
limits:
cpu: 1000m
{{- end }}
# Regex
{{- if regexMatch "^v[0-9]+" .Values.image.tag }}
# Semver tag detected
{{- end }}
9. Helm Plugins & Ecosystem
Helm memiliki ekosistem plugin yang memperluas fungsinya. Plugin bisa ditambahkan untuk keamanan, manajemen secrets, dan integrasi dengan tools lain.
Plugin Populer
| Plugin | Fungsi | Instalasi |
|---|---|---|
| helm-secrets | Enkripsi/decryption values menggunakan SOPS | helm plugin install https://github.com/jkroepke/helm-secrets |
| helm-diff | Preview perubahan sebelum upgrade | helm plugin install https://github.com/databus23/helm-diff |
| helmfile | Declarative spec untuk multiple releases | brew install helmfile |
| helm-git | Install chart dari Git repository | helm plugin install https://github.com/aslafy-z/helm-git |
| helm unittest | Unit testing untuk chart | helm plugin install https://github.com/helm-unittest/helm-unittest |
| helm-cm-push | Push chart ke OCI registry | helm plugin install https://github.com/chartmuseum/helm-push |
Contoh: helm-secrets
# Instalasi helm-secrets
helm plugin install https://github.com/jkroepke/helm-secrets
# Enkripsi values file
sops --encrypt --in-place secrets.yaml
# Hasil: secrets.yaml (encrypted)
# Install dengan secrets
helm secrets upgrade my-release bitnami/nginx \
-f values.yaml \
-f secrets://secrets.yaml
# Lihat decrypted values
helm secrets view secrets.yaml
Contoh: helmfile
# helmfile.yaml - Declarative Helm releases
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
- name: grafana
url: https://grafana.github.io/helm-charts
releases:
- name: nginx-ingress
namespace: ingress-system
chart: ingress-nginx/ingress-nginx
version: 4.10.0
values:
- controller:
replicaCount: 2
resources:
limits:
cpu: 500m
memory: 256Mi
- name: monitoring
namespace: monitoring
chart: grafana/kube-prometheus-stack
version: 61.0.0
values:
- grafana:
adminPassword: admin123
- prometheus:
retention: 30d
- name: my-app
namespace: production
chart: ./charts/my-app
values:
- values-production.yaml
Unit Testing Chart
# tests/deployment_test.yaml
suite: deployment tests
templates:
- deployment.yaml
tests:
- it: should create deployment with correct name
set:
nameOverride: my-app
asserts:
- isKind:
of: Deployment
- matchRegex:
path: metadata.name
pattern: my-app
- it: should set correct replica count
set:
replicaCount: 3
asserts:
- equal:
path: spec.replicas
value: 3
- it: should use correct image
set:
image:
repository: my-app
tag: "2.0"
asserts:
- equal:
path: spec.template.spec.containers[0].image
value: "my-app:2.0"
- it: should not create HPA when autoscaling disabled
set:
autoscaling:
enabled: false
asserts:
- hasDocuments:
count: 1
10. Best Practices
Mengikuti best practices Helm akan membantu Anda mengelola aplikasi di Kubernetes dengan lebih efektif dan aman. Berikut panduan komprehensif dari BeebaneLabs.
Struktur Chart
| Praktik | Rekomendasi |
|---|---|
| Versi Semver | Gunakan versi semver untuk chart: major.minor.patch (1.0.0) |
| appVersion | Selalu update appVersion sesuai versi aplikasi yang di-deploy |
| Minimal Permissions | Jangan berikan RBAC yang terlalu luas di chart |
| Non-root Container | Selalu jalankan container sebagai user non-root |
| Health Probes | Sertakan liveness dan readiness probe |
| Resource Limits | Selalu set resource requests dan limits |
Keamanan Chart
- Gunakan helm-secrets untuk values yang berisi sensitive data
- Jangan pernah hardcode credentials di values.yaml
- Gunakan Kubernetes Secret untuk password, API keys, dan certificates
- Scan chart dengan
trivyataucheckovsebelum deploy - Pin versi image tags, hindari menggunakan
latest - Gunakan
.helmignoreuntuk mengecualikan file sensitif
Manajemen Release
- Gunakan
--atomicuntuk auto-rollback jika install gagal - Gunakan
--waituntuk memastikan semua resource ready sebelum selesai - Gunakan
--timeoutuntuk mencegah proses hanging - Gunakan namespace terpisah untuk setiap environment (dev, staging, prod)
- Simpan values di version control (Git) untuk audit trail
Contoh Perintah Production-Ready
# Install production dengan semua safety net
helm install my-app bitnami/nginx \
--namespace production \
--create-namespace \
-f values-production.yaml \
--set image.tag=1.27.0 \
--atomic \
--wait \
--timeout 10m \
--history-max 10
# Upgrade dengan diff preview
helm diff upgrade my-app bitnami/nginx \
-f values-production.yaml
# Upgrade dengan atomic (auto-rollback on failure)
helm upgrade my-app bitnami/nginx \
--namespace production \
-f values-production.yaml \
--atomic \
--wait \
--timeout 10m
# Lihat semua releases di production
helm list -n production -o wide
Selalu gunakan --dry-run sebelum melakukan install/upgrade di production. Periksa diff hasil render template sebelum memastikan perubahan aman untuk diterapkan.
11. Quiz Pemahaman
Uji pemahaman Anda tentang Kubernetes Helm dengan menjawab pertanyaan berikut:
1. Apa fungsi utama file Chart.yaml?
2. Apa itu "release" dalam konteks Helm?
3. Bagaimana cara override values saat install Helm chart?
4. Apa fungsi flag --atomic saat helm install/upgrade?
5. Di direktori mana sub-chart dependencies disimpan?