Basics of Helm git clone Install Helm 3 Creating the chart Structure of the chart deleted unwanted files Configuration the yamls files from scratch create ngnix deployment with 3 replicas and use nodeport to expose ports how to deploy the chart delete the chart Deep Dive into Charts create new chart charts if you see your file structure you don't see charts folder Notes.txt its container notes for user how to run this helm charts helper this file nothing to do with kubernetes resource its just variable chart.yaml its container helm chart versioning apiVersion: v2 name: new-chart description: A Helm chart for Kubernetes A chart can be either an 'application' or a 'library' chart. Application charts are a collection of templates that can be packaged into versioned archives to be deployed. Library charts provide useful utilities or functions for the chart developer. They're included as a dependency of application charts to inject those utilities and functions into the rendering pipeline. Library charts do not define any templates and therefore cannot be deployed. type: application This is the chart version. This version number should be incremented each time you make changes to the chart and its templates, including the app version. Versions are expected to follow Semantic Versioning (https://semver.org/) version: 0.1.0 This is the version number of the application being deployed. This version number should be incremented each time you make changes to the application. Versions are not expected to follow Semantic Versioning. They should reflect the version the application is using. It is recommended to use it with quotes. appVersion: "1.16.0" Default values for application-1. This is a YAML-formatted file. Declare variables to be passed into your templates. deployment: replicaCount: 1 name: new-deployememt image: app: ngnix version: latest service: name: my-service type: NodePort port: 80 targetPort: 80 nodePort: 32046 selector: app: ngnix base) ➜ application-1 git:(main) ✗ helm install chart-1 . W0325 04:26:44.306101 7525 warnings.go:70] unknown field "spec.ports[0].nodeport" NAME: chart-1 LAST DEPLOYED: Mon Mar 25 04:26:44 2024 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None (base) ➜ application-1 git:(main) ✗ helm list NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION chart-1 default 1 2024-03-25 04:26:44.235604 +0530 IST deployed application-1-0.1.0 1.16.0 ➜ application-1 git:(main) ✗ helm install chart-2 . -f new-values.yaml W0325 04:31:02.212820 7835 warnings.go:70] unknown field "spec.ports[0].nodeport" NAME: chart-2 LAST DEPLOYED: Mon Mar 25 04:31:02 2024 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None {{- define "labels" }} app: ngnix version: "1.0" team: myteam {{- end }} (base) ➜ application-1 git:(main) ✗ helm template . Source: application-1/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-deployememt labels: app: ngnix version: "1.0" team: myteam spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: "ngnix:latest" (base) ➜ application-1 git:(main) ✗ apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Values.deployment.name }} labels: {{- include "labels" . nindent 4 }} spec: replicas: {{ .Values.deployment.replicaCount }} selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: "{{ .Values.deployment.image.app }}:{{ .Values.deployment.image.version }}" ports: - name: http containerPort: 80 protocol: TCP {{- if eq .Values.container1.enabled true }} {{- include "container1" . nindent 8 }} {{- end }} {{- define "container1" }} name: new-container image: "{{ .Values.deployment.image.app }}:{{ .Values.deployment.image.version }}" ports: - name: http containerPort: 80 protocol: TCP {{- end }} Default values for application-1. This is a YAML-formatted file. Declare variables to be passed into your templates. deployment: replicaCount: 1 name: my-deployememt image: app: ngnix version: latest service: name: my-service type: NodePort port: 80 targetPort: 80 nodePort: 32036 selector: app: ngnix container1: enabled: true (base) ➜ application-1 git:(main) ✗ helm template . Source: application-1/templates/service.yaml apiVersion: v1 kind: Service metadata: name: my-service labels: app: ngnix spec: type: NodePort ports: - port: 80 targetPort: 80 nodeport: 32036 protocol: TCP name: http selector: app: ngnix Source: application-1/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-deployememt labels: app: ngnix version: "1.0" team: myteam spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: "ngnix:latest" ports: - name: http containerPort: 80 protocol: TCP - name: new-container image: "ngnix:latest" ports: - name: http containerPort: 80 protocol: TCP (base) ?➜ application-1 git:(main) ?✗ {{- define "container1" }} name: new-container image: "{{ .Values.deployment.image.app }}:{{ .Values.deployment.image.version }}" ports: - name: http containerPort: 80 protocol: TCP {{- end }} {{- define "container2" }} name: new-container2 image: "{{ .Values.deployment.image.app }}:{{ .Values.deployment.image.version }}" ports: - name: http containerPort: 80 protocol: TCP {{- end }} Default values for application-1. This is a YAML-formatted file. Declare variables to be passed into your templates. deployment: replicaCount: 1 name: my-deployememt image: app: ngnix version: latest service: name: my-service type: NodePort port: 80 targetPort: 80 nodePort: 32036 selector: app: ngnix container1: enabled: false apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Values.deployment.name }} labels: {{- include "labels" . nindent 4 }} spec: replicas: {{ .Values.deployment.replicaCount }} selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: "{{ .Values.deployment.image.app }}:{{ .Values.deployment.image.version }}" ports: - name: http containerPort: 80 protocol: TCP {{- if eq .Values.container1.enabled true }} {{- include "container1" . nindent 8 }} {{- else }} {{- include "container2" . nindent 8 }} {{- end }} (base) ➜ application-1 git:(main) ✗ helm template . Source: application-1/templates/service.yaml apiVersion: v1 kind: Service metadata: name: my-service labels: app: ngnix spec: type: NodePort ports: - port: 80 targetPort: 80 nodeport: 32036 protocol: TCP name: http selector: app: ngnix Source: application-1/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-deployememt labels: app: ngnix version: "1.0" team: myteam spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: "ngnix:latest" ports: - name: http containerPort: 80 protocol: TCP - name: new-container2 image: "ngnix:latest" ports: - name: http containerPort: 80 protocol: TCP (base) ➜ application-1 git:(main) ✗ yaml replicas: {{ .Values.replicaCount }} yaml releaseName: {{ .Release.Name }} releaseNamespace: {{ .Release.Namespace }} yaml chartName: {{ .Chart.Name }} chartVersion: {{ .Chart.Version }} yaml containerPort: {{ .Values.containerPort }} yaml {{- if .Values.enableFeature }} featureEnabled: true {{- end }} yaml {{- if .Values.enableFeature }} featureEnabled: true {{- else }} featureEnabled: false {{- end }} yaml {{- range .Values.ingress.hosts }} - host: {{ . }} {{- end }} yaml {{- range $key, $value := .Values.labels }} {{ $key }}: {{ $value }} {{- end }} yaml username: {{ .Values.database.credentials.username }} yaml message: {{ .Values.message quote }} yaml {{- include "partials.common" . indent 2 }} yaml {{- toYaml .Values.config nindent 4 }} yaml jsonData: {{ toJson .Values.data }} yaml password: {{ randAlphaNum 10 quote }} yaml {{- if .Values.preInstallJob }} # pre-install job definition {{- end }} yaml {{- if .Values.postInstallJob }} # post-install job definition {{- end }} yaml apiVersion: v1 kind: Secret metadata: name: {{ .Release.Name }}-secret type: Opaque data: password: {{ .Values.secret.password b64enc }} yaml apiVersion: v1 kind: Service metadata: name: {{ include "mychart.fullname" . }} yaml apiVersion: v1 kind: ConfigMap metadata: name: {{ include "mychart.fullname" . }} data: config.yaml: {{ .Files.Get "config.yaml" indent 4 }} yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ include "mychart.fullname" . }} spec: rules: - host: {{ .Values.ingress.host }} yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: {{ include "mychart.fullname" . }}-data yaml resources: limits: cpu: {{ .Values.resources.cpu quote }} memory: {{ .Values.resources.memory quote }} yaml apiVersion: batch/v1 kind: Job metadata: name: {{ .Release.Name }}-job spec: template: spec: containers: - name: {{ .Chart.Name }}-job image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" command: ["{{ .Values.command }}"] yaml apiVersion: batch/v1beta1 kind: CronJob metadata: name: {{ .Release.Name }}-cronjob spec: schedule: "/1 " jobTemplate: spec: template: spec: containers: - name: {{ .Chart.Name }}-cronjob image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" command: ["{{ .Values.command }}"] yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ .Release.Name }}-statefulset yaml apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Release.Name }}-deployment spec: template: spec: containers: - name: {{ .Chart.Name }}-container image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" livenessProbe: httpGet: path: /healthz port: 80 initialDelaySeconds: 30 readinessProbe: httpGet: path: /readyz port: 80 initialDelaySeconds: 5 yaml apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: {{ .Release.Name }}-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: {{ .Release.Name }}-deployment minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 50 yaml dependencyValue: {{ .Values.dependencies.subchart.value }} yaml port: {{ .Values.port default 8080 }} yaml {{- if and .Values.condition1 .Values.condition2 }} # Block content {{- end }} yaml {{- if or .Values.condition1 .Values.condition2 }} # Block content {{- end }} yaml {{- range $index, $element := .Values.list }} - index: {{ $index }}, value: {{ $element }} {{- end }} yaml {{- range sort .Values.list }} - value: {{ . }} {{- end }} yaml renderedTemplate: {{ tpl (.Files.Get "template.yaml") . indent 4 }} yaml {{- include (printf "%s-config" .Values.serviceName) . indent 2 }} yaml {{- include "external-template.tpl" . indent 2 }} yaml {{- printf "%#v" .Values nindent 2 }} yaml metadata: name: {{ .Release.Name }}-{{ .Chart.Name }} yaml # This is a comment yaml apiVersion: v1 kind: ConfigMap metadata: name: my-configmap data: {{ .Files.Get "config-file.yaml" indent 2 }} yaml combinedValue: {{ trimPrefix "prefix-" (upper .Values.value) }} yaml volumeClaimTemplates: - metadata: name: data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi yaml apiVersion: v1 kind: Secret metadata: name: my-secret annotations: "helm.sh/resource-policy": keep type: Opaque data: password: {{ .Values.externalSecret.password b64enc }} yaml releaseDate: {{ .Release.Timestamp }} yaml {{ printf "%#v" .Values nindent 2 }} yaml quotedValue: {{ .Values.someValue quote }} unquotedValue: {{ .Values.quotedValue unquote }} yaml annotations: myAnnotation: {{ .Values.annotations.myAnnotation quote }} yaml labels: myLabel: {{ .Values.labels.myLabel quote }} yaml {{- if .Values.enablePodDisruptionBudget }} apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: {{ include "mychart.fullname" . }} spec: # PDB specification {{- end }} yaml requiredValue: {{ required "Value is required" .Values.requiredValue }} yaml domain: {{ .Values.domain lower trunc 9 quote}}
Kubernetes lab
Learn Helm
A comprehensive guide to Helm, covering its history, architecture, and practical usage in container orchestration.