Kubernetes Controllers - The Kubernetes Workshop

Download as pdf or txt
Download as pdf or txt
You are on page 1of 70

10/16/22, 8:59 AM 7.

Kubernetes Controllers | The Kubernetes Workshop

7. Kubernetes Controllers
Overview

This chapter introduces the concept of Kubernetes


controllers and explains how to use them to
create replicated Deployments. We will describe
the use of different types of controllers, such as
ReplicaSets, Deployments, DaemonSets,
StatefulSets, and Jobs. You will learn how to
choose a suitable controller for specific use cases.
Using hands-on exercises, we will guide you
through how to use these controllers with the
desired configuration to deploy several replicas of
Pods for your application. You will also learn how
to manage them using various commands.

Introduction
In previous chapters, we created different Pods,
managed their life cycle manually, and added
metadata (labels or annotations) to them to help
organize and identify various Pods. In this

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 1/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

chapter, we will take a look at a few Kubernetes


objects that help you manage several replica
Pods declaratively.

When deploying your application in production,


there are several reasons why you would want to
have more than one replica of your Pods. Having
more than one replica ensures that your
application continues to work in cases where
one or more Pods fail. In addition to handling
failures, replication also allows you to balance
the load across the different replicas so that one
Pod is not overloaded with a lot of requests,
thereby allowing you to easily serve higher
traffic than what a single Pod can serve.

Kubernetes supports different controllers that


you can use for replication, such as ReplicaSets,
Deployments, DaemonSets, StatefulSets, and
Jobs. A controller is an object that ensures that
your application runs in the desired state for its
entire runtime. Each of these controllers is
useful for specific use cases. In this chapter, we
will explore some of the most commonly used

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 2/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

controllers one by one and understand how and


when to use them in real-life scenarios.

ReplicaSets
As discussed earlier, having multiple replicas of
our application ensures that it is still available
even if a few replicas fail. This also makes it easy
for us to scale our application to balance the load
to serve more traffic. For example, if we are
building a web application that's exposed to
users, we'd want to have at least two replicas of
the application in case one of them fails or dies
unexpectedly. We would also want the failed
replica to recover on its own. In addition to that,
if our traffic starts growing, we would want to
increase the number of Pods (replicas) running
our application. A ReplicaSet is a Kubernetes
controller that keeps a certain number of Pods
running at any given time.

ReplicaSet acts as a supervisor for multiple Pods


across the different nodes in a Kubernetes
cluster. A ReplicaSet will terminate or start new
Pods to match the configuration specified in the
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 3/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

ReplicaSet template. For this reason, it is a good


idea to use them even if your application only
needs one Pod. Even if someone deletes the only
running Pod, the ReplicaSet will ensure that a
new Pod is created to replace it, thereby
ensuring that one Pod is always running.

A ReplicaSet can be used to reliably run a single


Pod indefinitely or to run multiple instances of
the same Pod.

ReplicaSet Configuration

Let's first look at an example of the configuration


of a ReplicaSet, and then we will cover what the
different fields mean:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
  labels:
    app: nginx
spec:
  replicas: 2
  selector:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 4/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

    matchLabels:
      environment: production
  template:
    metadata:
      labels:
        environment: production
    spec:
      containers:
      - name: nginx-container
        image: nginx
As with Pod configuration, a ReplicaSet also
needs fields such as apiVersion, kind, and
metadata. For a ReplicaSet, the API version,
apps/v1, is the current version and the kind
field will always be ReplicaSet. One field that
is different from what we have seen in Pod
configuration so far is the spec.

Now, we will see what information we need to


specify in the spec field.

Replicas

The replicas field under spec specifies how


many Pods the ReplicaSet should keep running

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 5/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

concurrently. You can see the following value in


the preceding example:

replicas: 2
The ReplicaSet will create or delete Pods in order
to match this number. The default value for this
field, if not specified, is 1.

Pod Template

In the template field, we will specify the


template of the Pod that we want to run using
this ReplicaSet. This Pod template will be exactly
the same as the Pod templates we used in the
previous two chapters. As usual, we can add
metadata in the form of labels and annotations
to the Pods. The ReplicaSet will use this Pod
template to create new Pods whenever there is a
need for them. The following section from the
previous example comprises the template:

template:
  metadata:
    labels:
      environment: production
  spec:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 6/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

    containers:
    - name: nginx-container
      image: nginx
Pod Selector

This is a really important section. In the


selector field under spec, we can specify the
label selectors that will be used by the ReplicaSet
to identify which Pods to manage:

selector:
  matchLabels:
    environment: production
The preceding example ensures that our
controller will only manage Pods with an
environment: production label.

Let's now proceed to create our first ReplicaSet.

Exercise 7.01: Creating a Simple


ReplicaSet with nginx Containers

In this exercise, we will create a simple


ReplicaSet and examine the Pods created by it.
To successfully complete this exercise, perform
the following steps:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 7/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

1. Create a file called replicaset-nginx.yaml


with the following content:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      environment: production
  template:
    metadata:
      labels:
        environment: production
    spec:
      containers:
      - name: nginx-container
        image: nginx
As you can see in the highlighted part of the
configuration, we have three fields: replicas,
selector, and template. We have set the

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 8/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

number of replicas to 2. The Pod selector has


