Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

 

Contrail Implementation Details

 

We’ve reiterated that Contrail implements Kubernetes network policy with a Contrail firewall security policy. You also know that Kubernetes labels are exposed as tags in Contrail. These tags are used by Contrail security policy to implement specified Kubernetes policies. Tags will be created automatically from Kubernetes objects labels or created manually in the UI.

In this section we’ll take a closer look at the Contrail firewall policies, policy rules, and the tags. In particular, we’ll examine the mapping relationships between the Kubernetes objects that we created and tested in the last section, and the corresponding Contrail objects in Contrail firewall system.

Contrail firewall is designed with a hierarchical structure:

  • The top level object is named Application Policy Set, abbreviated as APS.

  • APS has firewall policies.

  • Firewall policy has firewall rules.

  • Firewall rules have the endpoints.

  • Endpoints can be identified via tags or address groups (CIDRs).

The structure is illustrated in Figure 1.

Figure 1: Contrail Firewall
Contrail Firewall

Construct Mappings

Kubernetes network policy and Contrail firewall policy are two different entities in terms of the semantics of the network policy in which each is specified. In order for Contrail firewall to implement Kubernetes network policy, Contrail needs to implement the one-to-one mapping for a lot of data construct from Kubernetes to Contrail firewall. These data constructs are the basic building blocks of Kubernetes network policy and the corresponding Contrail firewall policy.

Table 1 lists Kubernetes network policy constructs and the corresponding constructs in Contrail:

Table 1: K8s Network Policy And Contrail Firewall Construct Mapping

K8s Network Policy Construct

Contrail Firewall Construct

Cluster Name

APS (one per k8s cluster)

Network Policy

Firewall Policy (one per k8s network policy)

Ingress and Egress policy rule

Firewall Rule (one per k8s ingress/egress policy rule)

CIDR

Address Group(one per k8s network policy CIDR )

Label

Tag (one for each k8s label)

Namespace

Custom Tag (one for each namespace)

The contrail-kube-manager, the KM, as we’ve read many times earlier in this book, does all of the translations between the two worlds. Basically the following will happen in the context of Kubernetes network policy:

  1. The KM will create an APS with a Kubernetes cluster name during its initialing process. Typically the default Kubernetes cluster name is k8s, so you will see an APS with the same name in your cluster.

  2. The KM registers to kube-apiserver to watch the network policies events.

  3. Whenever a Kubernetes network policy is created, a corresponding Contrail firewall policy will be created with all matching firewall rules and network endpoints.

  4. For each label created in a Kubernetes object there will be a corresponding Contrail tag created.

  5. Based on the tag, the corresponding Contrail objects (VN, pods, VMI, projects, etc.) can be located.

  6. Contrail will then apply the Contrail firewall policies and rules in the APS on the Contrail objects, this is how the specific traffic is permitted or denied.

The APS can be associated to different Contrail objects, for example:

  • VMI (virtual machine interface)

  • VM (virtual machine) or pods

  • VN (virtual network)

  • project

In Contrail Kubernetes cluster, the APS is associated to virtual network. Whenever traffic goes on those networks, firewall policies associated on the APS would be evaluated and respective action would be taken for the traffic.

In the previous section, we created two Kubernetes network policies in our use case. Now let’s explore the Contrail objects that are created for these Kubernetes network policies.

Application Policy Set (APS)

As mentioned, contrail-kube-manager will create an APS using the Kubernetes cluster name during the initialization stage. In Chapter 3, when we introduced Contrail Namespaces and Isolation, we learned the cluster name is k8s by default in Contrail. Therefore the APS name will also be k8s in the Contrail UI shown in Figure 2.

Figure 2: Contrail UI: APS Configure> Security > Global Policies > Application Policy Sets
Contrail UI: APS Configure> Security > Global Policies > Application
Policy Sets

There is one more APS default-application-policy-set that is created by default.

Policies

Now click on Firewall Policies to display all firewall polices in the cluster. In our test environment, you will find the following policies available:

  • k8s-dev-policy1

  • k8s-dev-policy2

  • k8s-denyall

  • k8s-allowall

  • k8s-Ingress

Figure 3: Contrail UI: Firewall Policies
Contrail UI:
Firewall Policies

Contrail Firewall Policy Naming Convention

The k8s-dev-policy1 and k8s-dev-policy2 policies are what we’ve created. Although they look different from the object names we gave in our YAML file, it is easy to tell which is which. When KM creates the Contrail firewall policies based on the Kubernetes network policies, it prefixes the firewall policy name with the cluster name, plus the namespace, in front of our network policy name:

This should sound familiar. Earlier we showed how KM names the virtual network in Contrail UI after the Kubernetes virtual network objects name we created in the YAML file.

The K8s-ingress firewall policy is created for the ingress loadbalancer to ensure that ingress to works properly in Contrail. A detailed explanation is beyond the scope of this book.

