Overview of Kubernetes Network Policies
Kubernetes Network Policies are a set of rules that define how pods in a Kubernetes cluster are allowed to communicate with each other and other network endpoints. These policies enable you to control the flow of network traffic at the IP level, both between pods and to/from external endpoints. Network Policies help enforce security and reduce attack surfaces by ensuring that only authorized communication happens between services.
By default, Kubernetes allows all pods to communicate with each other. Network Policies allow you to restrict this communication based on specified rules.
Key Features of Kubernetes Network Policies
Traffic Control:
- Allows you to control which pods can communicate with other pods or external services, both ingress (incoming) and egress (outgoing) traffic.
Pod-Selector Based Rules:
- Network Policies use selectors to apply rules based on pod labels, meaning you can target groups of pods instead of individual ones.
Namespace Isolation:
- You can isolate traffic between namespaces, further securing communication within the cluster.
Layer 3 and Layer 4 Filtering:
- Network Policies work at Layer 3 (IP addresses) and Layer 4 (ports) of the OSI model, allowing control over both which pods can communicate and over which protocols (TCP/UDP) and ports they can use.
Plugin-Dependent Implementation:
- Network Policies are enforced by the network plugin used in your Kubernetes cluster (e.g., Calico, Cilium, Weave). Without a CNI (Container Network Interface) plugin that supports Network Policies, the policies will not have any effect.
Step-by-Step Setup of Kubernetes Network Policies
Here’s a step-by-step guide to setting up Kubernetes Network Policies for managing traffic flow between pods.
Step 1: Ensure a Compatible Network Plugin
Install a Network Plugin:
Not all Kubernetes network plugins support Network Policies. Ensure your cluster is using a network plugin like Calico, Cilium, Weave, or others that support Network Policies.
To install Calico, for example, run the following command:
bashCopy codekubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
Verify Installation:
Ensure the plugin is correctly installed and functioning. For Calico, check the pods in the
kube-system
namespace:bashCopy codekubectl get pods -n kube-system
Step 2: Create a Namespace and Pods
Create a Namespace:
First, create a namespace to logically separate your resources:
bashCopy codekubectl create namespace demo
Create Sample Pods:
Deploy two different pods that will be used to test the Network Policies. For example:
yamlCopy codeapiVersion: v1 kind: Pod metadata: name: pod-a labels: app: app-a spec: containers: - name: nginx image: nginx --- apiVersion: v1 kind: Pod metadata: name: pod-b labels: app: app-b spec: containers: - name: nginx image: nginx
Apply the YAML file to create the pods:
bashCopy codekubectl apply -f pod-a.yaml kubectl apply -f pod-b.yaml
Test Connectivity:
Ensure both pods can communicate by using a quick test:
bashCopy codekubectl exec -it pod-a -- curl pod-b
By default, the communication will be successful since no Network Policies are in place.
Step 3: Define a Basic Network Policy
Create a Network Policy for Ingress Control:
To control ingress (incoming) traffic, create a Network Policy that allows traffic only to certain pods. Here’s an example that restricts traffic to
pod-a
:yamlCopy codeapiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-app-a-ingress namespace: demo spec: podSelector: matchLabels: app: app-a policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: app-b ports: - protocol: TCP port: 80
Explanation of the Policy:
The podSelector targets
app: app-a
pods.Ingress traffic is allowed only from pods with the label
app: app-b
on port 80.This policy will block all other traffic to
pod-a
, except frompod-b
.
Apply the Network Policy:
bashCopy codekubectl apply -f allow-app-a-ingress.yaml
Test the Policy:
Now test the network policy by trying to access
pod-a
frompod-b
:bashCopy codekubectl exec -it pod-b -- curl pod-a
This should succeed, while other pods trying to access
pod-a
will be denied.
Step 4: Define Egress Policies
Create a Network Policy for Egress Control:
Similar to ingress control, egress (outgoing) traffic can be restricted. The following policy will restrict
pod-b
to communicate only withpod-a
:yamlCopy codeapiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-app-b-egress namespace: demo spec: podSelector: matchLabels: app: app-b policyTypes: - Egress egress: - to: - podSelector: matchLabels: app: app-a ports: - protocol: TCP port: 80
Explanation of the Policy:
This Network Policy allows
pod-b
to send traffic topod-a
only on TCP port 80.No other outgoing communication from
pod-b
will be allowed.
Apply the Policy:
bashCopy codekubectl apply -f allow-app-b-egress.yaml
Test the Policy:
Try to curl from
pod-b
topod-a
(this should work) and any other pod (this should fail):bashCopy codekubectl exec -it pod-b -- curl pod-a # Should succeed kubectl exec -it pod-b -- curl pod-c # Should fail (if there's a pod-c)
Step 5: Test Network Isolation
Deploy Another Pod:
Create another pod (e.g.,
pod-c
), and try to accesspod-a
andpod-b
. Since the Network Policies only allow communication betweenpod-a
andpod-b
, any communication attempt frompod-c
should be blocked:bashCopy codekubectl exec -it pod-c -- curl pod-a # Should fail kubectl exec -it pod-c -- curl pod-b # Should fail
Ensure No Default Policies:
- It’s important to note that if no Network Policy exists for a pod, it is allowed to communicate freely with all other pods. Once you apply a Network Policy to a pod, Kubernetes denies all traffic not explicitly allowed by the policy.
Step 6: Advanced Policies
Namespace Isolation:
To control traffic between different namespaces, you can specify namespaceSelector in your Network Policies. For example, this policy allows only pods from the
frontend
namespace to access pods labeledapp: backend
in thebackend
namespace:yamlCopy codeapiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: namespace-policy namespace: backend spec: podSelector: matchLabels: app: backend ingress: - from: - namespaceSelector: matchLabels: name: frontend
Limitations:
- Network Policies work at Layer 3 and Layer 4. If you need Layer 7 (application layer) filtering, you’ll need tools like Istio or NGINX Ingress.
Conclusion
Kubernetes Network Policies provide a powerful way to enforce fine-grained network traffic control within your cluster. By following the step-by-step process above, you can set up rules that isolate pods, restrict unauthorized access, and create a more secure environment. With Network Policies, you reduce the risk of lateral movement within your cluster and ensure that communication follows your organization’s security guidelines.
Subscribe to my newsletter
Read articles from Yogesh Borude directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Yogesh Borude
Yogesh Borude
I am a DevOps engineer with over 2+ years of experience in enhancing deployment processes and automating workflows. Passionate about cloud technologies and continuous integration, I specialize in Docker, Kubernetes, and CI/CD pipelines.