12.1. Write a Deployment#
The pod is Kubernetes’ fundamental unit of work. Your Django site is deployed as a pod definition. However, in practice pods are never deployed directly. They’re deployed using another workload resource like a Deployment
or StatefulSet
. In this lab you’ll convert your Pod
to a Deployment
.
The Deployment Resource#
A deployment is a template for making pods. Deployments manage a set of pods called a ReplicaSet
. The number of pods is controllable by an option in the deployment which can be edited at any time. This gives you the power to quickly scale up your application when the need arises. Deployments are like services in that they have a selector
that helps them identify the pods that belong to the deployment. The corresponding pods must have a matching label.
Here’s an example deployment. Save this file to deployment/deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Apply it like this:
$ kubectl apply -f deployment.yaml
Now look at the running pods:
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-6b474476c4-4zjxt 1/1 Running 0 39s
pod/nginx-deployment-6b474476c4-62fb8 1/1 Running 0 39s
pod/nginx-deployment-6b474476c4-jmpkj 1/1 Running 0 39s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2m30s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 3/3 3 3 39s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-6b474476c4 3 3 3 39s
Wow! Three copies!
Scale Up!#
Now let’s scale up our deployment. We can edit the resource directly in Kubernetes like this:
Note
This brings up the default editor, for me it’s vi
$ kubectl edit deployment.apps/nginx-deployment
Under spec
change the replicas
to 10
, save and exit. Now let’s look at our cluster:
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-6b474476c4-27l26 1/1 Running 0 3s
pod/nginx-deployment-6b474476c4-4zjxt 1/1 Running 0 3m50s
pod/nginx-deployment-6b474476c4-62fb8 1/1 Running 0 3m50s
pod/nginx-deployment-6b474476c4-fj76s 0/1 ContainerCreating 0 3s
pod/nginx-deployment-6b474476c4-g7h5v 0/1 ContainerCreating 0 3s
pod/nginx-deployment-6b474476c4-gqmlj 0/1 ContainerCreating 0 3s
pod/nginx-deployment-6b474476c4-jmpkj 1/1 Running 0 3m50s
pod/nginx-deployment-6b474476c4-nqf65 0/1 ContainerCreating 0 3s
pod/nginx-deployment-6b474476c4-rthvl 0/1 ContainerCreating 0 3s
pod/nginx-deployment-6b474476c4-t4ljj 0/1 ContainerCreating 0 3s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5m41s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 4/10 10 4 3m50s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-6b474476c4 10 10 4 3m50s
Boom!
Now Scale Down#
Now let’s scale down to save money. Repeat the steps from the previous section but set the replicas to 1
.
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-6b474476c4-27l26 1/1 Terminating 0 101s
pod/nginx-deployment-6b474476c4-4zjxt 1/1 Terminating 0 5m28s
pod/nginx-deployment-6b474476c4-62fb8 1/1 Running 0 5m28s
pod/nginx-deployment-6b474476c4-fj76s 1/1 Terminating 0 101s
pod/nginx-deployment-6b474476c4-g7h5v 1/1 Terminating 0 101s
pod/nginx-deployment-6b474476c4-gqmlj 1/1 Terminating 0 101s
pod/nginx-deployment-6b474476c4-jmpkj 1/1 Terminating 0 5m28s
pod/nginx-deployment-6b474476c4-nqf65 1/1 Terminating 0 101s
pod/nginx-deployment-6b474476c4-rthvl 1/1 Terminating 0 101s
pod/nginx-deployment-6b474476c4-t4ljj 1/1 Terminating 0 101s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7m19s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 1/1 1 1 5m28s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-6b474476c4 1 1 1 5m28s
It’s also possible to zero-scale. That’s when you have the pod ready but none deployed.
Rolling Update#
Deployments make it possible to do rolling updates when a new version of the container is available. To perform a rolling update run the command:
$ kubectl rollout restart deployment.apps/nginx-deployment
Let’s watch the rollout:
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-6b474476c4-62fb8 1/1 Terminating 0 7m56s
pod/nginx-deployment-6d9955664c-w5nr7 1/1 Running 0 2s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m47s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 1/1 1 1 7m56s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-6b474476c4 0 0 0 7m56s
replicaset.apps/nginx-deployment-6d9955664c 1 1 1 2s
A rolling update ensures that there are always the desired number of pods during a rollout. Your application updates seamlessly.
Cleanup#
You can delete all of the workload resources, including the ReplicaSet
s by deleting the deployment:
$ kubectl delete deployment.apps/nginx-deployment