WEBVTT

00:00.247 --> 00:01.293
-In this lecture,

00:01.433 --> 00:05.781
we will take a look
at network policies in more detail.

00:06.288 --> 00:09.978
Here we have the same web API
and database pods

00:10.058 --> 00:12.738
that we discussed about
in the previous lecture.

00:13.064 --> 00:16.503
First, let's be very clear
with our requirements.

00:16.612 --> 00:19.395
Our goal is to protect the database pod

00:19.475 --> 00:23.039
so that it does not allow access
from any other pod,

00:23.185 --> 00:28.240
except the API pod, and only on port 3306.

00:28.836 --> 00:33.002
Let's assume that we are not concerned
about the web pod or the API pod.

00:33.245 --> 00:35.872
For those pods,
we are okay for all traffic

00:35.952 --> 00:38.244
to go in and out from anywhere.

00:38.401 --> 00:41.448
However, we want to protect
the database pod

00:41.528 --> 00:45.241
and only allow traffic from the API pod.

00:45.503 --> 00:48.199
Let's get the other things out of our way

00:48.279 --> 00:51.307
so we can focus exactly
on the required tasks.

00:51.558 --> 00:55.233
We don't need to worry about
the web pod or its port

00:55.336 --> 00:57.643
as we don't want to allow any traffic

00:57.723 --> 01:01.219
from any other sources
other than the API pod.

01:01.624 --> 01:03.662
Let's get rid of that.

01:03.858 --> 01:07.635
We can also forget about
the port on the API pod

01:07.715 --> 01:11.632
to which the web server connects
as we don't care about that either.

01:12.074 --> 01:13.905
As we discussed, by default,

01:13.978 --> 01:18.576
Kubernetes allows all traffic
from all pods to all destinations.

01:18.978 --> 01:20.356
As the first step,

01:20.436 --> 01:25.537
we want to block out everything
going in and out of the database pod.

01:25.917 --> 01:30.286
We create a network policy,
we will call it DB policy,

01:30.366 --> 01:34.818
and the first step is to associate
this network policy with a pod

01:34.898 --> 01:36.408
that we want to protect.

01:36.644 --> 01:39.366
We do that using labels and selectors.

01:39.761 --> 01:45.436
We do that by adding a pod selector field
with the match labels option.

01:45.700 --> 01:51.681
By specifying the label on the DBpod,
which happens to be set to role DB.

01:53.141 --> 01:56.961
That associates the network policy
with the database pod.

01:57.061 --> 01:59.549
Now, it still doesn't block out traffic

01:59.629 --> 02:02.765
because we haven't specified
policy types yet.

02:02.922 --> 02:06.474
If there are no policy types specified
in the network policy definition,

02:06.554 --> 02:08.398
the protection is not enforced.

02:08.601 --> 02:11.485
Since we'd like to restrict
both ingress and egress traffic,

02:11.565 --> 02:15.108
we will add ingress and egress
to the policy types.

02:15.576 --> 02:20.304
That should block all ingress
and egress traffic on the pod.

02:20.551 --> 02:27.002
However, we need the API pod to be able
to query the database on port 3306.

02:27.186 --> 02:29.820
That's what we're going to configure next.

02:30.122 --> 02:34.287
First, we need to figure out
what type of policies should be defined

02:34.367 --> 02:38.467
on this network policy object
to meet our requirements.

02:38.721 --> 02:42.685
There are two types of policies
that we discussed in the previous lecture.

02:42.772 --> 02:45.421
We have ingress and egress.

02:45.719 --> 02:49.416
Do we need ingress or egress here or both?

02:49.980 --> 02:53.937
You always look at this
from the DB pods perspective.

02:54.096 --> 02:56.219
From the DB pods perspective,

02:56.336 --> 03:00.357
we want to allow incoming
traffic from the API pod.

03:00.631 --> 03:03.718
That is incoming, so that is Ingress.

