Belajar Kubernetes - Episode 38 - Pengenalan dan Penjelasan Helm Charts

Belajar Kubernetes - Episode 38 - Pengenalan dan Penjelasan Helm Charts

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.

Arman Dwi Pangestu
Arman Dwi PangestuApril 13, 2026
0 views
6 min read

Pendahuluan

Catatan

Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 37 di bawah ini

Episode 37Episode 37

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.

Memahami Helm Charts

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.

Mengapa Helm Charts Penting

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.

Struktur Helm Chart

Typical Helm chart memiliki struktur ini:

plaintext
my-chart/
├── Chart.yaml
├── values.yaml
├── values-prod.yaml
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── configmap.yaml
│   ├── ingress.yaml
│   └── _helpers.tpl
├── charts/
│   └── dependency-chart/
└── README.md

Chart.yaml

Metadata tentang chart:

KubernetesChart.yaml
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.com

values.yaml

Default configuration value:

Kubernetesvalues.yaml
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: 256Mi

Templates

Kubernetes manifest dengan template variable:

Kubernetestemplates/deployment.yaml
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 }}

Membuat Helm Chart

Initialize Chart

Kubernetesbash
helm create my-app

Ini membuat basic chart structure dengan example file.

Chart Validation

Kubernetesbash
helm lint my-app

Validate chart untuk error.

Template Rendering

Kubernetesbash
helm template my-app ./my-app

Menunjukkan rendered YAML tanpa install.

Dry Run

Kubernetesbash
helm install my-release ./my-app --dry-run --debug

Simulate installation tanpa actually deploy.

Install Helm Charts

Basic Installation

Kubernetesbash
helm install my-release ./my-app

Install chart dengan default value.

Custom Values

Kubernetesbash
helm install my-release ./my-app -f values-prod.yaml

Install dengan custom value dari file.

Override Values

Kubernetesbash
helm install my-release ./my-app \
  --set replicaCount=5 \
  --set image.tag=2.0

Override specific value dari command line.

Namespace

Kubernetesbash
helm install my-release ./my-app -n production --create-namespace

Install di specific namespace.

Manage Helm Release

List Release

Kubernetesbash
helm list
helm list -n production

Menunjukkan semua installed release.

Get Release Info

Kubernetesbash
helm status my-release
helm get values my-release
helm get manifest my-release

Menunjukkan release status dan configuration.

Upgrade Release

Kubernetesbash
helm upgrade my-release ./my-app

Upgrade ke versi baru.

Rollback Release

Kubernetesbash
helm rollback my-release 1

Rollback ke previous revision.

Uninstall Release

Kubernetesbash
helm uninstall my-release

Remove release dari cluster.

Helm Repository

Add Repository

Kubernetesbash
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

Add Helm repository dan update index.

Search Charts

Kubernetesbash
helm search repo bitnami
helm search repo bitnami/nginx

Search chart di repository.

Install from Repository

Kubernetesbash
helm install my-nginx bitnami/nginx

Install chart dari repository.

Template Function

Built-in Function

KubernetesTemplate Function
# 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" . }}

Helper Template

