English

Share with friends

Note

In this guide, we will closely look at what are Kubernetes policies and how they work along with examples & best practices.

A Complete Guide to Kubernetes Network Policy - Examples & Best Practices cover image

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

Priyansh Khodiyar's profile

Written by Priyansh Khodiyar

Priyansh is the founder of UnYAML and a software engineer with a passion for writing. He has good experience with writing and working around DevOps tools and technologies, APMs, Kubernetes APIs, etc and loves to share his knowledge with others.

Further Reading

Life is better with cookies 🍪

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt out if you wish. Cookie Policy