Helm in Kubernetes

Helm in Kubernetes

1.What is Helm chart?

Helm Chart is an application package manager for the Kubernetes cluster, just like we have an apt packager manager in Linux.

So what can we do with Helm Chart

  • Define k8s application

  • Install k8s application

  • Upgrade k8s application

The most important aspect of the Helm Chart is you do not have to use Kubernetes CLI(command line interface) and neither you need to remember complex Kubernetes commands to manage the Kubernetes manifest.

2.How to install Helm chart

2.1 From Binary release

  1. Download your desired version

  2. Unpack it (tar -zxvf helm-v3.0.0-linux-amd64.tar.gz)

  3. Find the helm binary in the unpacked directory, and move it to its desired destination (mv linux-amd64/helm /usr/local/bin/helm)

2.2 Through package managers

The Helm community provides the ability to install Helm through operating system package managers. These are not supported by the Helm project and are not considered trusted 3rd parties.

Homebrew (macOS)

brew install helm

Chocolatey and scoop (Windows)

choco install kubernetes-helm
scoop install helm

APT (Debian/Ubuntu)

curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

dnf/yum (fedora)

sudo dnf install helm

2.3 From Script

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh
$ which helm
$ helm version

Let's install Helm using the script

3.Let's create Our First Helm Chart

Before we create our First Helm Chart, we need to have Kubernetes cluster up and running. Use the following command to verify the status of the Kubernetes cluster

$ kubectl get all
$ kubect get pods

$ helm create hello
$ tree hello

Note: Install tree command by using sudo apt-get install tree or sudo yum -y install tree

$ cd hello

Chart.yaml

Contains the metadata of the helm

apiVersion: v2 #mandatory
name: hello #mandatory
description: A Helm chart for Kubernetes
type: application
version: 0.1.0 #mandatory
appVersion: 1.16.0

values.yaml

This file holds the values for the configuration

Here you need to update the configuration at three places repository, port and service

  1. repository : rjthapaa/nodeimage

  2. port: 80000

  3. Service: NodePort

  4. Replicas count as needed

replicaCount: 2

image:
  repository: rjthapaa/nodeimage #Update the image from dockerhub
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: ""

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

podAnnotations: {}

podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

service:
  type: NodePort  #Update the service type
  port: 8000      #Update the application port number

ingress:
  enabled: false
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

$ cd templates

deployment.yaml

We need to update only the containerPort and edit the image

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "hello.fullname" . }}
  labels:
    {{- include "hello.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "hello.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "hello.selectorLabels" . | nindent 8 }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "hello.serviceAccountName" . }}
      securityContext:
        {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}"                #edited the imagevalue
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 8000 #Update the Port
              protocol: TCP
          #livenessProbe:
           # httpGet:
            #  path: /
             # port: http
         # readinessProbe:
          #  httpGet:
           #   path: /
            #  port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}

service. yaml

No need to update anything here

apiVersion: v1
kind: Service
metadata:
  name: {{ include "hello.fullname" . }}
  labels:
    {{- include "hello.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "hello.selectorLabels" . | nindent 4 }}
$ cd

Displays the entire yaml code
$ helm template hello

Checks for errors in yaml files
$ helm lint hello

Install a hel chart using install command
$ helm install <FIRST_ARGUMENT_RELEASE_NAME> <SECOND_ARGUMENT_CHART_NAME>
$ helm install hellonode hello

$ helm list -a
$ kubectl get all
$ kubectl get svc
$ kubectl get pods -o wide
$ helm delete hellonode

NodePortcan vary in the range 30000-32767

Access the node service by using NodePublicIP:Nodeport number