WEBVTT

00:01.820 --> 00:03.160
Hello, and welcome to this lecture.

00:03.380 --> 00:03.980
In this lecture,

00:04.210 --> 00:07.210
we discuss about pod networking
in Kubernetes.

00:08.140 --> 00:12.180
So far, we have set up several
Kubernetes master and worker nodes

00:12.440 --> 00:14.210
and configured networking
between them,

00:14.380 --> 00:17.120
so they're all on a network
that can reach each other.

00:17.450 --> 00:20.220
We also made sure the firewall
and network security groups

00:20.360 --> 00:23.490
are configured correctly to allow
for the Kubernetes control plane

00:23.620 --> 00:25.380
components to reach each other.

00:25.890 --> 00:27.780
Assume that we have also set up

00:28.000 --> 00:31.820
all the Kubernetes control plane
components, such as the QB API server

00:32.080 --> 00:34.380
the [?] servers, kubelets, et cetera,

00:34.690 --> 00:37.610
and we're finally ready to deploy
our applications.

00:38.050 --> 00:39.440
Before we can do that,

00:39.680 --> 00:41.500
there's something
that we must address.

00:41.800 --> 00:45.140
We talked about the network
that connects the nodes together,

00:45.520 --> 00:48.690
but there's also another layer
of networking that is crucial

00:48.820 --> 00:50.060
to the cluster's functioning.

00:50.250 --> 00:52.690
That is the networking
at the pod layer.

00:52.970 --> 00:54.850
Our Kubernetes cluster is soon

00:54.930 --> 00:58.380
going to have a large number of pods
and services running on it.

00:58.770 --> 01:00.050
How are the pods addressed?

01:00.340 --> 01:02.010
How do they communicate
with each other?

01:02.280 --> 01:03.850
How do you access the services

01:04.020 --> 01:06.800
running on these pods internally
from within the cluster,

01:07.000 --> 01:09.900
as well as externally
from outside the cluster?

01:10.220 --> 01:13.530
These are challenges
that Kubernetes expects you to solve.

01:14.060 --> 01:17.800
As of today, Kubernetes does not come
with a built-in solution for this.

01:18.100 --> 01:21.260
It expects you to implement
a networking solution

01:21.460 --> 01:23.410
that solves these challenges.

01:23.580 --> 01:25.280
However, Kubernetes have laid out

01:25.490 --> 01:28.340
clearly the requirements
for pod networking.

01:28.700 --> 01:30.100
Let's take a look at what they are.

01:30.930 --> 01:33.420
Kubernetes expects every pod to get

01:33.540 --> 01:37.720
its own unique IP address,
and that every pod should be able

01:37.940 --> 01:40.540
to read every other pod
within the same node

01:40.740 --> 01:42.340
using that IP address.

01:42.800 --> 01:44.410
Every pod should be able to reach

01:44.680 --> 01:47.380
every other pod
on other nodes as well,

01:47.890 --> 01:49.260
using the same IP address.

01:49.440 --> 01:51.300
It doesn't care what IP address

01:51.450 --> 01:54.800
that is and what range
or sub-net it belongs to.

01:55.160 --> 01:58.120
As long as you can implement
a solution that takes care

01:58.300 --> 02:01.360
of automatically assigning
IP addresses and establish

02:01.530 --> 02:04.450
connectivity between the pods
in a node, as well as pods

02:04.540 --> 02:06.520
on different nodes, you're good,

02:07.050 --> 02:09.050
without having to configure
any naturals.

02:09.860 --> 02:13.800
How do you implement a model
that solves these requirements?

02:14.600 --> 02:15.970
Now, there are many networking

02:16.140 --> 02:18.380
solutions available out there
that does these,

02:19.090 --> 02:21.530
but we've already learned
about networking concepts

02:21.740 --> 02:25.170
brought in IP address management
namespaces in CNI.

02:25.540 --> 02:28.410
Let's try to use that knowledge
to solve this problem

02:28.600 --> 02:29.780
by ourselves first.

02:30.040 --> 02:32.720
This will help in understanding
how other solutions work.

02:33.120 --> 02:34.760
I know there is a bit of repetition,

02:35.010 --> 02:37.820
but I'm trying to relate
the same concept and approach

02:38.050 --> 02:39.740
all the way from plain network

02:39.930 --> 02:42.840
namespaces on Linux all the way
to Kubernetes.

02:44.010 --> 02:45.520
We have a three-node cluster,

02:45.690 --> 02:48.050
it doesn't matter
which one is master or worker.

02:48.170 --> 02:49.980
They all run pods
either for management

02:50.210 --> 02:51.500
or workload purposes.

02:51.970 --> 02:53.620
As far as networking is concerned,

