-In this lecture,
we will take a look at network policies in more detail.
Here we have the same web API and database pods
that we discussed about in the previous lecture.
First, let's be very clear with our requirements.
Our goal is to protect the database pod
so that it does not allow access from any other pod,
except the API pod, and only on port 3306.
Let's assume that we are not concerned about the web pod or the API pod.
For those pods, we are okay for all traffic
to go in and out from anywhere.
However, we want to protect the database pod
and only allow traffic from the API pod.
Let's get the other things out of our way
so we can focus exactly on the required tasks.
We don't need to worry about the web pod or its port
as we don't want to allow any traffic
from any other sources other than the API pod.
Let's get rid of that.
We can also forget about the port on the API pod
to which the web server connects as we don't care about that either.
As we discussed, by default,
Kubernetes allows all traffic from all pods to all destinations.
As the first step,
we want to block out everything going in and out of the database pod.
We create a network policy, we will call it DB policy,
and the first step is to associate this network policy with a pod
that we want to protect.
We do that using labels and selectors.
We do that by adding a pod selector field with the match labels option.
By specifying the label on the DBpod, which happens to be set to role DB.
That associates the network policy with the database pod.
Now, it still doesn't block out traffic
because we haven't specified policy types yet.
If there are no policy types specified in the network policy definition,
the protection is not enforced.
Since we'd like to restrict both ingress and egress traffic,
we will add ingress and egress to the policy types.
That should block all ingress and egress traffic on the pod.
However, we need the API pod to be able to query the database on port 3306.
That's what we're going to configure next.
First, we need to figure out what type of policies should be defined
on this network policy object to meet our requirements.
There are two types of policies that we discussed in the previous lecture.
We have ingress and egress.
Do we need ingress or egress here or both?
You always look at this from the DB pods perspective.
From the DB pods perspective,
we want to allow incoming traffic from the API pod.
That is incoming, so that is Ingress.
The API pod makes database queries and the database pods returns the results.
What about the results?
Do you need a separate rule for the results to go back to the API pod?
No, because once you allow incoming traffic,
the response or reply to that traffic is allowed back automatically,
we don't need a separate rule for that.
In this case, all we need is an ingress rule to allow traffic
from the API pod to the database pod.
That would allow the API pod to connect to the database and run queries
and also retrieve the result of the queries.
When deciding on what type of rule is to be created,
you only need to be concerned
about the direction in which the request originate,
which is denoted by the straight line here.
You don't need to worry about the response,
which is denoted by the dotted line.
However, this rule does not mean that
the database pod will be able to connect to the API pod
or make calls to the API.
Say, for example, the database pod tries to make an API call to the API pod.
That would not be allowed because that is now an egress traffic
originating from the database pod
and would require a specific egress rule to be defined.
I hope you get the difference between the two
and are clear about ingress and egress rules.
I just wanted to make sure that you're clear on
what type of policy is to be selected for the requirement
that you have in hand.
A single network policy can have
an ingress type of rule and egress type of rule,
or both in cases where a pod wants to allow incoming connections
as well as wants to make external calls.
For now, our use case only requires ingress policy types.
Now that we have decided on the type of policy,
the next step is to define the specifics of that policy.
If it's ingress, we create a section called ingress,
within which we can specify multiple rules.
Each rule has a from and pods fields.
The from field defines the source of traffic
that is allowed to pass through to the database pod.
Here we would use a pod selector
and provide the labels of the API pod like this.
The ports field defines what pod on the database pod
is the traffic allowed to go to.
In this case, it's 3306 with the TCP protocol and that's it.
This would create a policy
that would block all traffic to the DB pod except for traffic from the API pod.
Now, what if there are multiple API pods
in the cluster with the same labels but in different name spaces?
Here we have different name spaces for dev, staging,
and prod environments, and we have the API pod
with the same labels in each of these environment.
Now first, if you are creating a network policy for the prod namespace,
which is a namespace other than the default namespace,
then it should have the namespace defined
as prod on the network policy object definition.
Now, by default, this policy will only allow the pod
in the prod name space,
which is the same name space as that of the network policy
with matching labels to reach the database pod,
but what if for some reason we want the pod in the staging name space,
which is another name space
to reach the database in the production name space.
For this, we add a namespace selector property
as well along with the pod selector property.
Under this, we use match labels again to provide a label set on the namespace.
Remember, you must have this label set on the namespace first
for this to work, so just note that.
That's what the namespace selector does.
It helps in defining from what namespace traffic is allowed
to reach to the database pod.
Now what if you only have the namespace selector
and not the pod selector like this?
In that case, all pods within the specified namespace
will be allowed to reach the database pod, such as the web pod in the staging space,
but pods from outside this namespace won't be allowed to go through.
Let's change that namespace selector back to prod for now
and continue with our example.
Let's look at another use case.
Say we have a backup server somewhere outside of a Kubernetes cluster,
and we want to allow this server to connect to the database pod.
Now since this backup server is not deployed in our Kubernetes cluster,
the pod selector and namespace selector fields
that we use to define traffic from won't work,
because it's not a pod in the cluster.
However, we know the IP address of the backup server
and that happens to be 192.168.5.10.
We could configure a network policy
to allow traffic originating from certain IP addresses.
For this, we add a new type of from definition
known as the IP block definition.
IP block allows you to specify a range of IP addresses
from which you could allow traffic to hit the database pod.
Those are three supported selectors under the from section and ingress,
and these are also applicable to the two section in egress
and we'll see that in a few minutes.
We have pod selector to select pods by labels.
We have namespace selector to select name spaces by labels,
and we have the IP block selector to select IP address ranges.
These can be passed in separately
as individual rules or together as part of a single rule.
In this example, under the from section, we have two elements,
so these are two rules.
The first rule has the pod selector and the namespace selector together,
and the second rule has the IP block selector.
This works like an or operation.
Traffic from sources meeting
either of these criteria are allowed to pass through.
However, within the first rule,
we have two selectors pod of it
that would mean traffic from sources
must meet both of these criteria to pass through,
so they have to be resonating from pods with matching labels of API pod,
and those pods must be in the prod namespace,
so it works like an and operation.
Now what if we were to separate them
by adding a dash before the namespace selector like this?
Now they are two separate rules.
This would mean that traffic matching the first rule is allowed,
that is from any pod matching
the label API pod in the same namespace,
and traffic matching the second rule is allowed,
which is from any pod within the prod namespace
that is either from the pod web and of course along with the backup server
as we have the IP block specification as well.
Now we have three separate rules
and almost traffic from anywhere is allowed to the DB pod.
A small change that can have a big impact.
It's important to understand
how you could put together these rules based on your requirements.
Now let's get rid of all of that and go back to a basic set of rules.
We'll now look at egress.
Say for example, instead of the backup server initiating a backup,
say we have an agent on the DB pod that pushes backup to the backup server.
In that case, the traffic is originating
from the database pod to an external backup server.
For this, we need to have egress rule defined.
We first add egress to the policy types,
and then we add a new egress section to define the specifics of the policy.
Instead of from, we now have two under egress.
That's the only difference.
Under two, we could use any of the selectors such as a pod,
a namespace,
or an IP block selector.
In this case, since the database server is external
we use IP block selector and provide the cidr block for the server.
The port to which the request are to be sent to is 80,
so we specify 80 as the port.
This rule allows traffic originating from the database pod
to an external backup server at the specified address.
That's it for now about network policies and roles.
Head over to the lab and practice working with network policies yourself.
I will see you in the next one.