Kubernetestemplates/_helpers.tpl
{{/*
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 }}

Chart Dependency

Chart.yaml dengan Dependency

KubernetesChart.yaml dengan Dependency
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.enabled

Update Dependency

Kubernetesbash
helm dependency update ./my-app

Download dan update chart dependency.

values.yaml dengan Dependency

Kubernetesvalues.yaml dengan Dependency
postgresql:
  enabled: true
  auth:
    username: myapp
    password: secret
    database: myapp_db
 
redis:
  enabled: true
  auth:
    enabled: false

Contoh Praktis

Simple Web Application Chart

Kubernetestemplates/deployment.yaml
apiVersion: 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" . }}

Conditional Resource

KubernetesConditional Ingress
{{- 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 }}

Kesalahan dan Jebakan Umum

Kesalahan 1: Hardcoding Value

Problem: Chart tidak reusable.

KubernetesKesalahan: Hardcoded Value
# JANGAN LAKUKAN INI - Hardcoded value
image: myapp:1.0
replicas: 3

Solusi: Gunakan template variable:

KubernetesCorrect: Template Variable
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
replicas: {{ .Values.replicaCount }}

Kesalahan 2: Missing Default Value

Problem: Chart gagal jika value tidak disediakan.

KubernetesKesalahan: No Default
# JANGAN LAKUKAN INI - No default value
image: "{{ .Values.image }}"

Solusi: Provide default:

KubernetesCorrect: With Default
image: "{{ .Values.image | default "nginx:latest" }}"

Kesalahan 3: Inconsistent Naming

Problem: Resource memiliki inconsistent name.

KubernetesKesalahan: Inconsistent Name
# JANGAN LAKUKAN INI - Inconsistent naming
metadata:
  name: my-app
---
metadata:
  name: myapp

Solusi: Gunakan helper template:

KubernetesCorrect: Consistent Name
metadata:
  name: {{ include "my-app.fullname" . }}

Kesalahan 4: Not Testing Chart

Problem: Chart memiliki error ketika di-deploy.

Solusi: Selalu test sebelum deploy:

Kubernetesbash
helm lint ./my-app
helm template ./my-app
helm install --dry-run --debug ./my-app

Kesalahan 5: Poor Documentation

Problem: User tidak tahu bagaimana menggunakan chart.

Solusi: Document value dan usage:

KubernetesREADME.md
# 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 |

Praktik Terbaik

1. Gunakan Semantic Versioning

Kubernetesyaml
version: 1.2.3
appVersion: "2.0.1"

2. Provide Comprehensive values.yaml

Document semua available value dengan comment:

Kubernetesyaml
# Number of replicas
replicaCount: 3
 
# Image configuration
image:
  # Image repository
  repository: myapp
  # Image tag
  tag: "1.0"
  # Image pull policy
  pullPolicy: IfNotPresent

3. Gunakan Helper Template

Create reusable template helper:

Kubernetesyaml
{{- define "my-app.fullname" -}}
{{- .Release.Name }}-{{ .Chart.Name }}
{{- end }}

4. Validate Chart

Selalu validate sebelum deploy:

Kubernetesbash
helm lint ./my-app
helm template ./my-app

5. Gunakan Namespace

Deploy ke specific namespace:

Kubernetesbash
helm install my-release ./my-app -n production --create-namespace

6. Version Your Chart

Track chart version di version control:

Kubernetesbash
git tag chart-v1.0.0

7. Document Value

Create comprehensive README:

Kubernetesmarkdown
# Chart Documentation
 
## Value
 
- `replicaCount`: Number of replicas (default: 3)
- `image.repository`: Image repository (default: myapp)
- `image.tag`: Image tag (default: 1.0)

Helm Hook

Execute action di specific point di release lifecycle:

KubernetesPre-Install Hook
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: Never

Hook Type

  • pre-install - Before install
  • post-install - After install
  • pre-upgrade - Before upgrade
  • post-upgrade - After upgrade
  • pre-delete - Before delete
  • post-delete - After delete
  • pre-rollback - Before rollback
  • post-rollback - After rollback

Kesimpulan

Pada 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 Charts package Kubernetes application
  • Chart.yaml - Chart metadata
  • values.yaml - Default configuration
  • templates/ - Kubernetes manifest dengan variable
  • helm create - Initialize chart baru
  • helm install - Deploy chart
  • helm upgrade - Update release
  • helm rollback - Revert ke previous version
  • Template function - Customize deployment
  • Dependency - Manage chart dependency
  • Repository - Share dan discover chart
  • Hook - Execute action di lifecycle event
  • Selalu validate - Test chart sebelum deploy
  • Document value - Help user understand configuration
  • Gunakan semantic versioning - Track chart version

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

Episode 38Episode 38

Related Posts