been set in such a way that this ReplicaSet will
manage the Pods with the environment:
production label. The Pod template has the
simple Pod configuration that we used in
previous chapters. We have ensured that the
Pod label selector matches the Pod's labels in
the template exactly.
2. Run the following command to create the
ReplicaSet using the preceding configuration:
kubectl create -f replicaset-
nginx.yaml
You should see the following response:
replicaset.apps/nginx-replicaset
created
3. Verify that the ReplicaSet was created by using
the kubectl get command:
kubectl get rs nginx-replicaset
Note that rs is a short form of replicaset in
all kubectl commands.
You should see the following response:
NAME DESIRED CURRENT READY AGE
nginx-replicaset 2 2 2 30s

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 9/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

As you can see, we have a ReplicaSet with two


desired replicas, as we defined in
replicaset-nginx.yaml in step 1.
4. Verify that the Pods were actually created by
using the following command:
kubectl get pods
You should get the following response:
NAME READY STATUS RESTARTS AGE
nginx-replicaset-b8fwt 1/1
Running 0 51s
nginx-replicaset-k4h9r 1/1
Running 0 51s
We can see that the names of the Pods created
by the ReplicaSet take the name of the
ReplicaSet as a prefix.
5. Now that we have created our first ReplicaSet,
let's look at it in more detail to understand
what actually happened during its creation. To
do that, we can describe the ReplicaSet we just
created by using the following command in
the terminal:
kubectl describe rs nginx-
replicaset
You should see output similar to the following:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 10/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Figure 7.1: Describing nginx-replicaset


6. Next, we will inspect the Pods created by this
ReplicaSet and verify that they have been
created with the correct configuration. Run the
following command to get a list of the Pods
that are running:
kubectl get pods
You should see a response as follows:
NAME READY STATUS RESTARTS AGE
nginx-replicaset-b8fwt 1/1
Running 0 38m
nginx-replicaset-k4h9r 1/1
Running 0 38m
7. Run the following command to describe one of
the Pods by copying its name:
kubectl describe pod <pod_name>

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 11/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

You should see output similar to the following:

Figure 7.2: Listing Pods

In the highlighted sections of the preceding


output, we can clearly see that the pod has the
environment=production label and is
controlled by ReplicaSet/nginx-replicaset.

So, we have created a simple ReplicaSet in this


exercise. In the following subtopics, we will go
through the highlighted sections of the preceding
output to understand the ReplicaSet that's
running.

Labels on the ReplicaSet

Consider the following line from the output


shown in Figure 7.1:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 12/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Labels:       app=nginx
It shows that, as desired, the ReplicaSet was
created with a label key called app with a value
of nginx.

Selectors for the ReplicaSet

Now, consider the following line from the output


shown in Figure 7.1:

Selector:    
environment=production
This shows that the ReplicaSet is configured with
an environment=production Pod selector. This
means that this ReplicaSet will try to acquire
Pods that have this label.

Replicas

Consider the following line from the output


shown in Figure 7.1:

Replicas:     2 current / 2
desired
We can see that the ReplicaSet has the desired
count of 2 for the Pods, and it also shows that
there are currently two replicas present.
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 13/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Pods Status

While the Replicas field only shows the


number of Pods currently present, Pods Status
shows the actual status of those Pods:

Pods Status:  2 Running / 0


Waiting / 0 Succeeded / 0 Failed
We can see that there are currently two Pods
running under this ReplicaSet.

Pods Template

Now, let's consider the Pod Template section of


the output shown in Figure 7.1. We can see that
the Pod template is the same as was described in
the configuration.

Events

In the last section of the output shown in Figure


7.1, we can see that there are two events, which
denotes that two pods were created to get to the
desired count of two Pods for the ReplicaSet.

In the last exercise, we created a ReplicaSet to


maintain a number of running replicas. Now,

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 14/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

let's consider a scenario where some nodes or


Pods fail for some reason. We will see how the
ReplicaSet will behave in this situation.

Exercise 7.02: Deleting Pods


Managed by a ReplicaSet

In this exercise, we will delete one of the Pods


managed by a ReplicaSet to see how it responds.
This way, we will be simulating a single or
multiple Pods failing during the runtime of a
ReplicaSet:

Note

In this exercise, we will assume that you have


successfully completed the previous exercise as we
will be reusing the ReplicaSet created in
that exercise.

1. Verify that the Pods created by the ReplicaSet


are still running:
kubectl get pods
You should see something similar to the
following response:
NAME READY STATUS RESTARTS AGE

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 15/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

nginx-replicaset-9tgb9 1/1
Running 0 103s
nginx-replicaset-zdjb5 1/1
Running 0 103s
2. Delete the first Pod to replicate Pod failure
during runtime by using the
following command:
kubectl delete pod <pod_name>
You should see a response similar to the
following:
pod "nginx-replicaset-9tgb9"
deleted
3. Describe the ReplicaSet and check the events:
kubectl describe rs nginx-
replicaset
You should see output similar to the following:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 16/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Figure 7.3: Describing the ReplicaSet


As highlighted in the preceding output, we can
see that after a Pod is deleted, the ReplicaSet
creates a new Pod using the Pod configuration
in the Template section of the ReplicaSet
configuration. Even if we delete all the Pods
managed by the ReplicaSet, they will be
recreated. So, to delete all the Pods
permanently and to avoid the recreation of the
Pods, we need to delete the ReplicaSet itself.
4. Run the following command to delete the
ReplicaSet:
kubectl delete rs nginx-
replicaset
You should see the following response:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 17/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