03:03.807 --> 03:10.807
The API pod makes database queries
and the database pods returns the results.

03:11.724 --> 03:14.138
What about the results?

03:14.253 --> 03:20.816
Do you need a separate rule
for the results to go back to the API pod?

03:21.832 --> 03:25.235
No, because once you allow
incoming traffic,

03:25.315 --> 03:30.502
the response or reply to that traffic
is allowed back automatically,

03:30.582 --> 03:32.951
we don't need a separate rule for that.

03:33.232 --> 03:36.962
In this case, all we need is
an ingress rule to allow traffic

03:37.042 --> 03:39.927
from the API pod to the database pod.

03:40.204 --> 03:44.397
That would allow the API pod
to connect to the database and run queries

03:44.477 --> 03:47.462
and also retrieve
the result of the queries.

03:47.813 --> 03:50.871
When deciding on
what type of rule is to be created,

03:50.951 --> 03:52.586
you only need to be concerned

03:52.666 --> 03:56.434
about the direction
in which the request originate,

03:56.850 --> 03:59.132
which is denoted
by the straight line here.

03:59.332 --> 04:01.647
You don't need
to worry about the response,

04:01.727 --> 04:04.665
which is denoted by the dotted line.

04:04.866 --> 04:07.374
However, this rule does not mean that

04:07.454 --> 04:11.485
the database pod will be able
to connect to the API pod

04:11.565 --> 04:13.565
or make calls to the API.

04:14.235 --> 04:19.502
Say, for example, the database pod
tries to make an API call to the API pod.

04:20.039 --> 04:23.605
That would not be allowed
because that is now an egress traffic

04:23.685 --> 04:25.344
originating from the database pod

04:25.424 --> 04:29.744
and would require
a specific egress rule to be defined.

04:30.086 --> 04:32.223
I hope you get the difference
between the two

04:32.303 --> 04:37.078
and are clear about
ingress and egress rules.

04:37.514 --> 04:39.475
I just wanted to make sure
that you're clear on

04:39.555 --> 04:43.109
what type of policy
is to be selected for the requirement

04:43.203 --> 04:44.875
that you have in hand.

04:45.241 --> 04:46.794
A single network policy can have

04:46.874 --> 04:49.746
an ingress type of rule
and egress type of rule,

04:49.827 --> 04:54.345
or both in cases where a pod wants
to allow incoming connections

04:54.425 --> 04:57.342
as well as
wants to make external calls.

04:57.602 --> 05:02.311
For now, our use case
only requires ingress policy types.

05:02.434 --> 05:04.976
Now that we have decided
on the type of policy,

05:05.056 --> 05:09.330
the next step is to define
the specifics of that policy.

05:09.982 --> 05:14.403
If it's ingress,
we create a section called ingress,

05:14.553 --> 05:17.680
within which we can specify
multiple rules.

05:17.856 --> 05:21.012
Each rule has a from and pods fields.

05:21.182 --> 05:23.546
The from field
defines the source of traffic

05:23.626 --> 05:26.683
that is allowed to pass through
to the database pod.

05:27.324 --> 05:29.423
Here we would use a pod selector

05:29.503 --> 05:33.308
and provide the labels
of the API pod like this.

05:33.591 --> 05:37.196
The ports field defines
what pod on the database pod

05:37.277 --> 05:39.126
is the traffic allowed to go to.

05:39.244 --> 05:44.687
In this case, it's 3306
with the TCP protocol and that's it.

05:44.757 --> 05:46.255
This would create a policy

05:46.335 --> 05:52.591
that would block all traffic to the DB pod
except for traffic from the API pod.

05:53.160 --> 05:55.316
Now, what if there are multiple API pods

05:55.396 --> 05:58.867
in the cluster with the same labels
but in different name spaces?

05:58.987 --> 06:01.984
Here we have different name spaces
for dev, staging,

06:02.064 --> 06:04.694
and prod environments,
and we have the API pod

