Overview of Kubernetes Network Policies

Yogesh BorudeYogesh Borude
5 min read

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

  1. Traffic Control:

    • Allows you to control which pods can communicate with other pods or external services, both ingress (incoming) and egress (outgoing) traffic.
  2. 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.
  3. Namespace Isolation:

    • You can isolate traffic between namespaces, further securing communication within the cluster.
  4. 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.
  5. 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

  1. 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
      
  2. 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

  1. Create a Namespace:

    • First, create a namespace to logically separate your resources:

        bashCopy codekubectl create namespace demo
      
  2. 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
      
  3. 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

  1. 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
      
  2. 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 from pod-b.

  3. Apply the Network Policy:

     bashCopy codekubectl apply -f allow-app-a-ingress.yaml
    
  4. Test the Policy:

    • Now test the network policy by trying to access pod-a from pod-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

  1. 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 with pod-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
      
  2. Explanation of the Policy:

    • This Network Policy allows pod-b to send traffic to pod-a only on TCP port 80.

    • No other outgoing communication from pod-b will be allowed.

  3. Apply the Policy:

     bashCopy codekubectl apply -f allow-app-b-egress.yaml
    
  4. Test the Policy:

    • Try to curl from pod-b to pod-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

  1. Deploy Another Pod:

    • Create another pod (e.g., pod-c), and try to access pod-a and pod-b. Since the Network Policies only allow communication between pod-a and pod-b, any communication attempt from pod-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
      
  2. 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

  1. 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 labeled app: backend in the backend 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
      
  2. 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.

0
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.