replicaset.apps "nginx-
replicaset" deleted
As shown in the preceding output, the nginx-
replicaset ReplicaSet was deleted.
5. Run the following command to verify that the
Pods managed by the ReplicaSet were also
deleted:
kubectl get pods
You should get the following response:
No resources found in default
namespace
As you can see from this output, we can verify
that the Pods were deleted.

Consider a scenario where you have already


deployed a single Pod for testing. Now, it is ready
to go live. You apply the required label changes
from development to production, and now you
want to control this using a ReplicaSet. We will
see how to do this in the following exercise.

Exercise 7.03: Creating a ReplicaSet


Given That a Matching Pod Already
Exists

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 18/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

In this exercise, we will create a Pod that


matches the Pod template in the ReplicaSet and
then create the ReplicaSet. Our aim is to prove
that the newly created ReplicaSet will acquire
the existing Pod and start managing it as if it
created that Pod itself.

In order to successfully complete this exercise,


perform the following steps:

1. Create a file called pod-matching-


replicaset.yaml with the following content:
apiVersion: v1
kind: Pod
metadata:
  name: pod-matching-replicaset
  labels:
    environment: production
spec:
  containers:
  - name: first-container
    image: nginx
2. Run the following command to create the Pod
using the preceding configuration:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 19/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

kubectl create -f pod-matching-


replicaset.yaml
You should see the following response:
pod/pod-matching-replicaset
created
3. Create a file called replicaset-nginx.yaml
with the following content:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      environment: production
  template:
    metadata:
      labels:
        environment: production
    spec:
      containers:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 20/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

      - name: nginx-container


        image: nginx
4. Run the following command to create the
ReplicaSet using the preceding configuration:
kubectl create -f replicaset-
nginx.yaml
You should see a response similar to the
following:
replicaset.apps/nginx-replicaset
created
This output indicates that the Pod has been
created.
5. Run the following command to check the
status of the ReplicaSet:
kubectl get rs nginx-replicaset
You should get the following response:
NAME DESIRED CURRENT READY AGE
nginx-replicaset 2 2 2 2
We can see that there are currently two Pods
managed by the ReplicaSet, as desired.
6. Next, let's check what Pods are running by
using the following command:
kubectl get pods
You should see output similar to the following:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 21/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

NAME READY STATUS RESTARTS AGE


nginx-replicaset-4dr7s 1/1
Running 0 28s
pod-matching-replicaset 1/1
Running 0 81s
In this output, we can see that the manually
created Pod named pod-matching-
replicaset is still running and that there was
only one new Pod created by the nginx-
replicaset ReplicaSet.
7. Next, we will use the kubectl describe
command to check whether the Pod named
pod-matching-replicaset is being managed
by the ReplicaSet:
kubectl describe pod pod-
matching-replicaset
You should see output similar to the following:

Figure 7.4: Describing the Pod

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 22/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

In the highlighted section of the truncated


output, we can see that even though this Pod
was created manually before the ReplicaSet
event existed, this Pod is now managed by the
ReplicaSet itself.
8. Next, we will describe the ReplicaSet to see
how many Pod creations were triggered by it:
kubectl describe rs nginx-
replicaset
You should see output similar to the following:

Figure 7.5: Describing the ReplicaSet


9. Run the following command to delete the
ReplicaSet for cleanup:
kubectl delete rs nginx-
replicaset

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 23/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

You should see the following response:


replicaset.apps "nginx-
replicaset" deleted
So, we can see that a ReplicaSet is capable of
acquiring existing Pods as long as they match
the label selector criteria. In cases where there
are more matching Pods than the desired
count, the ReplicaSet will terminate some of
the Pods in order to maintain the total count of
running Pods.

Another common operation is horizontally


scaling a ReplicaSet that you previously created.
Let's say that you create a ReplicaSet with a
certain number of replicas and later you need to
have more or fewer replicas to manage
increased or decreased demand. Let's see how
you can scale the number of replicas in the next
exercise.

Exercise 7.04: Scaling a ReplicaSet


after It Is Created
In this exercise, we will create a ReplicaSet with
two replicas and then modify it to increase the

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 24/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

number of replicas. Then, we will reduce the


number of replicas.

In order to successfully complete this exercise,


perform the following steps:

1. Create a file called replicaset-nginx.yaml


with the following content:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      environment: production
  template:
    metadata:
      labels:
        environment: production
    spec:
      containers:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 25/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

      - name: nginx-container


        image: nginx
2. Run the following command to create the
ReplicaSet using the kubectl apply
command, as described in the preceding code:
kubectl apply -f replicaset-
nginx.yaml
You should get the following response:
replicaset.apps/nginx-replicaset
created
3. Run the following command to check all the
existing Pods:
kubectl get pods
You should get a response similar to the
following:
NAME READY STATUS RESTARTS AGE
nginx-replicaset-99tj7 1/1
Running 0 23s
nginx-replicaset-s4stt 1/1
Running 0 23s
We can see that there are two Pods created by
the replica set.
4. Run the following command to scale up the
number of replicas for the ReplicaSet to 4:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 26/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

kubectl scale --replicas=4 rs


