Mastering Network Policies in Kubernetes

By default, Kubernetes pods accept traffic from any source. A network policy helps define how groups of pods communicate with each other and other network endpoints. NetworkPolicy uses labels to select pods and set rules that specify what traffic is allowed to those pods. Once a NetworkPolicy is applied to a particular pod, that pod will reject any connection not allowed by the policy. Pods not governed by any NetworkPolicy will continue to accept all traffic.

For more detailed information about NetworkPolicy, visit the official Kubernetes documentation.

This guide will demonstrate the use of Ingress and Egress NetworkPolicy, where ingress refers to incoming traffic to the pod, and egress refers to outgoing traffic from the pod.

Pre-requisites

  1. Kubernetes Cluster with at least one worker node. If you’re new to setting up a Kubernetes Cluster, follow this step-by-step guide to create a cluster with one Master and two Nodes on AWS Ubuntu 18.04 EC2 Instances.

Objectives

  1. Learn how to create Network Policies.

Create Network Policies

Ingress Network Policy

Create a pod named ‘hello-web’ with the label “app=destination-pod” and a service. We will allow incoming traffic on port 8080.

kubectl run hello-web --labels app=destination-pod --image=gcr.io/google-samples/hello-app:1.0 --port 8080 --expose
kubectl get pod | grep hello-web
kubectl get service | grep hello-web

create-a-pod-and-a-service

Create an ingress definition file, ‘ingress.yml’, to allow traffic to the “hello-web” pod from another pod with the label “app=source-pod”.

vim ingress.yml
kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: destination-pod-allow-from-source-pod
    spec:
      policyTypes:
      - Ingress
      podSelector:
        matchLabels:
          app: destination-pod
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: source-pod

ingress-network-policy-definition

Before creating the ingress policy, create a pod with the label “app=unknown”, which does not match the policy rule.

kubectl run -l app=unknown --image=alpine --restart=Never --rm -i -t test-1

Attempt to access the “hello-web” pod on port 8080 from this pod. Initially, the pod is accessible.

wget -qO- --timeout=2 http://hello-web:8080

create-unknown-pod

Create the policy that allows connections from a pod with the label “app=source-pod” to the pod with the label “app=destination-pod”.

kubectl apply -f ingress.yml
kubectl get networkpolicy destination-pod-allow-from-source-pod

create-ingress-network-policy

Create another pod with a label that does not match the policy.

kubectl run -l app=unknown --image=alpine --restart=Never --rm -i -t test-1

Attempt to access the “hello-web” pod from this pod again. This time, the “hello-web” pod is not reachable.

wget -qO- --timeout=2 http://hello-web:8080

try-to-access-from-unknown-pod

Now, create a pod matching the network policy rule with label “app=source-pod”.

kubectl run -l app=source-pod --image=alpine --restart=Never --rm -i -t test-1

Attempt to access the “hello-web” pod from the pod with label “app=source-pod”. The pod is accessible.

wget -qO- --timeout=2 http://hello-web:8080

access-from-known-pod

The above screenshot shows that the “hello-web” pod was accessible from the pod with label “app=source-pod”, demonstrating that our policy restricts connections to desired pods only.

Egress Network Policy

Create a new file, ‘egress.yml’, with the following content.

vim egress.yml
kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: source-pod-allow-to-destination-pod
    spec:
      policyTypes:
      - Egress
      podSelector:
        matchLabels:
          app: source-pod
      egress:
      - to:
        - podSelector:
            matchLabels:
              app: destination-pod
      - ports:
        - port: 53
          protocol: TCP
        - port: 53
          protocol: UDP

egress-network-policy-definition

This policy allows outgoing connections from pods labeled “app=source-pod” to pods labeled “app=destination-pod”, including DNS resolution on port 53.

Before applying the Egress Policy, create a pod “hello-web-2” and service that do not match the policy.

kubectl run hello-web-2 --labels app=hello-2 --image=gcr.io/google-samples/hello-app:1.0 --port 8080 --expose
kubectl get pod | grep hello-web-2
kubectl get service | grep hello-web-2

create-unknown-application

Create a pod labeled “app=source-pod”. Before applying the Egress policy, both “hello-web” and “hello-web-2” are accessible.

kubectl run -l app=source-pod --image=alpine --restart=Never --rm -i -t test-2
wget -qO- --timeout=2 http://hello-web:8080
wget -qO- --timeout=2 http://hello-web-2:8080

access-unknown-application-available

Create the Network policy with the egress rule.

kubectl create -f egress.yml
kubectl get networkpolicy | grep source-pod-allow-to-destination-pod

create-egress-network-policy

Create another pod labeled “app=source-pod” and attempt to access both that pod and the “hello-web” pod.

kubectl run -l app=source-pod --image=alpine --restart=Never --rm -i -t test-3
wget -qO- --timeout=2 http://hello-web:8080
wget -qO- --timeout=2 http://hello-web-2:8080

access-unknown-application-not-available

The screenshot demonstrates that the “hello-web-2” pod is no longer accessible because it does not meet the egress policy criteria of allowing connections from pods labeled “app=source-pod” only to pods labeled “app=destination-pod”.

Conclusion

In this guide, we explained the steps required to create both an ingress and egress network policy. Additionally, we demonstrated how these policies can be used to restrict both incoming and outgoing traffic using a simple web-app example.

Frequently Asked Questions (FAQ)

Q1: What is a Network Policy in Kubernetes?

A Network Policy in Kubernetes is a specification of how groups of pods are allowed to communicate with each other and other network endpoints.

Q2: What are Ingress and Egress in Network Policies?

Ingress is the incoming traffic to the pod, while Egress is the outgoing traffic from the pod. Network Policies can be used to control both types of traffic.

Q3: How do Network Policies use labels?

Network Policies utilize labels to select the pods to which they apply. These labels help define rules that specify permitted traffic to the selected pods.

Q4: What happens if a pod is not affected by any Network Policy?

Pods not selected by any Network Policy will continue to accept all inbound and outbound traffic.

Q5: How can I verify that my Network Policy is applied?

You can verify the Network Policy application by using the command kubectl get networkpolicy and checking if the intended rules and policies are applied to your pods.