[music]
Hello and welcome to this lecture
on Kubernetes controllers.
My name is Mumshad Mannambeth.
In this lecture, we will discuss about
Kubernetes controllers.
Controllers are the brain
behind Kubernetes.
They are the processes that monitor
Kubernetes objects
and respond accordingly.
In this lecture, we will discuss about
one controller in particular
and that is the ReplicationController.
What is a replica and why do we need
a ReplicationController?
Let's go back to our first scenario
where we had a single pod
running our application.
What if for some reason
our application crashes and the pod fails?
Users will no longer be able
to access our application.
To prevent users from losing access
to our application,
we would like to have more than
one instance or pod running
at the same time.
That way, if one fails,
we still have our application running
on the other one.
The ReplicationController helps us
run multiple instances of a single pod
in the Kubernetes cluster
thus providing high availability.
Does that mean you can't use
a ReplicationController if you plan
to have a single pod?
No.
Even if you have a single pod,
the ReplicationController can help
by automatically bringing up
a new pod when the existing one
fails thus the ReplicationController
ensures that the specified number
of pods are running at all times
even if it's just one or 100.
Another reason we need
ReplicationController is to create
multiple pods to share the load across them.
For example, in this simple scenario,
we have a single pod serving a set of users.
When the number of users increase,
we deploy additional pod to balance
the load across the two pods.
If the demand further increase
and if we were to run out of resources
on the first node,
we could deploy additional pods
across the other nodes in the cluster.
As you can see, the ReplicationController
spans across multiple nodes in the cluster.
It helps us balance the load
across multiple pods on different nodes
as well as scale our application
when the demand increases.
It's important to note that
there are two similar terms--
ReplicationController and ReplicaSet.
Both have the same purpose,
but they're not the same.
ReplicationController
is the older technology
that is being replaced by ReplicaSet.
ReplicaSet is the new recommended way
to set up replication.
However.
Whatever we discussed in the previous
few slides remain applicable
to both these technologies.
There are minor differences
in the way each works.
We will look at that in a bit.
As such, we will try to stick to ReplicaSets
in all of our demos
and implementations going forward.
Let us now look at how we create
a ReplicationController.
As with the previous lecture,
we start by creating
a ReplicationController definition file.
We will name it rc-definition.yml.
As with any Kubernetes definition file,
we have four sections--
the apiVersion, kind, metadata, and spec.
The apiVersion is specific
to what we are creating.
In this case, ReplicationController
is supported in Kubernetes apiVersion v1.
We will set it as v1.
The kind, as we know,
is a replication controller.
Under metadata, we will add a name
and we will call it myapp-rc
and we will also add a few labels, app,
and type and assign values to them.
So far, it has been very similar
to how we created a pod
in the previous section.
The next is the most crucial part
of the definition file
and that is the specification
written as spec.
For any Kubernetes definition file,
the spec section defines what's inside
the object we are creating.
In this case, we know that
the ReplicationController creates
multiple instances of a pod.
What pod?
We create a template section under spec
to provide a pod template to be used
by the ReplicationController
to create replicas.
Now, how do we define the pod template?
It's not that hard because we have already
done that in the previous exercise.
Remember, we created
a pod definition file
in the previous exercise.
We could reuse the contents of the file
to populate the template section.
Move all the contents of the pod
definition file into the template section
of the ReplicationController,
except for the first few lines
which are apiVersion and kind.
Remember, whatever we move must be
under the template section,
meaning they should be intended to the right
and have more spaces before them
than the template line itself.
They should be children
of the template section.
Looking at our file now,
we now have two metadata sections.
One is for the ReplicationController
and another for the pod.
We have two spec sections, one for each.
We have nested
two definition files together--
the ReplicationController being the parent,
and the pod definition being the child.
Now, there is something still missing.
We haven't mentioned how many replicas
we need in the ReplicationController.
For that, add another property
to the spec called replicas,
and input the number of replicas
you need under it.
Remember that the template and replicas
are direct children of spec sections.
They are siblings
and must be on the same vertical line,
which means having equal number
of spaces before them.
Once the file is ready,
run the kubectl create command
and input the file using the -f parameter.
The ReplicationController is created.
When the ReplicationController is created,
it first creates the pods using
the pod definition template
as many as required,
which is three in this case.
To view the list of created
ReplicationControllers,
run the kubectl get ReplicationController
command and you will see
the ReplicationController listed.
We can also see the desired
number of replicas or pods,
the current number of replicas,
and how many of them
are ready in the output.
If you would like to see the pods
that were created
by the ReplicationController,
run the kubectl get pods command
and you will see three pods running.
Note that all of them are starting
with the name of the ReplicationController,
which is myapp-rc,
indicating that they're all created
automatically
by the ReplicationController.
What we just saw
was the ReplicationController.
Let us now look at ReplicaSet.
Is it very similar to ReplicationController.
As usual, first, we have apiVerson,
kind, metadata, and spec.
The apiVersion though is a bit different.
It is apps/v1, which is different
from what we had before
for ReplicationController,
which was just v1.
If you get this wrong, you are likely
to get an error that looks like this.
It would say, "No match for Kind=ReplicaSet,"
because the specified
Kubernetes apiVersion
has no support for ReplicaSet.
The kind would be ReplicaSet.
We add name and labels in the metadata.
The specification section
looks very similar
to ReplicationController.
It has a template section where we provide
pod definition as before.
I'm going to copy contents
over from pod definition file.
We have number of replicas
which is set to three.
However, there is one major difference
between ReplicationController
and ReplicaSet.
ReplicaSet requires a selector definition.
The selector section helps the ReplicaSet
identify what pods fall under it.
Why would you have to specify
what pods fall under it if you have
provided the contents
of the pod definition file
itself in the template?
It's because ReplicaSet can also manage
pods that were not created
as part of the ReplicaSet creation.
Say, for example,
there were pods created
before the creation of the ReplicaSet
that matched labels
specified in the selector,
the ReplicaSet will also take those pods
into consideration when creating
the replicas.
I will elaborate this in the next slide.
Before we get into that,
I would like to mention that the selector
is one of the major differences
between ReplicationController
and ReplicaSet.
The selector is not a required field
in case of a ReplicationController.
It is still available.
When you skip it,
as we did in the previous slide,
it assumes it to be the same as the labels
provided in the pod definition file.
In case of ReplicaSet,
a user input is required for this property,
and it has to be written in the form
of matchLabels as shown here.
The matchLabels selectors simply matches
the labels specified under it
to the labels on the pod.
The ReplicaSet selector also provides
many other options for matching labels
that were not available
in a ReplicationController.
As always, to create a ReplicaSet,
run the kubectl create command
providing the definition file as input.
To see the created replicas,
run the kubectl get ReplicaSet command.
To get list of pods,
simply run the kubectl get pods command.
What is the deal with labels and selectors?
Why do we label our pods
and objects in Kubernetes?
Let us look at a simple scenario.
Savy deployed three instances
of our front-end web application
as three pods.
We would like to create
a ReplicationController or ReplicaSet
to ensure that we have three active pods
at any time.
Yes, that is one of the use case of ReplicaSets.
You can use it to monitor existing pods
if you have them already created,
as it is in this example.
In case they were not created,
the ReplicaSet will create them for you.
The role of the ReplicaSet
is to monitor the pods
and if any of them were to fail,
deploy new ones.
The ReplicaSet is in fact,
a process that monitors the pods.
Now, how does the ReplicaSet
know what pods to monitor?
There could be hundreds of other pods
in the cluster running
different applications.
This is where labeling our pods
during creation comes in handy.
We could now provide these labels
as a filter for ReplicaSet.
Under the selector section,
we use the matchLabels filter
and provide the same label
that we used while creating the pods.
This way the ReplicaSet knows
which pods to monitor.
The same concept of labels and selectors
is used in many other places
throughout Kubernetes.
Now, let me ask you a question
along the same lines.
In the ReplicaSet specification section,
we learned that there are three sections--
template, replicas, and the selector.
We need three replicas
and we have updated our selector
based on our discussion
in the previous slide.
Say, for instance,
we have the same scenario
as in the previous slide where we have
three existing pods
that were created already,
and we need to create a ReplicaSet
to monitor the pods to ensure
there are a minimum of three
running at all times.
When the ReplicationController is created,
it is not going to deploy a new instance
of pod as three of them
with matching labels are already created.
In that case, do we really need
to provide a template section
in the ReplicaSet specification
since we are not expecting the ReplicaSet
to create a new pod on deployment?
Yes, we do.
Because in case one of the pods
were to fail in the future,
the ReplicaSet needs to create
a new one to maintain
the desired number of pods.
For the ReplicaSet, to create a new pod,
the template definition section is required.
Let's now look at how we scale the ReplicaSet.
Say, we started with three replicas,
and in the future, we decided to scale to six.
How do we update our ReplicaSet
to scale to six replicas?
There are multiple ways to do it.
The first is to update the number
of replicas in the definition file to six.
Then run the kubectl replace command
to specify the same file
using the -f parameter.
That will update the ReplicaSet
to have six replicas.
The second way to do it is to run
the kubectl scale command,
use the replicas parameter to provide
the new number of replicas,
and specify the same file as input.
You may either input the definition file
or provide the ReplicaSet name
in the type name format.
However, remember that using the file name
as input will not result in the number
of replicas being updated
automatically in the file.
In other words, the number of replicas
in the Replica Sets definition file
will still be three even though
you scaled your ReplicaSet to have
six replicas using
the kubectl scale command
and the file as input.
There are also options available
for automatically scaling
the ReplicaSet based on load.
That is an advanced topic.
We will discuss it at a later time.
Let us now review the commands real quick.
The kubectl create command,
as we know, is used to create
a ReplicaSet or basically any object
in Kubernetes depending on the file
we are providing as input.
You must provide the input file
using the -f parameter.
Use the kubectl get command to see
the list of ReplicaSets created.
Use the kubectl delete
ReplicaSet command followed by
the name of the ReplicaSet
to delete the ReplicaSet.
Then we have the kubectl replace
command to replace or update
the ReplicaSet and also the kubectl scale
command to scale ReplicaSet
simply from the command line
without having to modify the file.
That's it for this lecture.