nginx-replicaset
You should see the following response:
replicaset.apps/nginx-replicaset
scaled
5. Run the following command to check all the
Pods that are running:
kubectl get pods
You should see output similar to the following:
NAME READY STATUS RESTARTS AGE
nginx-replicaset-99tj7 1/1
Running 0 75s
nginx-replicaset-klh6k 1/1
Running 0 21s
nginx-replicaset-lrqsk 1/1
Running 0 21s
nginx-replicaset-s4stt 1/1
Running 0 75s
We can see that now there are a total of four
Pods. The ReplicaSet created two new Pods
after we applied the new configuration.
6. Next, let's run the following command to scale
down the number of replicas to 1:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 27/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

kubectl scale --replicas=1 rs


nginx-replicaset
You should see the following response:
replicaset.apps/nginx-replicaset
scaled
7. Run the following command to check all the
Pods that are running:
kubectl get pods
You should see a response similar to the
following:
nginx-replicaset-s4stt 1/1
Running 0 11m
We can see that this time, the ReplicaSet
deleted all the Pods exceeding the count from
the desired count of 1 and kept only one
replica running.
8. Run the following command to delete the
ReplicaSet for cleanup:
kubectl delete rs nginx-
replicaset
You should see the following response:
replicaset.apps "nginx-
replicaset" deleted

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 28/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

In this exercise, we have managed to scale the


number of replicas up and down. This could be
particularly useful if the traffic to your
application grows or decreases for any reason.

Deployment
A Deployment is a Kubernetes object that acts as
a wrapper around a ReplicaSet and makes it
easier to use. In general, in order to manage
replicated services, it's recommended that you
use Deployments that, in turn, manage the
ReplicaSet and the Pods created by the
ReplicaSet.

The major motivation for using a Deployment is


that it maintains a history of revisions. Every
time a change is made to the ReplicaSet or the
underlying Pods, a new revision of the
ReplicaSet is recorded by the Deployment. This
way, using a Deployment makes it easy to roll
back to a previous state or version. Keep in mind
that every rollback will also create a new
revision for the Deployment. The following
diagram provides an overview of the hierarchy
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 29/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

of the different objects managing your


containerized application:

Figure 7.6: Hierarchy of Deployment, ReplicaSet,


Pods, and containers

Deployment Configuration

The configuration of a Deployment is actually


very similar to that of a ReplicaSet. Here's an
example of a Deployment configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 30/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

    app: nginx
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  selector:
    matchLabels:
      app: nginx
      environment: production
  template:
    metadata:
      labels:
        app: nginx
        environment: production
    spec:
      containers:
      - name: nginx-container
        image: nginx
The value for the kind field is Deployment. The
rest of the configuration remains the same as
that for ReplicaSets. Deployments also have the

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 31/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

replicas, selector, and Pod template fields


used in the same way as ReplicaSets.

Strategy

In the strategy field under spec, we can


specify which strategy the Deployment should
use when it replaces old pods with new ones.
This can either be RollingUpdate or Recreate.
The default value is RollingUpdate.

RollingUpdate

This is a strategy used to update a Deployment


without having any downtime. With the
RollingUpdate strategy, the controller updates
the Pods one by one. Hence, at any given time,
there will always be some Pods running. This
strategy is particularly helpful when you want to
update the Pod template without incurring any
downtime for your application. However, be
aware that having a rolling update means that
there may be two different versions of Pods (old
and new) running at the same time.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 32/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

If applications serve static information, this is


usually fine because there's usually no harm in
serving traffic using two different versions of an
application, so long as the information that is
served is the same. So, RollingUpdate is usually
a good strategy for these applications. In general,
we can use RollingUpdate for applications for
which the data stored by a new version can be
read and handled by the old version of the
application.

Here's an example configuration for setting the


strategy to RollingUpdate:

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 1
    maxSurge: 1
maxUnavailable is the maximum number of
Pods that can be unavailable during the update.
This field can be specified as either an integer
representing the maximum number of
unavailable Pods or a string representing the
percentage of total replicas that can be

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 33/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

unavailable. For the preceding example


configuration, Kubernetes will ensure that no
more than one replica becomes unavailable
while applying an update. The default value for
maxUnavailable is 25%.

maxSurge is the maximum number of Pods that


can be scheduled/created above the desired
number of Pods (as specified in the replicas
field). This field can also be specified as either an
integer or a percentage string, as with
maxUnavailable. The default value for
maxSurge is also 25%.

Hence, in the preceding example, we are telling


the Kubernetes controller to update the Pods one
at a time, in such a way that no more than one
Pod is ever unavailable and that no more than
four Pods are ever scheduled.

The two parameters—maxUnavailable and


maxSurge—can be tuned for availability and the
speed of scaling up or down the Deployment. For
example, maxUnavailable: 0 and maxSurge:
"30%" ensure a rapid scale-up while maintaining

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 34/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

the desired capacity at all times.


maxUnavailable: "15%" and maxSurge: 0
ensure that the deployment can be performed
without using any extra capacity at the cost of
having, at worst, 15% fewer Pods running.

Recreate

In this strategy, all the existing pods are killed


before creating the new Pods with an updated
configuration. This means there will be some
downtime during the update. This, however,
ensures that all the Pods running in the
Deployment will be on the same version (old or
new). This strategy is particularly useful when
working with application Pods that need to have
a shared state and so we can't have two different
versions of Pods running at the same time. This
strategy can be specified as follows:

strategy:
  type: Recreate
A good use case for using the Recreate update
strategy is if we need to run some data migration
or data processing before the new code can be
used. In this case, we will need to use the
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 35/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Recreate strategy because we can't afford to


