Kubernetes/Kubernetes Workshop/Step 7

From Wikitech

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