Our website is now running and we can access it, however it is running in a single pod. That means that if it fails, our website will be down. To prevent this, we need to introduce some self-healing and scaling, and that’s why we’ll create a Deployment.
Working with Deployments
Before we create a Deployment, let’s have a look what happens when we delete our single pod:
katarinabrookfield@KatsMac hugo-site % kubectl get pod hugo-site-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hugo-site-pod 1/1 Running 0 27h 10.2.0.15 lke27049-39949-60a531334464 <none> <none>
katarinabrookfield@KatsMac hugo-site % kubectl delete pod hugo-site-pod
pod "hugo-site-pod" deleted
katarinabrookfield@KatsMac hugo-site % kubectl get pod hugo-site-pod -o wide
Error from server (NotFound): pods "hugo-site-pod" not found
katarinabrookfield@KatsMac hugo-site % kubectl get pod hugo-site-pod -o wide
Error from server (NotFound): pods "hugo-site-pod" not found
As you can see, our pod is not coming back, and neither is our website, so we need to deploy it again:
katarinabrookfield@KatsMac hugo-site % kubectl apply -f pod.yml
pod/hugo-site-pod created
katarinabrookfield@KatsMac hugo-site % kubectl get pod hugo-site-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hugo-site-pod 1/1 Running 0 5s 10.2.0.16 lke27049-39949-60a531334464 <none> <none>
Adding self-healing
Create a file called deployment.yml:
katarinabrookfield@KatsMac hugo-site % vi deployment.yml
Enter the following info into the deployment.yml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hugo-deployment
spec:
replicas: 1
selector:
matchLabels:
project: hugo-site
template:
metadata:
labels:
project: hugo-site
spec:
containers:
- name: hugo-pod
imagePullPolicy: Always
ports:
- containerPort: 8080
image: katbrookfield/hugo-site
Deploy the Deployment
Run the following command to deploy the deployment:
katarinabrookfield@KatsMac hugo-site % kubectl apply -f deployment.yml
deployment.apps/hugo-site-deployment created
katarinabrookfield@KatsMac hugo-site % kubectl get pod | grep hugo
hugo-site-deployment-74c977df86-9zvgs 1/1 Running 0 72s
hugo-site-pod 1/1 Running 0 44m
As you can see, now we have two pods running; one from the previous example, and one from the deployment. We will now delete both of them and wait to see if the pod will be recreated:
katarinabrookfield@KatsMac hugo-site % kubectl delete pod hugo-site-deployment-74c977df86-9zvgs
pod "hugo-site-deployment-74c977df86-9zvgs" deleted
katarinabrookfield@KatsMac hugo-site % kubectl delete pod hugo-site-pod
pod "hugo-site-pod" deleted
katarinabrookfield@KatsMac hugo-site % kubectl get pod | grep hugo
hugo-site-deployment-74c977df86-z8hd2 1/1 Running 0 32s
New pod has been deployed automatically and our website is reachable again!
Scale the app
Another thing we can do with deployments is to scale our app by adding or removing replicas.
As with other commands, there are imperative commands to scale the application but I will stick to declarative and update the YAML definition file. This is mainly to avoid any confusion further down the line but also seems to be the best practice.
To update the file, open the deployment.yml file again:
katarinabrookfield@KatsMac hugo-site % vi deployment.yml
Change number of replicas, I have 3 nodes so I will change this to 3 replicas for now:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hugo-site-deployment
spec:
replicas: 3
selector:
matchLabels:
project: hugo-site
template:
metadata:
labels:
project: hugo-site
spec:
containers:
- name: hugo-pod
imagePullPolicy: Always
ports:
- containerPort: 8080
image: katbrookfield/hugo-site
If we deploy the deployment again, we will see the 2 new pods being created:
katarinabrookfield@KatsMac hugo-site % kubectl apply -f deployment.yml
deployment.apps/hugo-site-deployment configured
katarinabrookfield@KatsMac hugo-site % kubectl get pod | grep hugo
hugo-site-deployment-74c977df86-b8r9x 0/1 ContainerCreating 0 3s
hugo-site-deployment-74c977df86-mpfgn 0/1 ContainerCreating 0 3s
hugo-site-deployment-74c977df86-z8hd2 1/1 Running 0 59m
Bonus: Where are my pods?
In the previous section, I said I wanted to have 3 replicas to have them distributed over 3 nodes of my cluster. Looking at where they run, I could see they were actually deployed on 2 nodes only:
katarinabrookfield@KatsMac hugo-site % kubectl get pod -o wide | grep hugo
hugo-site-deployment-74c977df86-8xhgl 1/1 Running 0 2m37s 10.2.0.24 lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-b8kv7 1/1 Running 0 2m37s 10.2.1.32 lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-cs4qd 1/1 Running 0 2m37s 10.2.0.25 lke27049-39949-60a531334464 <none> <none>
So I tried to change it to 5 replicas:
katarinabrookfield@KatsMac hugo-site % vi deployment.yml
katarinabrookfield@KatsMac hugo-site % kubectl get pod -o wide | grep hugo
hugo-site-deployment-74c977df86-7nlf2 1/1 Running 0 22s 10.2.0.26 lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-8xhgl 1/1 Running 0 8m32s 10.2.0.24 lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-b8kv7 1/1 Running 0 8m32s 10.2.1.32 lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-cs4qd 1/1 Running 0 8m32s 10.2.0.25 lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-xq92b 1/1 Running 0 22s 10.2.1.33 lke27049-39949-60a53133d7b2 <none> <none>
and then 10…
katarinabrookfield@KatsMac hugo-site % kubectl apply -f deployment.yml
deployment.apps/hugo-site-deployment configured
katarinabrookfield@KatsMac hugo-site % kubectl get pod -o wide | grep hugo
hugo-site-deployment-74c977df86-7nlf2 1/1 Running 0 28s 10.2.0.26 lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-8xhgl 1/1 Running 0 8m38s 10.2.0.24 lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-b8kv7 1/1 Running 0 8m38s 10.2.1.32 lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-bkwqz 0/1 ContainerCreating 0 2s <none> lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-cs4qd 1/1 Running 0 8m38s 10.2.0.25 lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-flhn8 0/1 ContainerCreating 0 2s <none> lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-flv7l 0/1 ContainerCreating 0 2s <none> lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-q2qdg 0/1 ContainerCreating 0 2s <none> lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-rz5p7 0/1 ContainerCreating 0 2s <none> lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-xq92b 1/1 Running 0 28s 10.2.1.33 lke27049-39949-60a53133d7b2 <none> <none>
And then 60… I think you know where I’m going with this. It still only deployed on those 2 nodes even though I have 3 nodes ready:
katarinabrookfield@KatsMac hugo-site % kubectl get nodes
NAME STATUS ROLES AGE VERSION
lke27049-39949-60a531334464 Ready <none> 21d v1.20.6
lke27049-39949-60a53133d7b2 Ready <none> 21d v1.20.6
lke27049-39949-60a53134727c Ready <none> 21d v1.20.6
So I powered off one of the hosts and the pods still stayed there but marked as completed:
katarinabrookfield@KatsMac hugo-site % kubectl get nodes
NAME STATUS ROLES AGE VERSION
lke27049-39949-60a531334464 NotReady <none> 21d v1.20.6
lke27049-39949-60a53133d7b2 Ready <none> 21d v1.20.6
lke27049-39949-60a53134727c Ready <none> 21d v1.20.6
katarinabrookfield@KatsMac hugo-site % kubectl get pod -o wide | grep hugo
hugo-site-deployment-74c977df86-m9jq8 0/1 Completed 0 63m <none> lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-qmpwk 1/1 Running 0 63m 10.2.1.62 lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-znfcl 0/1 Completed 0 63m <none> lke27049-39949-60a531334464 <none> <none>
Next I changed the number of replicas to 5 and it still deployed only on the second node??
katarinabrookfield@KatsMac hugo-site % kubectl get pod -o wide | grep hugo
hugo-site-deployment-74c977df86-6zpv6 1/1 Running 0 24s 10.2.1.63 lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-m9jq8 0/1 Completed 0 65m <none> lke27049-39949-60a531334464 <none> <none>
hugo-site-deployment-74c977df86-qmpwk 1/1 Running 0 65m 10.2.1.62 lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-rss7f 1/1 Running 0 24s 10.2.1.64 lke27049-39949-60a53133d7b2 <none> <none>
hugo-site-deployment-74c977df86-znfcl 0/1 Completed 0 65m <none> lke27049-39949-60a531334464 <none> <none>
I think we’ll leave it here now and look at some restart policies next.