Chart
Creating a Helm chart involves defining the structure, configuration values, and Kubernetes resources required for your application. In this section, I’ll guide you through creating a simple Helm chart and explain the template files.
Chart Structure
A typical Helm chart structure consists of the following directories and files:
SomeChart/charts/: Subcharts if any. Contains information about the chart, dependencies, version, etc.crds/: Contains custom resource definitions (CRDs).templates/: Templates which are passed through the template engine. These templates incorporate the contents opf the values.yaml file.templates/NOTES.txt: This plain text file is printed out post-installation and when viewing release status.values.yaml: Contains predefined (default) values which will be passed to the templates. Values in this file can be overriden by values passed on the command line during installation.values.schema.json: Provides an optional schema for the values.yaml file.Chart.yaml: Chart metadata.LICENSE: Contains lisense information, if any.README.md: Markdown-formatted chart description, optiions, etc.
Creating a Helm Chart
Initialize a New Helm Chart
To create a new Helm chart, you can use the helm create command. For example, let’s create a chart for a hypothetical web application called “mywebapp”:
$ helm create mywebapp
$ tree ./mywebapp -a
.
├── charts
├── Chart.yaml
├── .helmignore
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
View the Manifest
A manifest refers to a declarative configuration file that describes the desired state of a Kubernetes resource. Manifests are typically written in YAML or JSON format and are used to define various components and objects within a Kubernetes cluster. These objects can include pods, services, deployments, replica sets, config maps, secrets, and more. To view the manifest for the newly created package run:
$ helm install mywebapp-release ./mywebapp --dry-run
NAME: mywebapp-release
LAST DEPLOYED: Wed Sep 6 07:18:13 2023
NAMESPACE: default
STATUS: pending-install
REVISION: 1
HOOKS:
---
# Source: mywebapp/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "mywebapp-release-test-connection"
labels:
helm.sh/chart: mywebapp-0.1.0
app.kubernetes.io/name: mywebapp
app.kubernetes.io/instance: mywebapp-release
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['mywebapp-release:80']
restartPolicy: Never
MANIFEST:
---
# Source: mywebapp/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: mywebapp-release
labels:
helm.sh/chart: mywebapp-0.1.0
app.kubernetes.io/name: mywebapp
app.kubernetes.io/instance: mywebapp-release
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
---
# Source: mywebapp/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: mywebapp-release
labels:
helm.sh/chart: mywebapp-0.1.0
app.kubernetes.io/name: mywebapp
app.kubernetes.io/instance: mywebapp-release
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: mywebapp
app.kubernetes.io/instance: mywebapp-release
---
# Source: mywebapp/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mywebapp-release
labels:
helm.sh/chart: mywebapp-0.1.0
app.kubernetes.io/name: mywebapp
app.kubernetes.io/instance: mywebapp-release
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: mywebapp
app.kubernetes.io/instance: mywebapp-release
template:
metadata:
labels:
app.kubernetes.io/name: mywebapp
app.kubernetes.io/instance: mywebapp-release
spec:
serviceAccountName: mywebapp-release
securityContext:
{}
containers:
- name: mywebapp
securityContext:
{}
image: "nginx:1.16.0"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{}
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mywebapp,app.kubernetes.io/instance=mywebapp-release" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace default $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:$CONTAINER_PORT
Information About the Chart
# show all information of the chart
helm show all ./mywebapp
# show the chart's definition
helm show chart ./mywebapp
# show the chart's CRDs
helm show crds ./mywebapp
# show the chart's README
helm show readme ./mywebapp
# show the chart's values
helm show values ./mywebapp
You can show information for the fetched tgz packages like prometheus-24.3.0.tgz instead of ./mywebapp
Updating the Chart Values
Values in Helm charts allow you to customize the chart’s behavior during installation. You can specify values in a values.yaml file or override them using the --set flag during installation:
Using values.yaml
First you need to create a new yaml file to override the values.yaml file inside the package:
# custom-values.yaml
image:
tag: latest
Then use the -f flag to override the the default values.yaml file:
$ helm install mywebapp-release ./mywebapp -f custom-values.yaml --dry-run
...
containers:
- name: mywebapp
securityContext:
{}
image: "nginx:latest"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
...
Using --set flag
helm install mywebapp-release ./mywebapp --set image.tag=latest --set service.type=NodePort --dry-run
Install the Chart
You can install your chart into a Kubernetes cluster using the helm install command. For example:
helm install mywebapp-release ./mywebapp
Here, mywebapp-release is the name you give to the release, and ./mywebapp is the path to your chart directory.
Subcharts
Subcharts are a powerful feature that allows you to break down complex Kubernetes applications into smaller, manageable components. Subcharts, are Helm charts that are used as dependencies within other charts. They allow you to break down a larger application or service into smaller, more manageable pieces. Subcharts can be thought of as building blocks that can be combined to create more complex applications. you can read more about the subcharts on the offical docs.
Use Case
Consider an e-commerce application that includes multiple microservices, a database, and a message broker. You can create individual Helm charts for each microservice, the database, and the message broker. Then, you can create a parent chart for the entire e-commerce application that includes these subcharts as dependencies. This modular approach simplifies the deployment and management of the complex application.