Share with friends
In this guide, we will closely look at what are Kubernetes policies and how they work along with examples & best practices.
Kubernetes, the backbone of modern container orchestration, has changed the way we deploy and manage applications. While Kubernetes is great at orchestrating containers, ensuring security and maintaining network isolation within the cluster can be a real pain.
This is where Kubernetes Network Policies come into play. In this article, we will delve into the intricacies of Kubernetes Network Policies, exploring their fundamental concepts, functionalities, and best practices.
What are Kubernetes Network Policies?
Kubernetes Network Policies are a set of rules that define how communication between pods (containers) within a Kubernetes cluster is allowed or denied.
They kind of serve as a way to control and secure network traffic among different parts of your applications running in Kubernetes.
Imagine you have several pods running various services, like a web frontend, a database, and an API.
You want to make sure that the frontend pod can access the API and the database, but you don't want the database to be accessible directly from the internet or by any other pods that shouldn't have access. Right?
This is where Kubernetes Network Policies come into play.
So, here's a little breakdown of key aspects of Kubernetes Network Policies.
1. Pod Selector
Network Policies start by selecting which pods they apply to. You use labels to specify which pods the policy should affect.
For instance, you can label your frontend and backend pods differently to distinguish them.
Like in the example below.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-access
spec:
podSelector:
matchLabels:
app: frontend
In this example, the policy selects pods with the label app: frontend
.
Also Read: Understanding Kubernetes Jobs
2. Ingress and Egress Rules
Once you've selected the pods, you define rules for what traffic is allowed to come in (ingress) or go out (egress) from those pods.
For example, you created an ingress rule that allows traffic from pods labeled as app: api
to access your app: frontend
pods on a specific port, like this:
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 80
This rule permits incoming traffic from pods with the label app: api
on port 80.
Also Read: 13 NGNIX Ingress Configuration Options
3. Default Deny
By default, Kubernetes enforces a "default-deny" policy, meaning if you don't explicitly allow traffic, it's denied. This beefs up security by ensuring you only allow what's necessary and no crap.
Let's say you have three pods labeled as app: frontend
, app: api
, and app: database
. You can create Network Policies to control traffic:
-
Allow traffic from frontend to api for your web application.
-
Allow traffic from api to database for database access.
-
Deny all other incoming and outgoing traffic to maintain a strict security posture.
And that's how it's done. But how it works? Let's see.
How Does Kubernetes Network Policies Work?
As you already know Kubernetes Network Policies work by defining rules that control traffic between pods within a Kubernetes cluster. These rules specify which pods are allowed to communicate with each other and under what conditions.
Now, let's see how they work with practical examples.
1. Defining Network Policies
To create a Network Policy, you use a YAML configuration file.
Let's say you have two pods: a frontend and a backend, and you want to restrict traffic so that only the frontend can communicate with the backend.
Here's a sample Network Policy YAML:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-backend
spec:
podSelector:
matchLabels:
app: frontend
ingress:
- from:
- podSelector:
matchLabels:
app: backend
This Network Policy has the following components:
-
podSelector: This selects the pods to which the policy applies. In this case, it selects pods with the label
app: frontend
. -
ingress: This specifies the allowed incoming traffic. Here, it allows traffic from pods with the label
app: backend
.
2. Applying the Network Policy
To apply the Network Policy to your cluster, simply use the kubectl apply
command:
kubectl apply -f network-policy.yaml
This command tells Kubernetes to enforce the rules you defined in the Network Policy.
Also Read: How to Use Terraform Apply?
3. Effect on Pod Communication
Once the Network Policy is applied, only the frontend pod is allowed to send traffic to the backend pod. Any other traffic attempting to access the backend pod is strictly denied.
Here's a simple test to demonstrate this:
# Create a test pod for the frontend
kubectl run test-frontend --image=busybox --labels=app=frontend --command sleep 3600
# Create a test pod for the backend
kubectl run test-backend --image=busybox --labels=app=backend --command sleep 3600
# Try to access the backend from the frontend pod (allowed)
kubectl exec -it test-frontend -- wget -qO- test-backend
# Try to access the backend from a different pod (denied)
kubectl run test-other --image=busybox --command --rm -it --restart=Never -- wget -qO- test-backend
In this test, you'll see that the frontend pod can access the backend pod, but any other pod's attempt to access the backend is denied due to the Network Policy.
Feel free to use any other custom images you might have instead of busybox.
4. Viewing Network Policies
You can view the Network Policies applied to your cluster using:
kubectl get networkpolicies
5. Deleting a Kubernetes Network Policy
To remove a Network Policy, you can use the kubectl delete
command.
kubectl delete networkpolicy allow-frontend-backend
This will remove the Network Policy, allowing unrestricted communication between pods.
Also Read: When to Use Kubectl Delete Deployment?
Default Network Policies in Kubernetes
Now that we have seen what Network policy is and it works, let's talk a little about Default Network Policy.
Default Network Policies in Kubernetes help control the traffic flow between pods by defining a set of rules that specify how pods are allowed to communicate with each other.
Unlike regular Network Policies that explicitly allow or deny traffic, Default Network Policies apply to all pods unless otherwise overridden by specific Network Policies.
Here's a better explanation with examples to make sure you understand it.
1. Understanding Default Network Policies
Default Network Policies are applied automatically to all pods in a namespace unless overridden by other Network Policies.
They are useful for implementing a "default deny" strategy, where all communication between pods is denied by default unless explicitly allowed.
Also Read: Kubernetes Pods vs Nodes
2. Sample Network Policy
Let's say you have a Kubernetes cluster with two namespaces: namespace-a
and namespace-b
.
By default, all pods in both namespaces can communicate with each other.
However, you want to restrict communication between pods in different namespaces and only allow certain traffic.
Also Read: The Only Guide to Kubernetes Namespaces You'll Ever Need
3. Create Default Network Policies
So, how to create one?
To create a Default Network Policy, you need to define a policy that denies all traffic. Create a YAML file, for instance, default-deny.yaml
:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
Now, apply this policy to your namespaces:
kubectl apply -f default-deny.yaml -n namespace-a
kubectl apply -f default-deny.yaml -n namespace-b
Congrats, this creates a Default Network Policy named default-deny
in both namespaces.
4. Allow Specific Traffic
Now, you can create specific Network Policies to allow certain traffic between pods.
For example, let's allow pods in namespace-a
to communicate with pods labeled as app=web
in namespace-b
. Create a YAML file, let's name it, allow-web.yaml
:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector:
matchLabels:
name: namespace-a
Apply this policy to namespace-b
:
kubectl apply -f allow-web.yaml -n namespace-b
This Network Policy allows traffic from pods in namespace-a
to pods labeled as app=web
in namespace-b
.
Also Read: How to Setup Multiple Apps one Just One Load Balancer in Kubernetes?
5. Verify Connectivity
You can now verify that pods in namespace-a
can communicate with pods labeled as app=web
in namespace-b
. Create pods in both namespaces and test connectivity:
# Create pods in namespace-a
kubectl run --namespace=namespace-a test-pod-a --image=busybox --command -- sleep 3600
kubectl exec -it --namespace=namespace-a test-pod-a -- sh
# In the shell of test-pod-a, try to ping a pod in namespace-b
ping <pod-b-ip>
# You should see successful communication
This setup ensures that only the allowed traffic specified in Network Policies is permitted while blocking all other communication.
6. Deleting Network Policies
To remove a Network Policy:
kubectl delete networkpolicy allow-web -n <namespace>
Also Read: Kubernetes Best Practices
Kubernetes Network Policy Best Practices
Without best practices, using Network policies can be a mess, here are a few points below to help you set it up.
1. Start with a Clear Network Policy Design
Before writing Network Policies, define your application's communication requirements. Identify what should be allowed and what should be denied, keeping in mind the requirements.
2. Use Labels for Selectors
Label your pods to easily define Network Policy selectors. This makes it easier to specify which pods should be allowed or denied traffic.
Let's look at an example.
apiVersion: v1
kind: Pod
metadata:
name: web-pod
labels:
app: frontend
Also Read: A Complete Guide to Kubernetes Liveness Probes
3. Default Deny All Ingress and Egress
Always start with a default deny policy for both ingress and egress traffic. Then, explicitly allow what's necessary. This makes sure a secure baseline.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
ingress: []
4. Minimize Pod Access
Allow only necessary pods to access your application pods. Avoid using allow-all
policies unless required.
Here's an example:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
spec:
podSelector:
matchLabels:
app: frontend
ingress:
- from:
- podSelector:
matchLabels:
app: backend
5. Limit Traffic by Ports and Protocols
Specify ports and protocols explicitly in Network Policies to minimize the attack surface. The less exposed, the less loopholes to get into the system.
Let's look at an example.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-http
spec:
podSelector:
matchLabels:
app: frontend
ingress:
- ports:
- port: 80
protocol: TCP
6. Use Network Policies with Namespaces:
Utilize Network Policies within namespaces to isolate and control traffic effectively. Always a best practice working in any K8s environment.
Here's an example.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-namespace-communication
spec:
podSelector:
matchLabels:
app: frontend
ingress:
- from:
- namespaceSelector:
matchLabels:
team: dev
7. Regularly Review and Update Policies
As your application evolves, regularly review and update your Network Policies to reflect the current requirements.
8. Leverage Network Policy Visualization Tools
Use visualization tools like Kiali or network policy debugging tools to validate and visualize your Network Policies.
9. Test Policies Before Applying
Always test your Network Policies in a non-production environment before applying them to production clusters.
10. Document Your Policies
Maintain clear documentation of your Network Policies, including their purpose and any exceptions.
11. Monitor Policy Violations
Set up monitoring and alerting for policy violations to detect and respond to security breaches promptly.
12. Use Network Policy Enforcement Tools
Consider using tools like Calico, Cilium, or Antrea for enhanced Network Policy enforcement and management. We got more at the end of the article.
13. Regularly Audit and Review Policies
Perform regular audits and reviews of your Network Policies to make sure they align with your application's evolving needs and security requirements.
In Kubernetes, you can create and apply Network Policies using kubectl
commands. For example:
# Create a Network Policy from a YAML file
kubectl apply -f network-policy.yaml
# List Network Policies in a namespace
kubectl get networkpolicy -n <namespace>
# Describe a Network Policy
kubectl describe networkpolicy <policy-name> -n <namespace>
# Delete a Network Policy
kubectl delete networkpolicy <policy-name> -n <namespace>
Top CNI Plugins
CNI plugins are helpful components for connecting containers within pods to the network. Here are a few for you to dig up.
1. Calico
Calico is a highly popular CNI plugin known for its flexibility and advanced networking features. It provides network policies for fine-grained control over traffic between pods.
Here's how to install this.
kubectl apply -f https://docs.projectcalico.org/v3.18/manifests/calico.yaml
2. Flannel
Flannel is a lightweight and straightforward CNI plugin that is easy to set up. It is commonly used for small to medium-sized clusters.
Install it using the following code snippets.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
3. Cilium
Cilium is a powerful CNI plugin that provides advanced security features and support for features like eBPF (extended Berkeley Packet Filter).
Here's how to install it.
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium
4. Weave
Weave is a CNI plugin that offers both networking and network policy features. It is known for its simplicity and ease of use.
Here's how to install it.
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
5. Antrea
Antrea is a CNI plugin specifically designed for Kubernetes. It focuses on providing networking and security features tailored for Kubernetes clusters.
Let's look at the installation process.
kubectl apply -f https://github.com/antrea-io/antrea/releases/latest/download/antrea.yml
Also Read: Top Kubernetes Distributions
6. Multus
Multus is a CNI plugin that allows attaching multiple network interfaces to a single pod, enabling complex networking setups.
Here's how to install it.
kubectl apply -f https://github.com/intel/multus-cni/blob/master/images/multus-daemonset.yml
7. kube-router
Kube-router is a CNI plugin that combines networking and security features, providing services like IPVS-based load balancing.
Installation:
kubectl apply -f https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/generic-kuberouter-all-features.yaml
8. OVN-Kubernetes
OVN-Kubernetes is based on Open Virtual Networking (OVN) and provides network policies, load balancing, and other advanced networking features.
Installation (with OpenShift):
oc get cm -n openshift-kni-ovn-kubernetes network-config -o jsonpath='{.data["network-config-vtep"]}' > /etc/ovn-k8s.conf
oc adm node-logs --role=master | grep ovn-controller | grep "Starting ovn-controller"
9. Contiv-VPP
Contiv-VPP combines the power of VPP (Vector Packet Processing) with Kubernetes networking to deliver high-performance networking.
Here's how to install this.
kubectl apply -f https://raw.githubusercontent.com/contiv/install/master/k8s/examples/contiv-vpp.yaml
10. NSX-T
VMware NSX-T is a CNI plugin that provides advanced networking and security features for Kubernetes clusters.
Installation (with Helm):
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm install -n <namespace> <release-name> vmware-tanzu/nsx-t
These are some of the top CNI plugins used in Kubernetes clusters.
Depending on your specific requirements, you can choose the one that best suits your needs and install it using the provided commands.
Each of these plugins comes with its own set of features and capabilities, so it's important to evaluate them based on your cluster's networking and security requirements.
Also Read: A Complete Guide to Kubernetes Secrets
Summary of Kubernetes Network Policies
In the ever-changing world of Kubernetes, where containers move and talk like digital neighbors, ensuring network security and thus, CNI is crucial.
Kubernetes Network Policies provide a great solution to help you define and enforce your network security rules with precision.
With the insights and practical knowledge shared in this article, you're now equipped to use Network Policies to protect your Kubernetes cluster and the applications running within it.
I hope this article made you more aware of Network Policies and can't wait to see how you apply your newfound knowledge.
Share with friends