06:04.820 --> 06:07.534
with the same labels
in each of these environment.

06:07.631 --> 06:12.448
Now first, if you are creating
a network policy for the prod namespace,

06:12.528 --> 06:15.250
which is a namespace
other than the default namespace,

06:15.353 --> 06:17.910
then it should have
the namespace defined

06:18.005 --> 06:22.474
as prod on the network
policy object definition.

06:22.613 --> 06:26.287
Now, by default,
this policy will only allow the pod

06:26.367 --> 06:27.558
in the prod name space,

06:27.638 --> 06:30.272
which is the same name space
as that of the network policy

06:30.352 --> 06:33.296
with matching labels
to reach the database pod,

06:33.511 --> 06:37.856
but what if for some reason
we want the pod in the staging name space,

06:37.937 --> 06:39.362
which is another name space

06:39.443 --> 06:42.078
to reach the database
in the production name space.

06:44.952 --> 06:47.538
For this, we add
a namespace selector property

06:47.617 --> 06:50.350
as well along with
the pod selector property.

06:50.465 --> 06:55.167
Under this, we use match labels again
to provide a label set on the namespace.

06:55.408 --> 06:58.928
Remember, you must have
this label set on the namespace first

06:59.008 --> 07:01.602
for this to work, so just note that.

07:01.850 --> 07:03.472
That's what the namespace selector does.

07:03.552 --> 07:06.741
It helps in defining
from what namespace traffic is allowed

07:06.821 --> 07:09.542
to reach to the database pod.

07:09.652 --> 07:12.118
Now what if you only have
the namespace selector

07:12.198 --> 07:14.861
and not the pod selector like this?

07:14.965 --> 07:18.342
In that case,
all pods within the specified namespace

07:18.482 --> 07:24.898
will be allowed to reach the database pod,
such as the web pod in the staging space,

07:25.052 --> 07:29.045
but pods from outside this namespace
won't be allowed to go through.

07:29.603 --> 07:33.061
Let's change that namespace selector
back to prod for now

07:33.141 --> 07:36.253
and continue with our example.

07:37.641 --> 07:39.452
Let's look at another use case.

07:39.626 --> 07:44.560
Say we have a backup server somewhere
outside of a Kubernetes cluster,

07:44.652 --> 07:48.637
and we want to allow this server
to connect to the database pod.

07:48.903 --> 07:53.296
Now since this backup server
is not deployed in our Kubernetes cluster,

07:53.428 --> 07:55.977
the pod selector
and namespace selector fields

07:56.057 --> 07:59.833
that we use to define traffic
from won't work,

08:00.139 --> 08:02.723
because it's not a pod in the cluster.

08:03.151 --> 08:06.171
However, we know
the IP address of the backup server

08:06.251 --> 08:10.246
and that happens to be 192.168.5.10.

08:11.485 --> 08:13.568
We could configure a network policy

08:13.648 --> 08:18.493
to allow traffic originating
from certain IP addresses.

08:18.861 --> 08:22.193
For this,
we add a new type of from definition

08:22.273 --> 08:24.834
known as the IP block definition.

08:24.914 --> 08:28.523
IP block allows you
to specify a range of IP addresses

08:28.603 --> 08:32.695
from which you could allow traffic
to hit the database pod.

08:33.601 --> 08:40.081
Those are three supported selectors
under the from section and ingress,

08:40.316 --> 08:43.975
and these are also applicable
to the two section in egress

08:44.100 --> 08:46.769
and we'll see that in a few minutes.

08:47.001 --> 08:50.333
We have pod selector
to select pods by labels.

08:50.413 --> 08:53.572
We have namespace selector
to select name spaces by labels,

08:53.652 --> 08:57.776
and we have the IP block selector
to select IP address ranges.

08:58.672 --> 09:00.812
These can be passed in separately

09:00.892 --> 09:05.015
as individual rules
or together as part of a single rule.

