How To Create A Helm Chart {and Deploy it on Kubernetes}

Introduction

Hallo setelah 3 bulan saya tidak upload karena banyak hal yang saya lakukan sehingga belum menyempatkan diri untuk menulis lagi, sudah banyak artikel yang saya buat sebelumnya dari mulai linux, databases, web server, container hingga terkahir kubernetes & CI/CD.

Kali ini saya akan membuat artikel tentang bagaimana cara membuat helm chart untuk deploy ke kubernetes

First What is Helm Chart????

Helm chart digunakan untuk deploy aplikasi yang kompononenya besar. Daftar dari helm chart official bisa dillihat disini https://github.com/helm/charts. Chart / template tersebut dapat di install atau di modifikasi untuk menyesuaikan kebutuhan, seperti menginstall plugin tertentu atau menggunakan custom Docker image.

Hal hal yang perlu disiapkan :

  • Image docker registry
  • Install Helm
  • Cluster kube

NB : Alasan menggunakan helm chart adalah karena bayangkan jika kita ingin men-deploy aplikasi atau services yang sangat banyak misal 10 repository, dan tidak mungkin kita melakukan apply menggunakan kubectl satu persatu manifestsnnya, tentu bukan opsi yang baik maka dari itu kita dapat menggunakan packet manger yaitu helm.

Langkah-langkah membuat helmchart saya bagi menjadi 3 stage sebagai berikut :

Step 1 – Create chart

Pertama kita membuat chart aplikasi yang akan kita deploy helm create mychart

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

Chart.yaml : nama template dan versioning aplikasi disini

templates : Adalah template manifests seperti deployment, service, ingress dll.

values.yaml : values adalah credentials dari manifests kita dengan indent yaml yang lebih mudah dipahami.

Step 2 – Define manifests

Disini contoh membuat file helm/template:

configMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.configmap.NAME }}
  namespace: {{ .Values.namespace }}
data:
  {{- range $key, $val := .Values.configmap }}
  {{ $key }}: "{{ $val | toString }}"
  {{- end}}

Secret

apiVersion: v1
kind: Secret
metadata:
  name: {{ .Values.secret.NAME }}
  namespace: {{ .Values.namespace}}
type: Opaque
data:
  {{- range $key, $val := .Values.secret }}
  {{ $key }}: {{ $val | toString | b64enc }}
  {{- end}}

Service

apiVersion: v1
kind: Service
metadata:
  name: {{ .Values.service.name }}-service
  namespace: {{ .Values.namespace }}
spec:
  selector:
    app: {{ .Values.service.app }}
  ports:
  - protocol: TCP
    port: {{ .Values.service.port }}
    targetPort: {{ .Values.service.port }}
    

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.deployment.name }}-deployment
  namespace: {{ .Values.namespace }}
  labels:
    app: {{ .Values.deployment.name }}
spec:
  replicas: {{ .Values.deployment.replicas }}
  selector:
    matchLabels:
      app: {{ .Values.deployment.app }}
  template:
    metadata:
      labels:
        app: {{ .Values.deployment.app }}
    spec:
      containers:
      - name: {{ .Values.deployment.containers.name }}
        image: {{ .Values.deployment.containers.image }}
        ports:
        - containerPort: {{ .Values.deployment.containerPort }}
        imagePullPolicy: Always
        env: 
          {{- toYaml .Values.env | nindent 12 }}
#Create readness & liveness
        readinessProbe:
          httpGet:
            path: /healthcheck
            port: {{ .Values.deployment.containerPort }}
            scheme: HTTP
          initialDelaySeconds: 20
          periodSeconds: 20
          failureThreshold: 3
        livenessProbe:
          httpGet:
            path: /healthcheck
            port: {{ .Values.deployment.containerPort }}
          initialDelaySeconds: 30
          periodSeconds: 30
          failureThreshold: 3
        resources:
          requests:
            cpu: {{ .Values.resources.requests.cpu }}
            memory: {{ .Values.resources.requests.memory }}
          limits:
            cpu: {{ .Values.resources.limits.cpu }}
            memory: {{ .Values.resources.limits.memory }}
      imagePullSecrets:
      - name: container-registry
      

Chart : nama aplikasi dan versioning

apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes

version: 0.1.0

appVersion: "1.16.0"

Values: manifest file credential kita yang berisi secret & configpam deployment dll

deployment:
  name: nginx-app
  app: nginx
  replicas: 1
  containerPort: 8080
  containers:
    name: nginx
    image:  nginx:latest
resources:
  requests:
    cpu: "128m"
    memory: "258Mi"
  limits:
    cpu: "256m"
    memory: "258Mi"

namespace: staging

service:
  name: nginx-app
  app: nginx
  port: 8080


secret:
  NAME: "nginx-secret"
  DB_HOST: 127.0.0.1
  DB_NAME: namedb
  DB_USER: user
  DB_PWD: asdf8
  DB_PORT: 3306

configmap:
  NAME: "nginx-configmap"
  DEBUG_MODE: true

#env

env: 
  - name: DB_HOST
    valueFrom:
      secretKeyRef:
        name: nginx-secret
        key: DB_HOST
  - name: DB_NAME
    valueFrom:
      secretKeyRef:
        name: nginx-secret
        key: DB_NAME
  - name: DB_USER
    valueFrom:
      secretKeyRef:
        name: nginx-secret
        key: DB_USER
  - name: DB_PWD
    valueFrom:
      secretKeyRef:
        name: nginx-secret
        key: DB_PWD
  - name: DB_PORT
    valueFrom:
      secretKeyRef:
        name: nginx-secret
        key: DB_PORT

#configmap
  - name: DEBUG_MODE
    valueFrom:
      configMapKeyRef:
        name: nginx-configmap
        key: DEBUG_MODE

repo di link berikut : https://github.com/gunawan-d/helm-mychart

Step 3 – Deploy app

Bagiamana cara untuk deploy aplikasi kita ke app menggunakan helm chart?

Command yang digunakan adalah upgrade & install, kemudian namespace chart & valuesnya

helm upgrade --install --namespace ${namespace} {$nameapp} {$Chart} -f {$values}

Deployment app

 helm upgrade --install --namespace staging nginx-test ../mychart -f ./values.yaml
kemudian chek list helm kita
helm list -n {$namespace}

Kemudian check app di cluster Kube kalian, Selamat mencoba, Terima kasih

Leave a Reply

Your email address will not be published. Required fields are marked *