02:53.860 --> 02:56.360
we're going to consider all of them
as the same.

02:56.600 --> 02:58.960
First, let's plan
what we're going to do.

02:59.540 --> 03:01.660
The nodes are part
of an external network

03:01.810 --> 03:05.970
and has IP addresses
in the 192.160.1. series.

03:06.380 --> 03:08.330
Node 1 is assigned 11.

03:08.520 --> 03:09.720
Node 2 is 12.

03:09.890 --> 03:11.360
Node 3 is 13.

03:11.960 --> 03:12.560
Next step,

03:12.730 --> 03:13.880
when containers are created,

03:14.170 --> 03:16.520
Kubernetes creates network namespaces
for them.

03:16.970 --> 03:18.930
To enable communication between them,

03:19.130 --> 03:21.800
we attach these namespaces
to a network.

03:22.000 --> 03:23.000
What network?

03:23.800 --> 03:25.160
We've learned about bridge networks

03:25.370 --> 03:28.380
that can be created within nodes
to attach namespaces.

03:28.730 --> 03:33.200
We create a bridge network
on each node and then bring them up.

03:33.650 --> 03:37.400
It's time to assign an IP address
to the bridge interfaces or networks.

03:37.880 --> 03:39.260
What IP address?

03:39.720 --> 03:41.660
We decide that each bridge network

03:41.850 --> 03:45.450
will be on its own sub-net,
choose any private address range,

03:45.720 --> 03:51.100
say 10.244.1, 10.244.2, and 10.244.3.

03:51.640 --> 03:54.360
Next, we set the IP address
for the bridge interface.

03:54.980 --> 03:56.650
We have built our base.

03:56.890 --> 03:58.370
The remaining steps
are to be performed

03:58.540 --> 03:59.480
for each container,

03:59.680 --> 04:01.940
and every time a new container
is created.

04:02.260 --> 04:03.600
We write a script for it.

04:03.900 --> 04:06.930
Now, you don't have to know
any kind of complicated scripting.

04:07.080 --> 04:09.330
It's just a file
that has all commands

04:09.540 --> 04:10.570
we will be using.

04:10.660 --> 04:14.280
We can run this multiple times
for each container going forward.

04:14.600 --> 04:16.330
To attach a container to the network,

04:16.420 --> 04:19.490
we need a pipe
or a virtual network cable.

04:19.690 --> 04:22.060
Recreate that
using the "IP link add" command.

04:22.330 --> 04:25.320
Don't focus on the options
as they are similar to what we saw

04:25.460 --> 04:26.940
in our previous lectures.

04:27.340 --> 04:29.930
Assume that they vary
depending on the inputs.

04:30.290 --> 04:31.650
We then attach one end

04:31.850 --> 04:34.200
to the container and another end
to the bridge

04:34.400 --> 04:36.450
using the "IP link set" command.

04:36.720 --> 04:39.700
With an assign IP address,
using the "IP addr" command

04:40.040 --> 04:42.740
and add a route
to the default gateway.

04:43.280 --> 04:44.970
What IP do we add?

04:45.210 --> 04:48.010
We either manage that ourselves
or store that information

04:48.260 --> 04:49.380
in some kind of database.

04:49.880 --> 04:51.060
For now, we will assume

04:51.370 --> 04:55.730
it is 10.244.1.2,
which is a free IP in the sub-net.

04:56.330 --> 04:59.400
We discuss about IP address
management in detail

04:59.480 --> 05:00.920
in one of the upcoming lectures.

05:01.680 --> 05:03.540
Finally we bring up the interface.

05:04.810 --> 05:08.080
We then run the same script,
this time for the second container

05:08.240 --> 05:10.460
with its information,
and gets the container

05:10.650 --> 05:12.020
connected to the network.

05:12.330 --> 05:15.170
The two containers can now
communicate with each other.

05:15.380 --> 05:17.080
We copy the script to the other nodes

05:17.170 --> 05:19.810
and run the script on them
to assign IP address

05:20.000 --> 05:23.120
and connect those containers
to their own internal networks.

05:23.880 --> 05:26.120
We have solved the first part
of the challenge.

05:26.620 --> 05:29.930
The pods all get their own
unique IP address and are able

05:30.130 --> 05:32.850
to communicate with each other
on their own nodes.

05:33.140 --> 05:37.170
The next part is to enable them
to reach other pods on other nodes.

05:37.880 --> 05:42.130
Say, for example,
the pod at 10.244.1.2 on Node 1

05:42.420 --> 05:46.360
wants to ping pod 10.244.2.2
on Node 2.

05:46.970 --> 05:52.600
As of now, the first has no idea
where the address 10.244.2.2 is

05:52.890 --> 05:55.290
because it is on a different network
than its own.