09:05.225 --> 09:09.497
In this example, under the from section,
we have two elements,

09:09.642 --> 09:11.862
so these are two rules.

09:11.971 --> 09:16.237
The first rule has the pod selector
and the namespace selector together,

09:16.317 --> 09:19.769
and the second rule
has the IP block selector.

09:20.046 --> 09:22.788
This works like an or operation.

09:23.162 --> 09:25.025
Traffic from sources meeting

09:25.105 --> 09:28.385
either of these criteria
are allowed to pass through.

09:28.775 --> 09:31.480
However, within the first rule,

09:31.688 --> 09:33.738
we have two selectors pod of it

09:33.939 --> 09:36.405
that would mean traffic from sources

09:36.520 --> 09:40.448
must meet both
of these criteria to pass through,

09:40.570 --> 09:45.473
so they have to be resonating from pods
with matching labels of API pod,

09:45.607 --> 09:49.116
and those pods must be
in the prod namespace,

09:49.436 --> 09:52.405
so it works like an and operation.

09:52.653 --> 09:55.026
Now what if we were to separate them

09:55.106 --> 09:59.190
by adding a dash
before the namespace selector like this?

09:59.411 --> 10:02.448
Now they are two separate rules.

10:02.795 --> 10:06.901
This would mean that traffic
matching the first rule is allowed,

10:07.000 --> 10:10.739
that is from any pod matching

10:10.891 --> 10:14.546
the label API pod in the same namespace,

10:14.652 --> 10:18.248
and traffic matching
the second rule is allowed,

10:18.345 --> 10:23.122
which is from any pod
within the prod namespace

10:23.579 --> 10:28.773
that is either from the pod web
and of course along with the backup server

10:28.853 --> 10:31.896
as we have the IP block
specification as well.

10:32.632 --> 10:34.658
Now we have three separate rules

10:34.738 --> 10:40.074
and almost traffic from anywhere
is allowed to the DB pod.

10:40.356 --> 10:43.479
A small change that can have a big impact.

10:43.697 --> 10:45.033
It's important to understand

10:45.113 --> 10:49.763
how you could put together these rules
based on your requirements.

10:50.145 --> 10:54.759
Now let's get rid of all of that
and go back to a basic set of rules.

10:55.077 --> 10:57.293
We'll now look at egress.

10:57.548 --> 11:02.275
Say for example, instead of
the backup server initiating a backup,

11:02.404 --> 11:07.238
say we have an agent on the DB pod
that pushes backup to the backup server.

11:07.318 --> 11:10.231
In that case, the traffic is originating

11:10.311 --> 11:13.641
from the database pod
to an external backup server.

11:13.893 --> 11:17.883
For this,
we need to have egress rule defined.

11:18.696 --> 11:21.479
We first add egress to the policy types,

11:21.546 --> 11:26.197
and then we add a new egress section
to define the specifics of the policy.

11:27.012 --> 11:31.477
Instead of from,
we now have two under egress.

11:31.606 --> 11:33.315
That's the only difference.

11:33.576 --> 11:37.147
Under two, we could use
any of the selectors such as a pod,

11:37.227 --> 11:38.745
a namespace,

11:39.046 --> 11:41.447
or an IP block selector.

11:41.586 --> 11:43.898
In this case,
since the database server is external

11:43.978 --> 11:48.915
we use IP block selector
and provide the cidr block for the server.

11:49.024 --> 11:52.441
The port to which the request
are to be sent to is 80,

11:52.521 --> 11:55.389
so we specify 80 as the port.

11:56.435 --> 12:00.677
This rule allows traffic originating
from the database pod

12:00.757 --> 12:04.402
to an external backup server
at the specified address.

12:05.712 --> 12:08.636
That's it for now
about network policies and roles.

12:08.717 --> 12:13.629
Head over to the lab and practice
working with network policies yourself.

12:13.863 --> 12:15.627
I will see you in the next one.

