Kubernetes/Kubernetes Workshop/Step 7
Step 7: Packages
“helm” is a popular package manager for kubernetes. It supports operations similar to other package managers such as “apt” or “npm”. Packages group files together into deployable group. The helm package manager can install packages, delete them, upgrade and downgrade them, plus it maintains a history of releases.
Let’s try it out on our applications.
So far, we have not used versioning in the creation of our docker images. Instead we have relied on the “latest” tag which is provided automatically to the most recent build (see Step 2). To use versions we have to add an additional tag in docker.
Hands-on: tag different builds of the simpleapache application
In the directory for simpleapache, make a change in the HTML (Hello to Hi) in the Dockerfile:
FROM ubuntu
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y apache2
RUN echo '<HTML><BODY>Hi World</BODY></HTML' >/var/www/html/index.html
EXPOSE 80
CMD ["apachectl","-DFOREGROUND"]
docker build . builds the image
docker images lists images - the new image should be the first listed with a REPOSITORY of <none> and TAG <none>. Copy the ID of that image and tag it with “1.0”. USER is your login name for dockerhub.
docker tag <ID> <userid>/simpleapache:1.0
docker images to verify
Let’s check on the current state of image on docker hub. Go to: https://hub.docker.com/repository/docker/<userid>/simpleapache and check what the state of the image is. You should see a tag of latest...
docker push <userid>/simpleapache:1.0 to upload
Check again on docker hub. Now you should see the 1.0 as well.
Let’s make another change in the HTML from Hi to Hey, build it, tag it as 1.1 and push to the hub.
When small changes like that are pushed you can see how the docker layering works in the output of the “docker push” command. Since we only change the HTML in one file, a push is fairly quick, as the majority of the image is unchanged.
Check again on docker hub. Now you should see both 1.0 and 1.1.
We can now run these different versions of simpleapache by changing the image used in the deployment.
Here is a deployment YAML file for 1.0, simpleapachedeployment.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: simpleapache labels: app: simpleapache spec: replicas: 1 strategy: type: RollingUpdate selector: matchLabels: app: simpleapache template: metadata: labels: app: simpleapache spec: containers: - name: simpleapache image: <userid>/simpleapache:1.0 imagePullPolicy: Always
And the YAML for the service- simpleapacheservice.yaml:
kind: Service apiVersion: v1 metadata: name: simpleapache spec: selector: app: simpleapache type: LoadBalancer ports: - protocol: TCP port: 80 targetPort: 80
Let’s deploy the application:
kubectl apply -f simpleapachedeployment.yaml
kubectl get pods
kubectl apply -f simpleapacheservice.yaml
kubectl get svc
minikube service list
curl to the URL (i.e. IP:port) listed to verify
Change to version 1.1 by editing the deployment file and rerun:
kubectl apply -f simpleapachedeployment.yaml
curl to the URL (i.e. IP:port) listed to verify
It should output Hey World now
Delete the application by:
kubectl delete service simpleapache
kubectl delete deployment simpleapache
Ok let’s see how helm can help us to make this process easier…
Hands-on: helm for simpleapache
Install helm - the current version is v3, which does not require the tiller component anymore.
Download (it is a single binary) and put in path
See: https://helm.sh/docs/intro/install/
Start using a helm “chart” - which is simply a directory with the files helm needs to operate. We will start simple and just use the “simpleapache” directory where the Dockerfile and the YAML files are and work in there. The “correct” way is to use the helm create command which will create all directories needed and provide some defaults, but that is way more complicated than what we want to look at right now.
In the “simpleapache” directory we need a “Chart.yaml” file that contains the basic description of the application. Here is a simple starter file.
Chart.yaml:
name: simpleapache
version: 1.0.0
description: a simple web server
maintainers:
- name: A. Maintainer
email: simpleapache@example.com
In addition we need a “templates” directory that will contain the YAML files for the package
mkdir templates; cp ../simplepache*.yaml templates
cd ..
Here is what the simpleapache directory should look like (non relevant files not listed, i.e Dockerfile and the original yaml files for deployment and service.)
simpleapache
├── Chart.yaml
└── templates
├── simpleapachedeployment.yaml
└── simpleapacheservice.yaml
We can now deploy the app with helm and test it - myname is the name of the release and can be anything you want:
cd ..
helm install myname simpleapache/
kubectl get pods
minikube service list
curl to test
Useful helm commands
helm list - lists releases
helm status <release> - <release> = typically the name given (myname in the example)
helm history <release>
helm delete <release>
Delete the application with helm delete <release>
helm has the capability to modify the YAML files using simple substitutions. Let’s use that capability to be able to deploy version 1.0 and version 1.1 of our application via helm.
Create a values.yaml file in the helmfiles directory with ‘versiontag: “1.0”’ in it. That defines a “versiontag” variable that can be used in the YAML field in the templates directory. Edit the simpleapachedeployment.yaml file and change the “image” line to:
image: <userid>/simpleapache:Template:.Values.versiontag
Template:.Values.versiontag is the way to reference the variable created. Before there was a hardcoded “latest” in that line.
You should now be able to deploy the application again:
helm install myname simpleapache/
minikube service list
curl…
But we can now use helm to upgrade the version to 1.1:
helm upgrade myname simpleapache/ --set versiontag="1.1" --description=”1.1 upgrade”
Note that description can be anything. It should explain what you are doing, but is not enforced in any way.
curl... to check
And back to 1.0:
helm upgrade myname simpleapache/ --set versiontag="1.0" --description=”1.0 downgrade”
curl... to check
helm history myname
Let’s add a second variable to the YAML file, to be able to scale the number of replicas
add a line with howmanyreplicas: 1 in values.yaml
change the line referencing replicas in templates/simpleapachedeployment.yaml to read
Replicas: Template:.Values.howmanyreplicas
helm upgrade myname simpleapache/ --set howmanyreplicas=3 --description=”replicas to 3”
kubectl get pods
Try this. Note the typo.
helm upgrade myname simpleapache/ --set howmanyreplica=4 --description=”replicas to 4”
kubectl get pods
Lastly use “helm create” to create a chart and browse through the files provided to get an idea of some of the additional functionality.
appVersion in Chart.yaml might be an interesting variable to populate in conjunction with an automated deployment system, for example.
Hands-on: helm on the bookapp
TBD