But the bigger question is, why do we still see two more firewall policies here, since we have never created any network policies like allowall, or denyall?

Well, remember when we introduced Kubernetes network policy back in Chapter 3, and mentioned that Kubernetes network policy uses a whitelist method and the implicit deny all and allow all policies? The nature of the whitelist method indicates deny all action for all traffic other than what is added in the whitelist, while the implicit allow all behavior makes sure a pod that is not involved in any network policies can continue its allow-any-any traffic model. The problem with Contrail firewall regarding this implicitness is that by default it follows a deny all model - anything that is not explicitly defined will be blocked. That is why in Contrail implementation, these two corresponding implicit network policies are honored by two explicit policies generated by the KM module.

One question may be raised at this point. With multiple firewall policies, which one should be applied and evaluated first and which ones later? In other words, in what sequence will Contrail apply and evaluate each policy – a firewall policy evaluation with a different sequence will lead to completely different result. Just imagine these two sequences denyall - allowall versus allowall - denyall. The former gives a deny to all other pods, while the latter gives a pass The answer is the sequence number.

Sequence Number

When firewall polices in an APS are evaluated, they have to be evaluated in a certain sequence. All firewall polices and all firewall rules (we will come to this soon) in each of the policies has a sequence number. When there is a matching policy, it will be executed, and the evaluation will stop. It is again contrail-Kube-manager that allocates the right sequence number for all firewall policies and firewall rules, so that everything works in the correct order. The process is automatically done without manual intervention. You don’t have to worry about these things when you create the Kubernetes network policies.

We’ll visit sequence numbers again later, but for now let’s look at the rules defined in the firewall policy.

Firewall Policy Rules

In the following capture of the Firewall Policies list, on the right side you can see the number of Rules for each policy.

Figure 4: Contrail UI:Firewall Policy Rules
Contrail
UI:Firewall Policy Rules

There are four rules for the k8s-dev-policy1 policy. Clicking on Rules will show the rules in detail as in Figure 5.

Figure 5: Contrail UI: k8s-dev-policy1 Rules
Contrail
UI: k8s-dev-policy1 Rules

It looks similar to the Kubernetes network policy policy1 that we’ve tested. Let’s put the rules, displayed in the screen captures, into Table 2.

Table 2: Rules

Rule#

Action

Services

End Point1

Dir

End Point2

Match Tags

1

Pass

tcp:80

project=jtac

>

app=webserver-dev && namespace=dev

-

2

Pass

tcp:80

app=client1-dev && namespace=dev

>

app=webserver-dev && namespace=dev

-

3

Pass

tcp:80

app=webserver-dev && namespace=dev

>

app=dbserver-dev && namespace=dev

-

4

Pass

tcp:80

Address Group: 10.169.25.20/32

>

app=webserver-dev && namespace=dev

-

The first column of Table 8.2 is the rule number that we added; all other columns are imported from the UI screenshot. Now let’s compare it with the Kubernetes object information:

The rules we see in firewall policy k8s-dev-policy1 match with rules in Kubernetes network policy policy1.

Rules in k8s-denyall Firewall Policy

Now let’s go back and examine the rules in the k8s-denyall policy that KM generated for our Kubernetes network policies.

Figure 6: Contrail UI: k8s-denyall Policy Rules
Contrail
UI: k8s-denyall Policy Rules

Again, if we convert that into a table it appears as shown in Table 3.

Table 3: Contrail UI: k8s-denyall Policy Rules

rule#

Action

Services

End Point1

Dir

End Point2

Match Tags

1

deny

any:any

app=webserver-dev && namespace=dev

>

any

-

2

deny

any:any

any

>

app=dbserver-dev && namespace=dev

-

3

deny

any:any

any

>

app=webserver-dev && namespace=dev

-

The k8s-alldeny rules are simple. They just tell Contrail to deny communication with all other pods that are not in the whitelist. One thing worth mentioning is that there is a rule in the direction from app=webserver-dev && namespace=dev to any, so that egress traffic is denied for webserver-dev pod, while there is no such a rule from app=dbserver-dev && namespace=dev to any. If you review our test in the last section, in the original policy policy2, we did not define an Egress option in policyTypes to deny egress traffic of dbserver-dev, that is why there is no such rule when translated into Contrail firewall, either. If we change policy2 to the new policy policy2-egress-denyall and examine the same, we’ll see the missing rule now.

Figure 7: Contrail UI: k8s-denyall Rules
Contrail UI:
k8s-denyall Rules

Pay attention to the fact that the k8s-denyall policy only applies to those target pods – pods that are selected by the network policies. In this case it only applies to pods webserver-dev and dbserver-dev. Other pods like client-jtac or client-qa will not be effected. Instead, those pods will be applied by k8s-allowany policy, which we’ll examine next.

