It is important to note that, not having a specific tag for a Docker image makes deployment rollback hard. In this example we are going to tag our Docker images every time we have a new update in our application, push it to Docker Hub and deploy it to Kubernetes.


Tagging the image


Assume that you updated your application. Let's build, tag and push it to Docker Hub.


IMAGE_TAG := $(shell git rev-parse --short HEAD)

.PHONY: docker
docker:
docker build -t you/address-finder-go:$(IMAGE_TAG) -f ./docker/go/Dockerfile .
docker push you/address-finder-go:$(IMAGE_TAG)

As you can see above, we have used the latest Git commit hash as image tag. You could use version tags such as v1.0.0 so on from GitHub releases. We should see a terminal output looks like below.


Successfully built 11416713s43z
Successfully tagged you/address-finder-go:v225062
docker push you/address-finder-go:v225062
The push refers to repository [docker.io/you/address-finder-go]
dd6dc1v214r2: Pushed

Deployment


Our deployment file looks like below. As you can see, we have the image tag set to latest but don't worry about it for now. It will be overridden when we deploy it with the following command. You can get rid of latest if it confuses you.


apiVersion: apps/v1
kind: Deployment

metadata:
name: address-finder-deployment
labels:
app: address-finder

spec:
replicas: 1
selector:
matchLabels:
app: address-finder
template:
metadata:
labels:
app: address-finder
spec:
containers:
- name: go
image: you/address-finder-go:latest

IMAGE_TAG := $(shell git rev-parse --short HEAD)

.PHONY: k8s-setup
k8s-setup:
kubectl apply -f deploy/k8s/configmap.yaml
kubectl apply -f deploy/k8s/deployment.yaml
kubectl apply -f deploy/k8s/service.yaml

.PHONY: k8s-deploy
k8s-deploy:
kubectl apply -f deploy/k8s/configmap.yaml
kubectl set image deployment/address-finder-deployment go=you/address-finder-go:$(IMAGE_TAG)
kubectl apply -f deploy/k8s/service.yaml

You can replace kubectl set image command with the one below which does the same thing.


kubectl patch deployment address-finder-deployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"go","image":"you/address-finder-go:$(IMAGE_TAG)"}]}}}}'

Let's setup our Kubernetes environment. This is necessary as the very first time application setup process. It will use the latest image tag.


$ make k8s-setup
kubectl apply -f deploy/k8s/configmap.yaml
configmap/address-finder-config created
kubectl apply -f deploy/k8s/deployment.yaml
deployment.apps/address-finder-deployment created
kubectl apply -f deploy/k8s/service.yaml
service/address-finder-service created

Let's check what image tag attached to the components. As seen it is the latest.


$ kubectl describe deployment.apps/address-finder-deployment | grep Image
Image: you/address-finder-go:latest

$ kubectl describe replicaset.apps/address-finder-deployment-68dd5b79b8 | grep Image
Image: you/address-finder-go:latest

$ kubectl describe pod/address-finder-deployment-68dd5b79b8-24ppp | grep Image
Image: you/address-finder-go:latest

We already know that our image is tagged with v225062 in Docker Hub. It is also the latest commit hash of our app so let's deploy it.


$ make k8s-deploy
kubectl apply -f deploy/k8s/configmap.yaml
configmap/address-finder-config unchanged
kubectl set image deployment/address-finder-deployment go=you/address-finder-go:v225062
deployment.apps/address-finder-deployment image updated
kubectl apply -f deploy/k8s/service.yaml
service/address-finder-service unchanged

Let's confirm the changes.


$ kubectl describe deployment.apps/address-finder-deployment | grep Image
Image: you/address-finder-go:v225062

$ kubectl describe replicaset.apps/address-finder-deployment-7887d5f54f | grep Image
Image: you/address-finder-go:v225062

$ kubectl describe pod/address-finder-deployment-7887d5f54f-phnf7 | grep Image
Image: you/address-finder-go:v225062