WEBVTT

00:00.633 --> 00:02.029
Hello and welcome to this lecture.

00:02.109 --> 00:04.153
In this lecture, we look at deploying

00:04.233 --> 00:07.305
multiple schedulers
in a Kubernetes cluster.

00:07.659 --> 00:10.489
Now, we have seen
how the default scheduler works

00:10.569 --> 00:12.409
in Kubernetes in the previous lectures.

00:12.489 --> 00:16.519
It has an algorithm that distributes
parts across nodes evenly,

00:16.599 --> 00:19.120
as well as takes
into consideration various conditions

00:19.200 --> 00:23.053
we specify through taints and tolerations
and node affinity, et cetera,

00:23.133 --> 00:25.669
but what if none
of these satisfies your needs?

00:25.749 --> 00:29.629
Say you have a specific application
that requires its components

00:29.709 --> 00:34.067
to be placed on nodes
after performing some additional checks.

00:34.689 --> 00:37.339
You decide to have your own scheduling
algorithm to place

00:37.419 --> 00:40.909
parts on nodes so that you can add
your own custom conditions

00:40.989 --> 00:42.446
and checks in it.

00:42.609 --> 00:45.039
Kubernetes is highly extensible.

00:45.309 --> 00:49.059
You can write your own Kubernetes
scheduler program,

00:49.299 --> 00:52.279
package it and deploy
it as the default scheduler

00:52.359 --> 00:55.399
or as an additional scheduler
in the Kubernetes cluster.

00:55.479 --> 00:58.759
That way, all of the other applications
can go through the default scheduler.

00:58.839 --> 01:01.253
However, some specific applications

01:01.333 --> 01:05.120
that you may choose can use
your own custom scheduler.

01:05.679 --> 01:10.239
Your Kubernetes cluster
can have multiple schedulers at a time.

01:10.839 --> 01:12.829
When creating a pod or a deployment,

01:12.909 --> 01:15.439
you can instruct
Kubernetes to have the pod

01:15.519 --> 01:20.019
scheduled by a specific scheduler,
so let's see how that's done.

01:21.129 --> 01:23.749
Now, when there are multiple schedulers,
they must have different names

01:23.829 --> 01:27.439
so that we can identify
them as separate schedulers.

01:27.519 --> 01:30.499
The default scheduler
is named default-scheduler,

01:30.579 --> 01:32.187
and this name is configured

01:32.267 --> 01:36.169
in a kube-scheduler configuration
file that looks like this.

01:36.249 --> 01:38.287
Now, the default scheduler
doesn't really need one

01:38.367 --> 01:40.309
because if you don't specify a name,

01:40.389 --> 01:42.709
it sets the name to default-scheduler,

01:42.789 --> 01:45.409
but this is how it would look
if you were to create one.

01:45.489 --> 01:49.249
For the other schedulers, we could create
a separate configuration file

01:49.329 --> 01:51.999
and set the scheduler name like this.

01:55.659 --> 01:58.129
Let's start with the most simplest way

01:58.209 --> 02:00.439
of deploying an additional scheduler.

02:00.519 --> 02:04.699
Now, earlier we saw how to deploy
the Kubernetes kube-scheduler.

02:04.779 --> 02:06.739
We download the kube-scheduler binary

02:06.819 --> 02:09.889
and run it as a service
with a set of options.

02:09.969 --> 02:12.259
Now, to deploy an additional scheduler,

02:12.339 --> 02:14.269
you may use the same kube-scheduler binary

02:14.349 --> 02:16.549
or use one that you might have built
for yourself,

02:16.629 --> 02:18.439
which is what you would do if you needed

02:18.519 --> 02:20.809
the scheduler to work differently.

02:20.889 --> 02:23.020
In this case,
we are going to use the same binary

02:23.100 --> 02:24.619
to deploy the additional scheduler,

02:24.699 --> 02:26.719
and this time we point the configuration

02:26.799 --> 02:30.228
to the custom configuration
file that we created.

02:30.639 --> 02:34.139
Each scheduler uses
a separate configuration file,

02:34.239 --> 02:37.579
and with each file having
its own scheduler name.

02:37.659 --> 02:39.769
Note that there are other options
to be passed in such

02:39.849 --> 02:43.339
as the kube config file
to authenticate into the Kubernetes API,

02:43.419 --> 02:46.819
but I'm just keeping that for now,
just to keep it super simple.

02:46.899 --> 02:49.219
This is not how you would deploy
a custom scheduler

02:49.299 --> 02:53.387
99% of the time today
because with kubeadm deployment,

02:53.467 --> 02:56.239
all the control plane
components run as a pod

02:56.319 --> 02:59.534
or a deployment
within the Kubernetes cluster.

03:00.099 --> 03:01.957
Let's look at another way.