05:55.770 --> 05:58.610
It routes to Node 1's IP,
as it is said

05:58.700 --> 06:00.140
to be the default gateway.

06:00.450 --> 06:03.530
Node 1 doesn't know
either since 10.244.2.2

06:03.620 --> 06:05.660
is a private network or Node 2.

06:06.680 --> 06:12.100
Add a route to Node 1's routing table
to route traffic to 10.244.2.2

06:12.300 --> 06:17.450
where the second node's IP
at 192.168.1.12.

06:18.370 --> 06:22.400
Once the route is added,
the blue pod is able to ping across.

06:23.060 --> 06:24.860
Similarly, we configure route

06:24.930 --> 06:27.780
on all hosts to all the other hosts
with information

06:27.940 --> 06:30.210
regarding the respective networks
within them.

06:31.290 --> 06:32.280
Now, this works fine

06:32.570 --> 06:35.140
in this simple setup,
but this will require

06:35.330 --> 06:38.210
a lot more configuration
as in when your underlying

06:38.380 --> 06:40.290
network architecture
gets complicated.

06:41.380 --> 06:44.490
Instead of having to configure routes
on each server,

06:44.880 --> 06:48.400
a better solution is to do that
on a router if you have one

06:48.570 --> 06:52.770
in your network and point all hosts
to use that as the default gateway.

06:53.100 --> 06:55.040
That way you can easily manage routes

06:55.280 --> 06:58.080
to all networks in the routing table
on the router.

06:58.300 --> 06:58.930
With that,

06:59.000 --> 07:01.650
the individual virtual networks
we created

07:01.880 --> 07:07.770
with the address 10.244.1.0/24
on each node now form

07:07.900 --> 07:13.520
a single large network
with the address 10.244.0.0/16.

07:14.440 --> 07:16.450
It's time to tie everything together.

07:16.740 --> 07:18.650
We performed a number of manual steps

07:18.770 --> 07:20.880
to get the environment ready
with the bridge networks

07:21.060 --> 07:21.930
and routing tables.

07:22.100 --> 07:23.130
We then wrote a script

07:23.370 --> 07:26.900
that can be run for each container
that performs the necessary steps

07:27.050 --> 07:29.570
required to connect each container
to the network.

07:29.740 --> 07:32.250
We executed the script manually.

07:32.560 --> 07:35.160
Of course, we don't want to do that
as in large environments

07:35.320 --> 07:38.060
where thousands of pods
are created every minute.

07:38.340 --> 07:39.120
How do we run

07:39.440 --> 07:42.560
this script automatically
when a pod is created on Kubernetes?

07:42.780 --> 07:45.970
That's where CNI comes in acting
as the middleman.

07:46.300 --> 07:49.400
CNI tells Kubernetes
that this is how you should call

07:49.600 --> 07:53.050
a script as soon as you create
a container, and CNI tells us,

07:53.290 --> 07:55.740
"This is how your script
should look like."

07:56.260 --> 07:59.860
We need to modify the script
a little bit to meet CNI standards,

08:00.250 --> 08:03.610
it should have an add section
that will take care of adding

08:03.720 --> 08:05.960
a container to the network,
and a delete section

08:06.210 --> 08:09.370
that will take care of deleting
container interfaces from the network

08:09.900 --> 08:12.040
and freeing the IP address,
et cetera.

08:12.360 --> 08:13.890
Our script is ready.

08:14.280 --> 08:15.800
The kubelet on each node

08:16.010 --> 08:18.450
is responsible
for creating containers.

08:18.620 --> 08:20.100
Whenever a container is created,

08:20.300 --> 08:22.800
the kubelet looks
at the CNI configuration

08:22.930 --> 08:26.160
passed as a command-line argument
when it was run,

08:26.480 --> 08:28.380
and identifies our script's name.

08:28.720 --> 08:29.440
It then looks

08:29.660 --> 08:33.570
in the CNI's bin directory to find
our script and then executes

08:33.770 --> 08:36.760
the script with the "Add" command
and the name and namespace

08:36.930 --> 08:40.530
of the container, and then our script
takes care of the rest.

08:40.920 --> 08:44.060
We will look at how and where the CNI
is configured in Kubernetes

08:44.250 --> 08:46.890
in the next lecture
along with practice tests.

08:47.530 --> 08:49.660
For now, that's it
from the pod networking

08:49.930 --> 08:51.000
concepts lecture.

08:51.220 --> 08:53.820
Hopefully, that should give you
enough knowledge on inspecting

08:54.010 --> 08:56.890
networking within pods
in a Kubernetes cluster.

08:57.280 --> 09:01.090
We will see how other solutions
do the same thing that we did

09:01.320 --> 09:02.400
in the upcoming lectures.