have any new code running along with the old
one without running the migration or processing
first for all the Pods.

Now that we have studied the different fields in


the configuration of a Deployment, let's
implement them in the following exercise.

Exercise 7.05: Creating a Simple


Deployment with Nginx Containers

In this exercise, we will create our first


Deployment Pod using the configuration
described in the previous section.

To successfully complete this exercise, perform


the following steps:

1. Create a file called nginx-deployment.yaml


with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 36/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      environment: production
  template:
    metadata:
      labels:
        app: nginx
        environment: production
    spec:
      containers:
      - name: nginx-container
        image: nginx
In this configuration, we can see that the
Deployment will have three replicas of Pods
running with the app: nginx and
environment: production labels.
2. Run the following command to create the
Deployment defined in the previous step:
kubectl apply -f nginx-
deployment.yaml

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 37/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

You should see the following response:


deployment.apps/nginx-deployment
created
3. Run the following command to check the
status of the Deployment:
kubectl get deployment nginx-
deployment
You should see a response similar to the
following:
NAME READY UP-TO-DATE AVAILABLE
AGE
nginx-deployment 3/3 3 3 26m
4. Run the following command to check all the
Pods that are running:
kubectl get pods
You should see a response similar to the
following:

Figure 7.7: A list of Pods created by the


Deployment
We can see that the Deployment has created
three Pods, as desired.
Let's try to understand the names given to the
Pods automatically. nginx-deployment
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 38/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

creates a ReplicaSet named nginx-


deployment-588765684f. The ReplicaSet
then creates three replicas of Pods, each of
which has a name that is prefixed with the
name of the ReplicaSet followed by a
unique identifier.
5. Now that we have created our first
Deployment, let's look at it in more detail to
understand what actually happened during its
creation. To do that, we can describe the
Deployment we just created using the
following command in the terminal:
kubectl describe rs nginx-
deployment
You should see output similar to this:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 39/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Figure 7.8: Describing nginx-deployment

This output shows various details about the


Deployment we just created. In the following
subtopics, we will go through the highlighted
sections of the preceding output to understand
the Deployment that's running.

Labels and Annotations on the Deployment

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 40/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Similar to ReplicaSets, we can see the following


line highlighted in the output shown in Figure
7.8:

Labels:    app=nginx
This indicates that the Deployment was created
with an app=nginx label. Now, let's consider the
next field in the output:

Annotations:    deployment.kuberne
tes.io/revision: 1
                kubectl.kubernetes
