June 29, 2024| 0 minute read

Fundamentals of Kubernetes Network Policy Simplified - Part 2

Tutorial Image

Source: www.cajieh.com

Pre-requisite:

  • Basic knowledge of Container technology and kubernetes are required
  • Proficient in the use of command line tools i.e. Bash terminal
  • Access to a Kubernetes cluster that supports NetworkPolicy if you want to experiment with the example in this tutorial

Introduction

NetworkPolicy is a key technique for isolating and restricting pod-to-pod communications in Kubernetes cluster environment. They are often used to control the access to/from pods in the same namespace or separate namespaces. By default, every pod can communicate with each other and have unrestricted access which is not ideal in most situations.

In part 1 of this tutorial series, I demonstrated how Kubernetes NetworkPolicy resources are implemented in the same namespace by creating three pods in the default namespace: frontend, backend, and database. Then, I applied it to control the flow of traffic from/to pod resources according to the specifications. To see part 1 on Fundamentals of Kubernetes Network Policy Simplified, click the following link: Fundamentals of Kubernetes NetworkPolicy Simplified

In this tutorial, I'll be explaining the fundamentals of Kubernetes NetworkPolicy, using an example of pod communication within separate or interconnecting namespaces In the part 1 of the tutorial, I mentioned that there are four unique selector types that can be used to target endpoints which are:

  • podSelector: Select a particular pod and allow traffic to/from communication with Pods that match a specific label in the same namespace
  • namespaceSelector: Select particular namespaces for which all pods within the namespace are granted permission to communicate
  • podSelector and namespaceSelector: Select a combination of namespaceSelector and podSelector for specific Pods within certain namespaces.
  • ipBlock: Select an IP address within the specified block and allow the connection.

An example of Kubernetes NetworkPolicy specifications and implementation for inter-namespace communications

To demonstrate how the Kubernetes NetworkPolicy resource works for inter-namespace pod communications, let's start by creating two namespaces, namely houston and durham, and a pod in each, named pod1 and pod2 respectively. Then to valid the implementation, let’s create a pod in the default namespace and name it pod-test.

Usually, I like using alias command to shorten the kubectl command e.g. alias k=kubectl This would allow me to use the letter k instead of kubectl which makes typing easy and fast.

k create ns houston
namespace/houston created
k create ns durham 
namespace/durham created
k run pod1 --image=nginxdemos/hello:plain-text -n houston
pod/pod1 created
k run pod2 --image=nginxdemos/hello:plain-text -n durham 
pod/pod2 created
k run pod-test --image=nginxdemos/hello:plain-text           
pod/pod-test created

Verify that each pod can communicate with each other

Get the pod IP addresses

k get po -o wide -n houston          
NAME   READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          7m54s   192.168.0.11   controlplane   <none>           <none>

k get po -o wide -n durham
NAME   READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
pod2   1/1     Running   0          7m53s   192.168.0.12   controlplane   <none>           <none>
co

k get po -o wide          
NAME       READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
pod-test   1/1     Running   0          87s     192.168.0.13   controlplane   <none>           <none>

Verify pod1 in houston namespace can access pod2 in durham namespace

k -n houston exec -it pod1 -- curl 192.168.0.12
Server address: 192.168.0.12:80
Server name: pod2
Date: 26/Jun/2024:20:10:23 +0000
URI: /
Request ID: 2bdb7b18d75dc2dce6dcdd12623c8960

Verify pod2 in durham namespace can access pod2 houston namespace

k -n durham exec -it pod2 -- curl 192.168.0.11
Server address: 192.168.0.11:80
Server name: pod1
Date: 26/Jun/2024:20:11:12 +0000
URI: /
Request ID: 56307ba7893a6e4fbf0217452a15905b

Verify pod-test in default namespace can access pod1 ns houstonnamespace

k exec -it pod-test -- curl 192.168.0.11
Server address: 192.168.0.11:80
Server name: pod1
Date: 26/Jun/2024:20:12:11 +0000
URI: /
Request ID: 25dc1bb7f09ab19f4c666b81192bdbbe

Verify pod-test in default namespace can access pod2 durham namespace

k exec -it pod-test -- curl 192.168.0.12
Server address: 192.168.0.12:80
Server name: pod2
Date: 26/Jun/2024:20:12:46 +0000
URI: /
Request ID: 3157da37dbc3e094cc7e82d53fd35e6b

These are absolutely working as expected because pod communications are non-isolated by default, and given that no NetworkPolicies have been implemented.

