The last part is maybe the most important part: automation!
This is actually quite easy thanks to Kubernetes. In this post I’ll cover:
- Updating an image
- Removing everything
Updating an image
In the good old days (and still today), an update of an application is done by deploying new files to the webserver. To maintain strong versioning in most cases full sites are deployed when actually only a single file was changed. The downside of all of this is that the deployments are heavy, contains lots of files and often involves some processing before the actual deployment begins. For example, to prevent orphaned configurations or assemblies, all configurations and assemblies are removed first before a new deployment starts. Deployments are just no fun, it’s hard working and is hard to automate.
However, the idea is correct, always deploy a full version of an application. Kubernetes is taking the same idea but it’s using a single image instead of 25.000 files. And because we are dealing with images we do not need to process all these files. An update within Kubernetes is done by changing a deployment file or by telling Kubernetes that a container in a pod must use an other image of tag.
As read from the Kubernetes site:
A Deployment’s rollout is triggered if and only if the Deployment’s pod template (that is,
.spec.template) is changed.
So, we can change our deployment using the CLI:
kubectl set image deployment/kubernetes-web-deployment container-kubernetes-web=kubernetes.web:2.0.0 --namespace=kubernetes-demo
In this example we tell Kubernetes that the container-kubernetes-web container in the kubernetes-web-deployment deployment in the kubernetes-demo namespace must use another tag for the image kubernetes.web (which is using 1.0.0 at the moment)
Now, we can run the set image command:
Now, something interesting is happening. For our setup, we are using only 6 pods (2 pods per app/api). Kubernetes is setup to only replace pods if a new pod is operational. So, in our case a new pod is created first before the existing pod is updated(replaced). This can be seen in the Kubernetes dashboard where you’ll see 7 pods for a few seconds. When the new pod is running, the old pods will be removed and be replaced by new pods with the new image. No downtime! All managed by Kubernetes.
In this are there is still lots to learn and there is quite some interesting stuff to learn. Think about auto-scaler where it is possible to scale pods horizontally when the load is above 80% using a minimum of 10 pods with a maximum of 20 pods. Sounds cool huh!
And there are of course several types of deployment strategies which can be used to update the containers:
- Rolling update
- Blue green
Recreate is the most basic strategy. Using this strategy will stop all running containers using this image and recreate the image.
Rolling update, this is done in our example, a new pod will be created and other pods will follow after. So this is just a normal update. It starts and rolls out the update one after the other.
Blue Green deployment is done by setting up a full new temporary environment, so all Pods are duplicated using the new version. When all Pods are ready, the service is updated and will point to the new version.
Canary deployment is actually using multiple active sets of Pods. Based upon the results of the new version it is possible to ramp up the number of new Pods and scale down the number of Pods using the older version. This is mostly done when testing new features which are tested by a subset of users only.
Rollback to a previous version is just as easy a defining a new version. Because every state of the deployments are registered, rollback is just using the image of the previous version:
kubectl rollout undo deployment/kubernetes-web-deployment --namespace=kubernetes-demo
This will simply put back the previous version of the deployment, all done in seconds! Of course it is possible to rollback to a certain revision too. I still have to find out how 😉
More information about rolling back can be found here:
Removing everything is done by removing resources by namespace:
kubectl delete --namespace="kubernetes-demo"
This will clean up everything we’ve done so far 😉
It is also possible to delete resources defined in manifest files:
kubectl delete -f deployment_kubernetes_profile.yaml
This will remove all pods defined in this file, which is the profile-api in this case.