.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"De
ployment","metadata":
{"annotations":{},"labels":
{"app":"nginx"},"name":"nginx-
deployment","namespace":"d...
There are two annotations added to the
Deployment automatically.

The Revision annotation

The Kubernetes controller adds an annotation


with the
deployment.kubernetes.io/revision key,

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 41/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

which contains information about how many


revisions have been there for a particular
Deployment.

The last-applied-configuration annotation

Another annotation added by the controller has


the kubectl.kubernetes.io/last-applied-
configuration key, which contains the last
configuration (in JSON format) that was applied
to the Deployment. This annotation is
particularly helpful in rolling back a Deployment
to a previous revision if a new revision doesn't
work well.

Selectors for the Deployment

Now, consider the following line from the output


shown in Figure 7.8:

Selector:    app=nginx,environment
=production
This shows which Pod selectors the Deployment
is configured with. So, this Deployment will try
to acquire the Pods that have both of these
labels.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 42/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Replicas

Consider the following line from the output


shown in Figure 7.8:

Replicas:    3 desired | 3 updated


| 3 total | 3 available | 0
unavailable
We can see that the Deployment has the desired
count of 3 for the Pods, and it also shows that
there are currently 3 replicas present.

Rolling Back a Deployment

In a real-life scenario, you may make a mistake


when making a change in the Deployment
configuration. You can easily undo a change and
roll back to a previous stable revision of the
Deployment.

We can use the kubectl rollout command to


check the revision history and rollback. But to
make this work, we also need to use the --
record flag when we use any apply or set
commands to modify the Deployment. This flag

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 43/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

records the rollout history. Then, you can view


the rollout history using the following command:

kubectl rollout history deployment


<deployment_name>
Then, we can undo any updates by using the
following command:

kubectl rollout undo deployment


<deployment_name>
Let's take a closer look at how this works in the
following exercise:

Exercise 7.06: Rolling Back a


Deployment

In this exercise, we will update the Deployment


twice. We will make an intentional mistake in
the second update and try to roll back to a
previous revision:

1. Create a file called app-deployment.yaml


with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 44/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

  name: app-deployment
  labels:
    environment: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      environment: production
  template:
    metadata:
      labels:
        app: nginx
        environment: production
    spec:
      containers:
      - name: nginx-container
        image: nginx
2. Run the following command to create the
Deployment:
kubectl apply -f app-
deployment.yaml
You should see the following response:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 45/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

deployment.apps/app-deployment
created
3. Run the following command to check the
rollout history of the newly
created Deployment:
kubectl rollout history
deployment app-deployment
You should see the following response:
deployment.apps/app-deployment
REVISION CHANGE-CAUSE
1 <none>
This output shows that the Deployment has no
rollout history as of now.
4. For the first update, let's change the name of
the container to nginx instead of nginx-
container. Update the content of the app-
deployment.yaml file with the following:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
  labels:
    environment: production
spec:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 46/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

  replicas: 3
  selector:
    matchLabels:
      app: nginx
      environment: production
  template:
    metadata:
      labels:
        app: nginx
        environment: production
    spec:
      containers:
      - name: nginx
        image: nginx
As you can see, the only thing that has changed
in this template is the container name.
5. Apply the changed configuration using the
kubectl apply command with the --record
flag. The --record flag ensures that the
update to the Deployment is recorded in the
rollout history of the Deployment:
kubectl apply -f app-
deployment.yaml --record
You should see the following response:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 47/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

deployment.apps/app-deployment
configured
Note that the rollout history maintained by the
--record flag is different from the past
configs stored in the annotations, which we
saw in the Labels and Annotations on the
Deployment subsection.
6. Wait for a few seconds to allow the
Deployment to recreate the Pods with the
updated Pod configuration, and then run the
following command to check the rollout
history of the Deployment:
kubectl rollout history
deployment app-deployment
You should see the following response:

Figure 7.9: Checking the deployment history


In the output, we can see that the second
revision of the Deployment was created. It also
keeps track of what command was used to
update the Deployment.
7. Next, let's update the Deployment and assume
that we made a mistake while doing so. In this

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 48/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

example, we will update the container image


to ngnx (note the intentional spelling error)
instead of nginx using the set image
command:
kubectl set image deployment
app-deployment nginx=ngnx --
record
You should see the following response:
deployment.apps/app-deployment
image updated
8. Wait for a few seconds for Kubernetes to
recreate the new containers, and then check
the status of the Deployment rollout using the
kubectl rollout status command:
kubectl rollout status
deployment app-deployment
You should see the following response:
Waiting for deployment "app-
deployment" rollout to finish: 1
out of 3 new replicas have been
updated...
In this output, we can see that none of the new
replicas are ready yet. Press Ctrl + C to exit and
proceed.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 49/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

9. Run the following command to check the state


of the Pods:
kubectl get pods
You should see the following output:

Figure 7.10: Checking the status of Pods


We can see in the output that the newly
created Pod has failed with an
ImagePullBackOff error, which means that
the Pods aren't able to pull the image. This is
expected because we have a typo in the name
of the image.
10. Next, check the revision history of the
Deployment again by using the
following command:
kubectl rollout history
deployment app-deployment
You should see the following response:

Figure 7.11: Checking the rollout history of the


Deployment

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 50/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

We can see that a third revision of the


Deployment was created using the set image
command containing the typo. Now that we
have pretended to have made a mistake in
updating the Deployment, we will see how to
undo this and roll back to the last stable
revision of the Deployment.
11. Run the following command to roll back to the
previous revision:
kubectl rollout undo deployment
app-deployment
You should see the following response:
deployment.apps/app-deployment
rolled back
As we can see in this output, the Deployment
has not been rolled back to the previous
revision. To practice, we may want to roll back
to a revision different from the previous
revision. We can use the --to-revision flag
to specify the revision number to which we
want to roll back. For example, in the
preceding case, we could have used the
following command and the result would have
been exactly the same:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 51/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

kubectl rollout undo deployment


app-deployment --to-revision=2
12. Run the following command to check the
rollout history of the Deployment again:
kubectl rollout history
deployment app-deployment
You should see the following output:

Figure 7.12: The rollout history for the


Deployment after rollback

We can see in this output that a new revision


was created, which applied the revision that was
previously revision 2. We can see that revision 2
is no longer present in the list of revisions. This
is because rollouts are always done in a rolling-
forward manner. This means that any time we
update a revision, a new revision of a higher
number is created. Similarly, in the case of a
rollback to revision 2, revision 2 became revision
4.

In this exercise, we explored a lot of different


possible operations relating to updating a
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 52/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Deployment, rolling it forward with some


changes, tracking the history of a Deployment,
undoing some changes, and rolling back to a
previous revision.

StatefulSets
StatefulSets are used to manage stateful replicas.
Similar to a Deployment, a StatefulSet creates
and manages the specified number of Pod
replicas from an identical Pod template.
However, where StatefulSets differ from
Deployments is that they maintain a unique
identity for each of their Pods. So, even if all the
Pods are of identical specs, they are not
interchangeable. Each of the Pods has a sticky
identity that can be used by the application code
to manage the state of the application on a
particular Pod. For a StatefulSet with n replicas,
each Pod is assigned a unique integer ordinal
between 0 and n – 1. The names of the Pods
reflect the integer identity assigned to them.
When a StatefulSet is created, all the Pods are
created in the order of their integer ordinal.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 53/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Each of the Pods managed by a StatefulSet will


persist their sticky identity (integer ordinal) even
if the Pod restarts. For example, if a particular
Pod crashes or is deleted, a new Pod will be
created and assigned the same sticky identity as
that of the old Pod.

StatefulSet Configuration

The configuration of a StatefulSet is also very


similar to that of a ReplicaSet. Here's an example
of StatefulSet configuration:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: example-statefulset
spec:
  replicas: 3
  selector:
    matchLabels:
      environment: production
  template:
    metadata:
      labels:
        environment: production
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 54/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

    spec:
      containers:
      - name: name-container
        image: image_name
As we can see in the preceding configuration,
apiVersion for a StatefulSet is apps/v1 and
kind is StatefulSet. The rest of the fields are
used in the same way as for ReplicaSets.

Note

You will learn how to implement StatefulSets on a


multi-node cluster in Chapter 14, Running Stateful
Components in Kubernetes.

Use Cases for StatefulSets

StatefulSets are useful if you need persistent


storage. Using a StatefulSet, you can partition
the data and store it in different Pods. In this
case, it would also be possible for a Pod to go
down and a new Pod come up with the same
identity and have the same partition of data
previously stored by the old Pod.
A StatefulSet can also be used if you require
ordered updates or scaling. For example, if you

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 55/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

want to create or update your Pods in the


order of the identities assigned to them, using
a StatefulSet is a good idea.

DaemonSets
DaemonSets are used to manage the creation of a
particular Pod on all or a selected set of nodes in
a cluster. If we configure a DaemonSet to create
Pods on all nodes, then if new nodes are added to
the cluster, new pods will be created to run on
these new nodes. Similarly, if some nodes are
removed from the cluster, the Pods running on
these nodes will be destroyed.

Use Cases for DaemonSets

Logging: One of the most common use cases


for a DaemonSet is to manage running a log
collection Pod on all nodes. These Pods can be
used to collect logs from all the nodes and then
process them in a log processing pipeline.
Local data caching: A DaemonSet can also be
used to manage caching Pods on all the nodes.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 56/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

These Pods can be used by other application


Pods to store the cached data temporarily.
Monitoring: Another use case for a DaemonSet
is to manage running monitoring Pods on all
the nodes. This can be used to collect system-
or application-level metrics for Pods running
on a particular node.

DaemonSet Configuration

The configuration of a DaemonSet is also very


similar to that of a ReplicaSet or a Deployment.
Here's an example of DaemonSet configuration:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-example
  labels:
    app: daemonset-example
spec:
  selector:
    matchLabels:
      app: daemonset-example
  template:
    metadata:
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 57/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

      labels:
        app: daemonset-example
    spec:
      containers:
      - name: busybox-container
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 10000
As we can see in the preceding configuration,
apiVersion for a DaemonSet is set to apps/v1
and kind is set to DaemonSet. The rest of the
fields are used in the same way as for
ReplicaSets.

To limit the scope of this book, we will not cover


the details for implementing DaemonSets.

Up until now in this chapter, you have learned


about ReplicaSets, which help us manage several
replicas of Pods running an application, and how
a Deployment acts as a wrapper on a ReplicaSet
to add some features to control rolling out
updates and maintaining the update history,

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 58/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

with the option of rolling back if needed. Then,


we learned about StatefulSets, which are handy
if we need to treat each replica as a unique
entity. We also learned how DaemonSets allow
us to schedule a Pod on each of our nodes.

All of these controllers have one common


characteristic—they are useful for applications
or workloads that are to be run continually.
However, some workloads have a graceful
conclusion, and there is no need to keep the Pods
running after the task is done. For this,
Kubernetes has a controller called a Job. Let's
take a look at this in the following section.

Jobs
A Job is a supervisor in Kubernetes that can be
used to manage Pods that are supposed to run a
determined task and then terminate gracefully. A
Job creates the specified number of Pods and
ensures that they successfully complete their
workloads or tasks. When a Job is created, it
creates and tracks the Pods that were specified
in its configuration. When a specified number of
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 59/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Pods complete successfully, the Job is considered


complete. If a Pod fails because of underlying
node failures, the Job will create a new Pod to
replace it. This also means that the application or
code running on the Pod should be capable of
gracefully handling a case where a new Pod
comes up during the runtime of the process.

The Pods created by a Job aren't deleted


following completion of the job. The Pods run to
completion and stay in the cluster with a
Completed status.

A Job can be used in several different ways:

The simplest use case is to create a Job that


runs only one Pod to completion. The Job will
only create additional new Pods if the running
pod fails. For example, a Job can be used for
one-off or recurring data analysis work or for
the training of a machine learning model.
Jobs can also be used for parallel processing.
We can specify more than one successful Pod
completion to ensure that the Job will
complete only when a certain number of Pods
have terminated successfully.
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 60/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Job Configuration

The configuration of a Job follows a similar


pattern to that of a ReplicaSet or a Deployment.
Here's an example of Job configuration:

apiVersion: batch/v1
kind: Job
metadata:
  name: one-time-job
spec:
  template:
    spec:
      containers:
      - name: busybox-container
        image: busybox
        args:
        - /bin/sh
        - -c
        - date
      restartPolicy: OnFailure
The apiVersion field for a Job object is set to
batch/v1. The batch API group contains objects
relating to batch processing jobs. The kind field
is set to Job.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 61/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

A Use Case for Jobs in Machine Learning

Jobs are perfect for batch processes—processes


that run for a certain amount of time before
exiting. This makes Jobs ideal for many types of
production machine learning tasks, such as
feature engineering, cross-validation, model
training, and batch inference. For instance, you
can create a Kubernetes Job that trains a
machine learning model and persists the model
and training metadata to external storage. Then,
you can create another Job to perform batch
inference. This Job would create a Pod that
fetches the pre-trained model from storage, loads
both the model and data into memory, performs
inference, and stores the predictions.

Exercise 7.07: Creating a Simple Job


That Finishes in Finite Time

In this exercise, we will create our first Job,


which will run a container that simply waits for
10 seconds and then finishes.

To successfully complete this exercise, perform


the following steps:
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 62/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

1. Create a file called one-time-job.yaml with


the following content:
apiVersion: batch/v1
kind: Job
metadata:
  name: one-time-job
spec:
  template:
    spec:
      containers:
      - name: busybox-container
        image: busybox
        args:
        - /bin/sh
        - -c
        - date; sleep 20; echo
"Bye"
      restartPolicy: OnFailure
2. Run the following command to create the
Deployment using the kubectl apply
command:
kubectl apply -f one-time-
job.yaml
You should see the following response:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 63/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

job.batch/one-time-job created
3. Run the following command to check the
status of the Job:
kubectl get jobs
You should see a response similar to this:
NAME COMPLETIONS DURATION AGE
one-time-job 0/1 3s 3s
We can see that the Job requires one
completion and is not yet completed.
4. Run the following command to check the Pod
running the Job:
kubectl get pods
Note that you should run this before the Job is
complete to see the response shown here:
NAME READY STATUS RESTARTS AGE
one-time-job-bzz8l 1/1 Running 0
7s
We can see that the Job has created a Pod
named one-time-job-bzz8l to run the task
specified in the Job template.
5. Next, run the following command to check the
logs for the Pod created by the Job:
kubectl logs -f <pod_name>
You should see logs similar to the following:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 64/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Sun Nov 10 15:20:19 UTC 2019


Bye
We can see that the Pod printed the date,
waited for 20 seconds, and then printed Bye in
the terminal.
6. Let's check the status of the Job again by using
the following command:
kubectl get job one-time-job
You should see a response similar to this:
NAME COMPLETIONS DURATION AGE
one-time-job 1/1 24s 14m
We can see that the Job has now been
completed.
7. Run the following command to verify that the
Pod has run to completion:
kubectl get pods
You should see a response similar to this:
NAME READY STATUS RESTARTS AGE
one-time-job-whw79 0/1 Completed
0 32m
We can see that the Pod has a Completed
status.
8. Run the following command to delete the job
(as well as the Pod it created) for cleanup:

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 65/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

kubectl delete job one-time-job


You should see the following response:
job.batch "one-time-job" deleted

In this exercise, we created a one-time Job and


verified that the Pod created by the Job runs to
completion. Implementing Jobs for parallel tasks
is a bit more complicated, and we will leave that
out of this workshop for brevity.

Next, let's wrap this chapter up with an activity


where we will create a Deployment and bring
together several ideas learned in this chapter.

Activity 7.01: Creating a Deployment


Running an Application

Consider a scenario where the


product/application team you're working with is
now ready to put their application in production
and they need your help to deploy it in a
replicated and reliable manner. For the scope of
this exercise, consider the following
requirements for the application:

The default number of replicas should be 6.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 66/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

For simplicity, you can use the nginx image for


the container running in the Pod.
Make sure all the Pods have the following two
labels with corresponding values:
chapter=controllers
activity=1
The update strategy for the Deployment should
be RollingUpdate. At worst, no more than
half of the Pods can be down, and similarly, at
no point should there be more than 150% of
the desired count of Pods.

You should be able to perform the following


tasks once the Deployment has been created:

Scale up the number of replicas to 10.


Scale down the number of replicas to 5.
Note
Ideally, you would want to create this
Deployment to be in a different namespace to
keep it separate from the rest of the stuff that
you created during the previous exercises. So,
feel free to create a namespace and create the
Deployment in that namespace.

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 67/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

The following are the high-level steps to perform


this activity:

1. Create a namespace for this activity.


2. Write the Deployment configuration. Ensure
that it meets all the requirements that are
specified.
3. Create the Deployment using the configuration
from the previous step.
4. Verify that six Pods were created by the
Deployment.
5. Perform both of the tasks mentioned
previously and verify the number of Pods after
performing each step.

You should be able to get the list of Pods to check


whether you can scale up the number of Pods, as
shown in the following image:

Figure 7.13: Checking whether the number of


Pods is scaled up

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 68/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

Similarly, you should also be able to scale down


and check the number of Pods, as shown here:

Figure 7.14: Checking whether the number of


Pods is scaled down

Note

The solution to this activity can be found at the


following address: https://packt.live/304PEoD.

Summary
Kubernetes treats Pods as ephemeral entities,
and ideally you would not deploy any
application or a microservice in an individual
Pod. Kubernetes offers various controllers to
leverage various benefits, including automatic
replication, health monitoring, and automatic
scaling.

In this chapter, we covered different kinds of


controllers and understood when to use each of
them. We created ReplicaSets and observed how
https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 69/70
10/16/22, 8:59 AM 7. Kubernetes Controllers | The Kubernetes Workshop

they manage Pods. We learned when to use


DaemonSets and StatefulSets. We also created a
Deployment and learned how we can scale up
and down the number of replicas and roll back
to an earlier version of the Deployment. Finally,
we learned how to create Jobs for one-time tasks.
All of these controllers come into play when you
want to deploy a production-ready application or
workload, as you will see in the upcoming
chapters.

In the next chapter, we will see how we can


discover and access the Pods or replicas
managed by a Deployment or a ReplicaSet.

Support Sign Out

©2022 O'REILLY MEDIA, INC.  TERMS OF SERVICE PRIVACY POLICY

https://learning.oreilly.com/library/view/the-kubernetes-workshop/9781838820756/B14870_07_Final_SMP_ePub.xhtml 70/70

You might also like