Rules in k8s-allowall Firewall Policy

In Figure 8, the k8s-allowall policy seems to have more rules than other policies.

Figure 8: Contrail UI: k8s-allowall Rules
Contrail UI:
k8s-allowall Rules

Despite the number of rules, in fact k8s-allowall is the simplest one. It works at the NS level and simply has two rules for each NS. In the UI, within the search field, key in a namespace as the filter, for example, dev or qa, and you’ll see these results in Figure 9 and Figure 10.

Figure 9: Contrail UI: k8s-allowall Rules Filtered by NS dev
Contrail UI: k8s-allowall Rules Filtered by NS dev
Figure 10: Contrail UI: k8s-allowall Rules Filtered by NS qa
Contrail UI: k8s-allowall Rules Filtered by NS qa

What this policy says is: for those pods that do not have any network policy applied yet, let’s continue the Kubernetes default allow-any-any networking model and allow everything!

Sequence Number

After having explored the Contrail firewall policy rules, let’s come back to the sequence number and see exactly how it works.

The sequence number is a number attached to all firewall policies and their rules that decides the order in which all policies are applied and evaluated, and does the same in one particular policy. The lower the sequence number the higher the priority. To find the sequence number you have to look into the firewall policy and policy rule object attributes in Contrail configuration database.

First let’s explore the firewall policy object in APS to check their sequence number.

Tip

In Chapter 5 we used the curl command to pull the loadbalancer object data when we introduced service. Here we used Config Editor to do the same.

Figure 11 and Figure 12 capture the sequence number in firewall policies.

Figure 11: Contrail UI: Sequence Number for Policies: Setting> Config Editor
Contrail UI: Sequence Number for Policies: Setting> Config
Editor
Figure 12: Contrail UI: Sequence Number for Policies (continued)
Contrail UI: Sequence Number for Policies (continued)

All five policies that we’ve seen appear in these screenshots, under APS k8s. For example, the policy k8s-dev-policy1, which maps to the Kubernetes network policy policy1 that we explicitly defined, and the policy k8s-denyall, which is what the system automatically generated. The figures show k8s-dev-policy1 and k8s-denyall have sequence numbers of 00038.0 and 00042.0, respectively. Therefore k8s-dev-policy1 has a higher priority and it will be applied and evaluated first. That means the traffic types we defined in the whitelist will be allowed first, then all other traffic to or from the target pod will be denied. This is the exact goal that we wanted to achieve.

All sequence numbers for all firewall policies are listed in Table 4, from the highest priority to the lowest:

Table 4: Sequence Numbers

Sequence Number

Firewall Policy

00002.0

k8s-Ingress

00038.0

k8s-dev-policy1

00040.0

k8s-dev-policy2

00042.0

k8s-denyall

00043.0

k8s-allowall

Based on the sequence number, the application and evaluation order are the first explicit policies, followed by the deny all policy and ending with the allow all policy. The same order as in Kubernetes is honored.

Sequence Number in Firewall Policy Rules

Figure 13: Contrail UI Sequence Number for Rules: Setting> Config Editor
Contrail UI Sequence Number for Rules: Setting> Config Editor

As mentioned previously, in the same firewall policy, policy rules will also have to be applied and evaluated in a certain order. In Contrail firewall that is again ensured by the sequence number. The sequence numbers in the rules of firewall policy k8s-dev-policy1 are displayed in Figure 13 and Figure 14.

Figure 14: Contrail UI Sequence Number for Rules (continued)
Contrail UI Sequence Number for Rules (continued)

And Table 5 lists the sequence number of all rules of the firewall policy k8s-dev-policy1, from highest priority to the lowest.

Table 5: Sequence Numbers for Policy1

seq#

firewall rule

00000.0

dev-ingress-policy1-0-ipBlock-0-cidr-10.169.25.20/32-0

00001.0

dev-ingress-policy1-0-namespaceSelector-1-0

00002.0

dev-ingress-policy1-0-podSelector-2-0

00003.0

dev-egress-policy1-podSelector-0-0

Let’s compare with our network policy YAML file configuration:

We find that the rules sequence number is consistent with the sequence that appears in the YAML file. In other words, rules will be applied and evaluated in the same order as they are defined.

Tag

We’ve been talking about the Contrail tags and we already know that contrail-kube-manager will translate each Kubernetes label into a Contrail tag, which is attached to the respective port of a pod as shown in Figure 15.

Figure 15: Tags UI
Tags UI

UI Visualization

Contrail UI provides a nice visualization for security as shown in Figure 16. It’s self - explanatory if you know how Contrail security works.

Figure 16: Sample Traffic Visualization for the Above Policy with Workload
Sample Traffic Visualization for the Above Policy with Workload
Figure 17: Sample Traffic Visualization with More Network Policies
Sample Traffic Visualization with More Network Policies