Implement two NetworkPolicies to allow connections from/to houston and hurham

Let's implement two NetworkPolicies to allow connections from/to houston and hurham. Refer to the diagram above for a quick overview of the architectural setup of the namespaces, pods, and NetworkPolicy types. The NetworkPolicy rules will allow the egress and ingress traffic from/to the houston and durham namespaces, and deny traffic to and from other namespaces using the namespaceSelector selector on port 80.

houston-np.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: houston-np
  namespace: houston
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: durham
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: durham
    ports:
    - protocol: TCP
      port: 80

The houston-np.yaml Kubernetes NetworkPolicy specification manifest defines a NetworkPolicy named houston-np in the houston namespace. Here's what it does:

  • podSelector: { }- This selects all pods in the houston namespace because it's an empty selector.
  • policyTypes : - This specifies that the policy will apply to both incoming Ingress and outgoing Egress traffic.
  • ingress: This section defines the ingress rules. Where the from specifies the sources of incoming traffic. The namespaceSelector with the matchLabels uses the kubernetes.io/metadata.name to target the namespace of durham. This allows traffic from any pod in the durham namespace. The ports TCP protocol allows incoming TCP traffic on port 80.
  • egress: This section defines the egress rules. Where the to specifies the destinations for outgoing traffic. The namespaceSelector with the matchLabels uses the kubernetes.io/metadata.name to target the namespace of durham. This allows traffic to any pod in the durham namespace. The ports TCP protocol allows incoming TCP traffic on port 80.

In summary, this NetworkPolicy allows TCP traffic on port 80 from/to all pods in the houston namespace to all pods in the durham namespace. Next let's look at the NetworkPolicy specification for durham namespace

durham-np.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: durham-np
  namespace: durham
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: houston
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: houston
    ports:
    - protocol: TCP
      port: 80

The durham-np.yaml Kubernetes NetworkPolicy specification manifest similar vey similar to houston-np.yaml but defines a NetworkPolicy named durham-np in the durham namespace, and podSelector: { } to selects all pods in the durham. Then, it specifies that the policy will apply to both incoming Ingress and outgoing Egress traffic in houston namespace.

Let’s apply the NetworkPolicy using the houston-ns.yaml and durham-np.yaml files

k create -f   houston-ns.yaml
networkpolicy.networking.k8s.io/network-policy created
k create -f   durham-ns.yaml
networkpolicy.networking.k8s.io/network-policy created

Verify the connection again.

k exec -it pod-test -- curl 192.168.0.11
curl: (7) Failed to connect to 192.168.0.11 port 80 after 1012 ms: Couldn't connect to server
command terminated with exit code 7

k exec -it pod-test -- curl 192.168.0.12
curl: (7) Failed to connect to 192.168.0.12 port 80 after 1017 ms: Couldn't connect to server
command terminated with exit code 7

Verify if pod1 houston can still access pod2

k -n houston exec -it pod1 -- curl 192.168.0.12
Server address: 192.168.0.12:80
Server name: pod2
Date: 26/Jun/2024:20:31:51 +0000
URI: /
Request ID: 88e965de127b88e96604edd0580fa41d

Verify if pod2 durham can still access pod1

 k -n durham exec -it pod2 -- curl 192.168.0.11
Server address: 192.168.0.11:80
Server name: pod1
Date: 26/Jun/2024:20:33:45 +0000
URI: /
Request ID: f3f0085f7d7c49cb50cc16c637f0c6b4

Verify that pod1 and pod2 in houston and durham respectively cannot access pods in default namespce.

k -n houston exec -it pod1 -- curl 192.168.0.13
curl: (7) Failed to connect to 192.168.0.13 port 80 after 1012 ms: Couldn't connect to server
command terminated with exit code 7

k -n durham exec -it pod2 -- curl 192.168.0.13
curl: (7) Failed to connect to 192.168.0.13 port 80 after 1012 ms: Couldn't connect to server
command terminated with exit code 7

That concludes the fundamentals of Kubernetes NetworkPolicy on how to restrict access across namespaces using the NetworkPolicy resource. This was explained with an example of inter-namespace pod communication using the Egress and Ingress policy types and the namespaceSelector selector.

I hope this helps! Go to the contact page and let me know if you have any further questions.

Happy learning!

Additional resources:

Want more tutorials?

Subscribe and get notified whenever new tutorials get added to the collection.

By submitting this form, I agree to cajieh.com Privacy Policy.