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 ReplicaSets by deleting the deployment:

$ kubectl delete deployment.apps/nginx-deployment