03:02.169 --> 03:04.153
Let's look at how it works

03:04.233 --> 03:06.679
if you were to deploy
the scheduler as a pod.

03:06.759 --> 03:10.369
So we create a pod definition file
and specify the kube config property,

03:10.449 --> 03:14.433
which is the path
to the scheduler con file

03:14.733 --> 03:18.649
that has the authentication information
to connect to the Kubernetes API server.

03:18.729 --> 03:21.679
We then pass in our custom kube-scheduler

03:21.759 --> 03:25.617
configuration file as a config
option to the scheduler.

03:25.899 --> 03:29.479
Note that we have the scheduler
name specified in the file,

03:29.559 --> 03:34.629
so that's how the name gets
picked up by the scheduler.

03:35.649 --> 03:40.578
Now, another important option
to look here is the leader elect option,

03:40.809 --> 03:43.939
and this goes
into the kube-scheduler configuration.

03:44.019 --> 03:45.409
The leader elect option is used

03:45.489 --> 03:47.239
when you have multiple
copies of the scheduler

03:47.319 --> 03:48.889
running on different master nodes,

03:48.969 --> 03:52.020
as in a high availability setup
where you have multiple master nodes

03:52.100 --> 03:55.129
with the kube-scheduler
process running on both of them.

03:55.209 --> 03:59.149
If multiple copies of the same scheduler
are running on different nodes,

03:59.229 --> 04:01.159
only one can be active at a time,

04:01.239 --> 04:04.579
and that's where the leader elect
option helps in choosing a leader

04:04.659 --> 04:07.129
who will lead the scheduling activities.

04:07.209 --> 04:10.579
We will discuss more about
HA setup in another section.

04:10.659 --> 04:13.549
In case you do have multiple masters,
just remember that you can pass

04:13.629 --> 04:18.159
in this additional parameter
to set a log object name,

04:18.399 --> 04:20.989
and this is to differentiate
the new custom

04:21.069 --> 04:24.141
scheduler from the default
election process.

04:25.149 --> 04:26.539
Now let's take a look at how to deploy

04:26.619 --> 04:28.789
the additional scheduler as a deployment,
and for this,

04:28.869 --> 04:32.727
I'm going to go into the Kubernetes
documentation pages

04:33.309 --> 04:36.409
and for the one for configuring
multiple schedulers.

04:36.489 --> 04:39.829
If you look here first of all,
it shows you how to,

04:39.909 --> 04:42.767
if you were to build your own scheduler,

04:42.999 --> 04:45.879
how you could clone the Kubernetes repo

04:46.209 --> 04:50.029
and then make changes
to the kube-scheduler and build it

04:50.109 --> 04:52.989
and package it into a docker image.

04:53.529 --> 04:57.079
Then here you can see the config file

04:57.159 --> 04:59.874
to create a scheduler as a deployment.

05:00.159 --> 05:03.079
You can ignore all of this to begin with.

05:03.159 --> 05:05.017
This is what it is really.

05:05.229 --> 05:08.869
Here you have the deployment,
and this deployment is similar to the pod,

05:08.949 --> 05:10.279
but it's just that it's a deployment,

05:10.359 --> 05:12.919
the pod that we just looked
at but it's just that it's a deployment.

05:12.999 --> 05:15.919
Here you have the image
which is the custom kube-scheduler image,

05:15.999 --> 05:18.649
and this is the config file
that we just talked about

05:18.729 --> 05:22.509
which has my-scheduler config file.

05:23.499 --> 05:25.579
The binary is the kube-scheduler binary.

05:25.659 --> 05:30.019
Now for this to work
there are some additional prerequisites.

05:30.099 --> 05:34.129
Some of these are like the service
account and clusteral bindings.

05:34.209 --> 05:36.859
These are basically for authentication.

05:36.939 --> 05:39.829
We discuss about clusteral
bindings and cluster roles

05:39.909 --> 05:43.029
and service accounts in the odd section.

05:43.119 --> 05:47.539
If you haven't gone through that yet,
just hold off on this.

05:47.619 --> 05:50.239
You can basically ignore this for now.

05:50.319 --> 05:54.889
The only other thing is how this file
is passed into the deployment.

05:54.969 --> 05:56.809
You can either create this file locally

05:56.889 --> 05:58.549
and then pass it in as a volume mount

05:58.629 --> 06:02.169
as it's done for the other pods usually,

06:03.309 --> 06:06.049
or another thing
you could do that's done here.

06:06.129 --> 06:09.679
The approach that's used here
is basically creating a config map.

06:09.759 --> 06:14.749
This is the kube-scheduler configuration
that we just talked about with

06:14.829 --> 06:16.489
the leader elect option set to false

06:16.569 --> 06:19.099
because I think the replicas is just one.

