Helm
A popular method of deploying applications or cluster components on Kubernetes is through the use of templating tools like Helm. These tools allow users to specify all of the components of an application meant to run on Kubernetes in a series of templated YAML files. Tools like Helm take these templated YAML files, populate them with user-defined values, and deploy all of those resources together.
Helm takes the concept of an application package and applies it to Kubernetes. The application’s resource templates are grouped into packages known as charts. Charts include all of the YAML templates that represent Kubernetes resources deployed by Helm and supporting components like metadata, information on dependencies, custom resource definitions, and tests to be run.
Deploying an application with helm is straightforward. First, identify a chart that you want to install. Common chart repositories include artifacthub.io, which in provides as a central space to find charts.
Once you have identified a chart, you need to add that chart as a source to your Helm instance:
$ helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
After adding the chart repository to helm, your helm command can now search and install charts from the selected repository.
If you want to install, say, an NGINX web server using helm from the recently added repository, you use helm’s install command to generate a release of that chart. The release is the grouping of Kubernetes resources generated from the template in the chart. The resources are populated with values provided by the user (using the --set flag or providing a yaml file with values) or the default values of provided by the chart during the installation:
$ helm install self-study-nginx bitnami/nginx
NAME: self-study-nginx
LAST DEPLOYED: Tue Apr 19 19:20:14 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 10.1.1
APP VERSION: 1.21.6
** Please be patient while the chart is being deployed **
NGINX can be accessed through the following DNS name from within your cluster:
self-study-nginx.default.svc.cluster.local (port 80)
To access NGINX from outside the cluster, follow the steps below:
1. Get the NGINX URL by running these commands:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
Watch the status with: 'kubectl get svc --namespace default -w self-study-nginx'
export SERVICE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].port}" services self-study-nginx)
export SERVICE_IP=$(kubectl get svc --namespace default self-study-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "http://${SERVICE_IP}:${SERVICE_PORT}"
You can easily identify the resources generated by Helm because every resource bears the name of its release once deployed to the cluster:
$ kubectl get all --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod/self-study-nginx-7ccd4b56d9-q29bb 1/1 Running 0 73s app.kubernetes.io/instance=self-study-nginx,app.kubernetes.io/managed-by=Helm,app.kubernetes.io/name=nginx,helm.sh/chart=nginx-10.1.1,pod-template-hash=7ccd4b56d9
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
service/kubernetes ClusterIP 10.96.0.1 443/TCP 19h component=apiserver,provider=kubernetes
service/self-study-nginx LoadBalancer 10.99.49.207 80:30959/TCP 73s app.kubernetes.io/instance=self-study-nginx,app.kubernetes.io/managed-by=Helm,app.kubernetes.io/name=nginx,helm.sh/chart=nginx-10.1.1
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/self-study-nginx 1/1 1 1 73s app.kubernetes.io/instance=self-study-nginx,app.kubernetes.io/managed-by=Helm,app.kubernetes.io/name=nginx,helm.sh/chart=nginx-10.1.1
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/self-study-nginx-7ccd4b56d9 1 1 1 73s app.kubernetes.io/instance=self-study-nginx,app.kubernetes.io/managed-by=Helm,app.kubernetes.io/name=nginx,helm.sh/chart=nginx-10.1.1,pod-template-hash=7ccd4b56d9
Once a release is generated, you can change the parameters by changing values (again using the --set or providing an updated values yaml file) and using Helm’s upgrade subcommand:
$ helm upgrade self-study-nginx --set service.type=NodePort bitnami/nginx
Release "self-study-nginx" has been upgraded. Happy Helming!
NAME: self-study-nginx
LAST DEPLOYED: Tue Apr 19 19:24:14 2022
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 10.1.1
APP VERSION: 1.21.6
** Please be patient while the chart is being deployed **
NGINX can be accessed through the following DNS name from within your cluster:
self-study-nginx.default.svc.cluster.local (port 80)
To access NGINX from outside the cluster, follow the steps below:
1. Get the NGINX URL by running these commands:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services self-study-nginx)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo "http://${NODE_IP}:${NODE_PORT}"
The releases themselves are managed directly by Helm, and can be uninstalled using Helm’s uninstall command:
$ helm uninstall self-study-nginx
release "self-study-nginx" uninstalled
$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 443/TCP 19h
Learn more about the Helm package manager and its use.
Kustomize
Kustomize is a standalone tool to customize Kubernetes objects through a kustomization file. Since 1.14, kubectl also supports the management of Kubernetes objects using a kustomization file. To view resources found in a directory containing a kustomization file, run the following command: kubectl kustomize <kustomization_directory>
To apply those resources, run kubectl apply with --kustomize or -k flag: kubectl apply -k <kustomization_directory>
Kustomize features include:
- Generating resources from other resources
- Setting cross-cutting fields for groups of resources
- Composing and customizing collections of resources
Imagine we want to update our project to include standard project labels and other features. We can create a kustomization.yaml file something like this:
namespace: my-namespace
namePrefix: dev-
nameSuffix: "-001"
labels:
- pairs:
app: bingo
includeSelectors: true
commonAnnotations:
oncallPager: 800-555-1212
resources:
- deployment.yaml
An example deployment that would be modified by this kustomization:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app
This will add prefixes and suffixes to all of our project files. Build the project:
$ kubectl kustomize ./
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
name: dev-my-app-001
namespace: my-namespace
spec:
selector:
matchLabels:
app: bingo
template:
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
spec:
containers:
- image: my-app
name: app
Kustomize provides similar features to helm but in a lighter weight solution. Both have their advantages and shortcomings.