Kubernetes Kubernetes Kubernetes is the new Docker Docker Docker

Remember way back in 2015 when all anybody would talk about was Docker even though nobody actually knew what it was or what to do with it? That’s where Kubernetes is right now. Before we get into Helm charts, a quick primer on Kubernetes is a good idea.

Kubernetes provides scheduling and management for your containerized applications as well as the networking and other necessary plumbing and surfaces its resources to the developer in the form of declarative manifests written in YAML or JSON.

A Pod is the smallest deployable unit that can be deployed with Kubernetes. It contains one or more collocated containers that share the same [internal] IP address. Generally a pod is just a single container, but if your application requires a sidecar container to share the same IP or a shared volume then you would declare multiple containers in the same pod.

A Pod is unmanaged and will not be recreated if the process inside the container ends. Kubernetes has a number of resources that build upon a pod to provide different types of lifecycle management such as a Deployment that will ensure the correct number of replicas of your Pod are running.

A Service provides a stable name, IP address, and DNS (if KubeDNS is enabled) across a number of pods and acts as a basic load balancer. This allows pods to easily communicate to each other and can
also provide a way for Kubernetes to expose your pod externally.

Helm is a Package Manager for Kubernetes. It doesn’t package the containers (or Pods) directly but instead packages the kubernetes manifests used to build those Pods. It also provides a templating engine that allows you to deploy your application in a number of different scenarios and configurations.

[Helm] Charts are easy to create, version, share, and publish — so start using Helm and stop the copy-and-paste madness.
– https://helm.sh/

Let’s Build a Helm Chart!

In order to follow along with this tutorial you will need to install the following:

If you are on a Mac you should be able to use the following to install the necessary bits:

$ brew cask install minikube
$ brew install kubernetes-helm

If you already have a Kubernetes manifest its very easy to turn it into a Helm Chart that you can then iterate over and improve as you need to add more flexibility to it. In fact your first iteration of a Helm chart can be your existing manifests tied together with a simple Chart.yaml file.

You’ll see you now have two Kubernetes manifests saved. We can use these
to bootstrap our helm charts:

$ tree
└── templates
├── deployment.yaml
└── service.yaml

Explore the deployment.yaml file in a text editor. Following is an abbreviated version of it with comments to help you understand what some of the sections mean:

# These first two lines appear in every Kubernetes manifest and provide
# a way to declare the type of resource and the version of the API to
# interact with.
apiVersion: apps/v1beta1
kind: Deployment
# under metadata you set the resource's name and can assign labels to it
# these labels can be used to tie resources together. In the service.yaml
# file you'll see it refers back to this `run: example` label.
metadata:
labels:
run: example
name: example
# how many replicas of the declared pod should I run ?
spec:
replicas: 1
selector:
matchLabels:
run: example
# the Pod that the Deployment will manage the lifecycle of.
# You can see once again the use of the label and the containers
# to run as part of the pod.
template:
metadata:
labels:
run: example
spec:
containers:
- image: nginx:alpine
imagePullPolicy: IfNotPresent
name: example

Explore the service.yaml file in a text editor. Following is an abbreviated version of it:

apiVersion: v1
kind: Service
metadata:
labels:
run: example
name: example
spec:
# The clusterIP is the IP address that other nodes can use to access the pods
# Since we didn't specify and IP Kubernetes picked one for us.
clusterIP: 10.0.0.62
# The Port mappings for the service.
ports:
- nodePort: 32587
port: 80
protocol: TCP
targetPort: 80
# Any pods that have this label will be exposed by this service.
selector:
run: example
# All Kubernetes worker nodes will expose this service to the outside world
# on the port specified above as `nodePort`.
type: NodePort

Delete the resources you just created so that you can move on to creating the Helm Chart:

Congratulations! You’ve just created and deployed your first Helm chart. However its a little bit basic, the next step is to add some templating to the manifests and update the deployment.

Add variables to your Helm Chart

In order to render templates you need a set of variables. Helm charts can come with a values.yaml file which declares a set of variables and their default values that can be used in your templates. Create a values.yaml file that looks like this:

replicaCount: 2
image: "nginx:alpine"

These values can be accessed in the templates using the golang templating
engine. For example the value replicaCount would be written as {{ .Values.replicaCount }}.
Helm also provides information about the Chart and Release that can be handy to utilize.

Summary

Congratulations you have deployed a Kubernetes cluster on your laptop using minikube and deployed a basic application to Kubernetes by creating a Deployment and a Service. You have also built your very first Helm chart and used the Helm templating engine to deploy different versions of the application.

Helm is a very powerful way to package up your Kubernetes manifests to make them
extensible and portable. While it is quite complicated its fairly easy to get started
with it and if you’re like me you’ll find yourself replacing the Kubernetes manifests
in your code repos with Helm Charts.

There’s a lot more you can do with Helm, we’ve just scratched the surface. Enjoy
using and learning more about them!