06:19.179 --> 06:21.739
Then you have the scheduler name here.

06:21.819 --> 06:24.609
This is the config file.

06:24.729 --> 06:29.839
Then this config file is passed
in as a volume here as a config file.

06:29.919 --> 06:33.469
Basically whatever
is the content in that particular config

06:33.549 --> 06:39.129
map is then mapped to a volume mount
to a volume here, this specific location.

06:39.489 --> 06:40.549
Then from this location,

06:40.629 --> 06:45.219
you have this YAML file
which basically has this content.

06:46.239 --> 06:47.389
This is how that maps.

06:47.469 --> 06:49.039
Again, if you haven't gone
through the volume

06:49.119 --> 06:50.959
and volume mount sections of this course

06:51.039 --> 06:53.539
then just hold off on this for now,

06:53.619 --> 06:57.049
then you'll understand
that when we talk about these.

06:57.129 --> 06:58.999
Then again, liveness probes,
readiness probes,

06:59.079 --> 07:00.469
resources and security contexts,

07:00.549 --> 07:03.469
all of these are sections
that we talk about later.

07:03.549 --> 07:05.029
Again, you can ignore these for now,

07:05.109 --> 07:09.395
but what we need to understand
here is just that this section

07:10.209 --> 07:14.859
on how this file is passed
to this custom schedule.

07:17.619 --> 07:19.162
That's about that.

07:20.169 --> 07:22.629
Just proceeding with our lecture.

07:23.199 --> 07:26.239
When you run the get pods
command in the kube system

07:26.319 --> 07:29.839
namespace you can then see
the new custom scheduler running.

07:29.919 --> 07:33.529
This is if you ran it as a pod,
and if you ran it as a deployment,

07:33.609 --> 07:36.379
then you'll probably see a slightly
different naming convention,

07:36.459 --> 07:38.269
but you'll be able to see the pod there.

07:38.349 --> 07:40.909
Just make sure you're checking
the right namespace.

07:40.989 --> 07:45.279
Now, once we have deployed
that custom scheduler,

07:45.549 --> 07:48.109
the next step is to configure a pod

07:48.189 --> 07:49.939
or a deployment to use this new scheduler.

07:50.019 --> 07:52.929
How do you use our custom scheduler?

07:53.619 --> 07:56.029
Here we have a pod definition file.

07:56.109 --> 07:59.689
What we need to do is add
a new field called schedulerName

07:59.769 --> 08:02.299
and specify the name of the new scheduler.

08:02.379 --> 08:03.499
That's basically it.

08:03.579 --> 08:06.829
This way, when the pod is created
the right scheduler gets picked up

08:06.909 --> 08:09.267
and the scheduling process works.

08:09.939 --> 08:12.679
We now create the pod using
the kubectl create command.

08:12.759 --> 08:15.169
If the scheduler
was not configured correctly,

08:15.249 --> 08:18.499
the pod will continue
to remain in a pending state.

08:18.579 --> 08:22.279
If everything is good then the pod
will be in a running state.

08:22.359 --> 08:23.899
If the pod is in a pending state,

08:23.979 --> 08:29.689
then you can look at the logs
under the pod describe command,

08:29.769 --> 08:31.841
the kubectl describe command.

08:32.019 --> 08:37.179
You'll mostly notice that the scheduler
isn't configured correctly.

08:38.409 --> 08:41.269
Now how do you know
which scheduler picked it up?

08:41.349 --> 08:42.469
We have multiple schedulers.

08:42.549 --> 08:47.478
How do you know which scheduler
picked up scheduling a particular pod?

08:47.739 --> 08:50.779
Now we can view
this in the events using the kubectl

08:50.859 --> 08:53.859
get events command
with the -O wide option.

08:54.459 --> 08:56.719
This will list all the events
in the current name space,

08:56.799 --> 08:59.228
and look for the scheduled events.

08:59.349 --> 09:01.999
As you can see the source of the event

09:02.079 --> 09:03.769
is the custom scheduler that we created.

09:03.849 --> 09:06.409
That's the name that we gave
to the custom scheduler.

09:06.489 --> 09:09.409
The message says
that successfully assigned the image.

09:09.489 --> 09:11.479
That indicates that it's working.

09:11.559 --> 09:13.009
You could also view the logs

09:13.089 --> 09:16.429
of the scheduler in case
you run into issues.

09:16.509 --> 09:20.295
For that, view the logs using
the kubectl logs command

09:20.529 --> 09:23.719
and provide the scheduler name,

09:23.799 --> 09:28.699
either the pod name or the deployment
name, and then the right namespace.

09:28.779 --> 09:30.019
That's it for this lecture.

09:30.099 --> 09:32.171
I'll see you in the next one.

