Skip to content

Mastering Kubernetes Network Policies - A Hands-On Guide

Published: at 06:30 AM

Network policies are a crucial aspect of Kubernetes security, allowing fine-grained control over pod-to-pod communication. In this hands-on guide, we’ll walk through setting up a Kind cluster with Calico, deploying applications, and implementing network policies.

Step 1: Creating a Kind Cluster with Custom Networking

First, let’s create a Kind cluster with the default CNI disabled:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    extraPortMappings:
      - containerPort: 30001
        hostPort: 30001
  - role: worker
  - role: worker
networking:
  disableDefaultCNI: true
  podSubnet: 192.168.0.0/16

Save this as kind-config.yaml and create the cluster:

kind create cluster --config kind-config.yaml

Step 2: Installing Calico

Follow the official Calico documentation to install it on your Kind cluster:

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml

Step 3: Deploying Applications

Let’s create deployments for frontend, backend, and db:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: password

Save this as deployments.yaml and apply:

kubectl apply -f deployments.yaml

Step 4: Exposing Services

Now, let’s expose these deployments as NodePort services:

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30001
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  type: NodePort
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30002
---
apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  type: NodePort
  selector:
    app: db
  ports:
    - port: 3306
      targetPort: 3306
      nodePort: 30003

Save this as services.yaml and apply:

kubectl apply -f services.yaml

Step 5: Testing Connectivity

To test connectivity, you can use temporary pods:

kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot -- /bin/bash

From within this pod, you can use curl to test connections to other services.

Step 6: Implementing Network Policy

Now, let’s create a network policy that only allows the backend to access the db:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-access-policy
spec:
  podSelector:
    matchLabels:
      app: db
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: backend
      ports:
        - protocol: TCP
          port: 3306

Save this as network-policy.yaml and apply:

kubectl apply -f network-policy.yaml

Key Takeaways

  1. CNI Flexibility: Kind allows us to disable the default CNI and use alternatives like Calico.
  2. Fine-grained Control: Network policies enable precise control over pod-to-pod communication.
  3. Label-based Selectors: Network policies use labels to select pods, making them flexible and powerful.
  4. Default Deny: Without explicit allow rules, network policies default to denying all traffic.
  5. Testing is Crucial: Always test your network policies thoroughly to ensure desired behavior.

Conclusion

Kubernetes Network Policies provide a powerful tool for securing your cluster’s internal communications. By following this guide, you’ve set up a Kind cluster with Calico, deployed applications, and implemented a basic network policy. This foundation will allow you to create more complex policies tailored to your specific security needs.

Remember, network security is an ongoing process. Regularly review and update your policies as your application architecture evolves.


This blog post template provides a comprehensive, hands-on guide to implementing Kubernetes Network Policies, based on the task you described. It includes step-by-step instructions, explanations of key concepts, and important takeaways. The content is structured to be both informative and practical, suitable for readers who want to understand and implement Network Policies in their Kubernetes environments.