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
- 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
- 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 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
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 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 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
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
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
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 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
Create the Network policy with the egress rule.
kubectl create -f egress.yml
kubectl get networkpolicy | grep source-pod-allow-to-destination-pod
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
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.