Building Your Own Helm Chart

Building Your Own Helm Chart

Helm charts are a powerful way to package, share, and deploy Kubernetes applications. While using existing charts is beneficial, there are times when you need to create a custom chart tailored to your specific application. In this lesson, we’ll guide you through the process of building your own Helm chart from scratch. By the end of this lesson, you’ll be able to structure a Helm chart, create templates, define default values, and package your chart for deployment.

Setting Up Your Environment

Before you start building your own Helm chart, ensure that your environment is properly set up.

Prerequisites

  • Helm CLI: Ensure Helm is installed and configured on your local machine.

  • Kubernetes Cluster: You should have access to a Kubernetes cluster, either locally (e.g., using Minikube) or on the cloud.

  • Text Editor: Use a code editor like VS Code, Vim, or any other that you prefer.

Creating a New Helm Chart

Helm provides a command to scaffold a new chart directory structure. This command creates all the necessary files and folders for a new chart.

Command to Create a New Helm Chart:

helm create myapp
  • myapp: This is the name of your new Helm chart. Helm will create a directory named myapp with the basic structure and files inside.

After running this command, you’ll see the following directory structure:

codemyapp/
  Chart.yaml
  values.yaml
  charts/
  templates/
    deployment.yaml
    service.yaml
    _helpers.tpl

Understanding the Helm Chart Structure

Each Helm chart follows a specific structure, with files and directories that serve distinct purposes. Let’s explore each component:

Chart.yaml

The Chart.yaml file contains metadata about your chart, such as its name, version, and description.

Example Chart.yaml:

apiVersion: v2
name: myapp
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.0"
  • apiVersion: Indicates the chart’s API version (usually v2 for Helm 3).

  • name: The name of your chart.

  • description: A brief description of what your chart does.

  • type: Indicates whether it’s an application or a library.

  • version: The version of the chart itself.

  • appVersion: The version of the application being deployed.

values.yaml

The values.yaml file defines default configuration values for your chart. These values can be overridden at deployment time.

Example values.yaml:

replicaCount: 2
image:
  repository: nginx
  tag: "1.19.0"
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 80
resources: {}
  • replicaCount: Default number of replicas for the deployment.

  • image: Specifies the default Docker image, tag, and pull policy.

  • service.type: Defines the default service type (e.g., ClusterIP).

  • resources: Placeholder for resource requests and limits.

templates/ Directory

This directory contains the Go templates that will be rendered into Kubernetes manifests. These templates define the Kubernetes resources your application will use.

Common Template Files:

  • deployment.yaml: Defines the Deployment resource.

  • service.yaml: Defines the Service resource.

  • _helpers.tpl: Contains helper functions for use in your templates.

Example deployment.yaml Template:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ include "myapp.name" . }}
  template:
    metadata:
      labels:
        app: {{ include "myapp.name" . }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        ports:
        - containerPort: 80
  • {{ .Values.replicaCount }}: Pulls the value from values.yaml.

  • {{ include "myapp.fullname" . }}: Uses a helper function defined in _helpers.tpl to generate a name.

charts/ Directory

The charts/ directory is used to manage dependencies. If your chart depends on other charts, those charts will be stored here.

helpers.tpl

The _helpers.tpl file is a place to store reusable template code. Functions defined here can be called from other templates within your chart.

Example _helpers.tpl Function:

{{- define "myapp.name" -}}
{{ .Chart.Name | lower }}
{{- end -}}

{{- define "myapp.fullname" -}}
{{ .Release.Name }}-{{ include "myapp.name" . }}
{{- end -}}
  • define: Declares a new template function.

  • include: Calls a function defined elsewhere in the chart.

Creating and Customizing Templates

With the basic structure in place, you can now create and customize the templates to define the Kubernetes resources that your application requires.

Defining a Deployment Template

Let’s start by defining a basic Deployment template in templates/deployment.yaml.

Example deployment.yaml:

yamlCopy codeapiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}
  labels:
    app: {{ include "myapp.name" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ include "myapp.name" . }}
  template:
    metadata:
      labels:
        app: {{ include "myapp.name" . }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        ports:
        - containerPort: 80

Defining a Service Template

Next, create a Service template in templates/service.yaml to expose your application.

Example service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: {{ include "myapp.fullname" . }}
  labels:
    app: {{ include "myapp.name" . }}
spec:
  type: {{ .Values.service.type }}
  ports:
  - port: {{ .Values.service.port }}
    targetPort: 80
  selector:
    app: {{ include "myapp.name" . }}
  • type: {{ .Values.service.type }}: Configures the service type from values.yaml.

  • port: {{ .Values.service.port }}: Sets the service port based on values.yaml.

Adding Custom Logic with Conditionals

To make your chart more flexible, you can add conditionals in your templates. For example, you might want to add resource limits only if they are specified.

Example Conditional Logic:

resources:
{{- if .Values.resources.requests }}
  requests:
    cpu: {{ .Values.resources.requests.cpu }}
    memory: {{ .Values.resources.requests.memory }}
{{- end }}
{{- if .Values.resources.limits }}
  limits:
    cpu: {{ .Values.resources.limits.cpu }}
    memory: {{ .Values.resources.limits.memory }}
{{- end }}

Packaging and Deploying Your Helm Chart

Once you’ve defined your templates and customized your chart, the next step is to package and deploy it.

Packaging Your Chart

You can package your Helm chart into a .tgz file, which can then be distributed or stored in a Helm repository.

Command to Package a Chart:

helm package myapp

This command creates a myapp-0.1.0.tgz file, which can be shared or uploaded to a Helm repository.

Deploying the Packaged Chart

To deploy your packaged chart, use the helm install command, specifying the chart archive and a release name.

Deploying Your Packaged Chart:

helm install my-release ./myapp-0.1.0.tgz

Helm will render the templates, create the Kubernetes resources, and track the release.

Hands-on Example: Building and Deploying a Simple Web Application

Let’s build a Helm chart for a simple web application and deploy it to a Kubernetes cluster.

Steps:

  1. Create a New Chart:

    helm create webapp
  2. Edit the values.yaml: Customize the application’s settings.

    replicaCount: 3
    image:
      repository: httpd
      tag: "2.4"
    service:
      type: LoadBalancer
      port: 8080
  3. Customize the Deployment Template: Ensure the deployment uses the custom settings.

  4. Package the Chart:

    helm package webapp
  5. Deploy the Packaged Chart:

    helm install my-webapp ./webapp-0.1.0.tgz
  6. Verify the Deployment:

    helm status my-webapp

Summary

Building your own Helm chart allows you to create reusable, configurable packages for deploying applications on Kubernetes. By understanding the structure of a Helm chart and how to create and customize templates, you can tailor deployments to fit specific needs, making your Kubernetes applications more flexible and easier to manage.

Last updated