Kubernetes Networking Demystified: A Comprehensive Guide with Real-World Examples

Kubernetes networking is the backbone of how containers communicate within a cluster and how external users interact with services. While it may seem complex at first, breaking it down into digestible concepts and real-world scenarios can help you understand it deeply. This article focuses on explaining Kubernetes networking with practical examples, particularly addressing how services like NGINX can be exposed to external users.


Understanding Kubernetes Networking

Kubernetes networking is built on the following principles:

  1. Pod-to-Pod Communication: Every pod gets a unique IP and can communicate with other pods directly.

  2. Pod-to-Service Communication: Services provide a stable endpoint to access a group of pods, even as pods are added or removed.

  3. External Access: Kubernetes provides multiple ways for external clients to access services within the cluster.


Scenario: Exposing an E-Commerce Application

Let’s take an example of an e-commerce app with the following architecture:

  1. Frontend Service: Handles user interactions (e.g., nginx).

  2. Backend Service: Processes orders (e.g., Flask).

  3. Database Service: Stores order data (e.g., PostgreSQL).

Cluster Setup:

  • The cluster has 1 control plane and 3 worker nodes.

    • Worker Node 1 runs NGINX pods.

    • Worker Node 2 runs Flask pods.

    • Worker Node 3 runs PostgreSQL pods.


How Kubernetes Networking Works

1. Pod-to-Pod Communication

Concept: Each pod is assigned a unique IP by the CNI (Container Network Interface) plugin, enabling direct communication without NAT.

  • Example: Backend pod (10.244.1.5) needs to query the database pod (10.244.2.8).

  • The request flows through the CNI, which handles the routing between pods, even if they are on different nodes.

2. Pod-to-Service Communication

Concept: Services abstract a set of pods behind a stable ClusterIP.

  • Example:

    • NGINX service has a ClusterIP: 10.96.0.5.

    • Requests to 10.96.0.5 are routed to NGINX pods via kube-proxy.

3. Service-to-External Communication

Concept: To expose services to external users, Kubernetes provides the following options:

  1. NodePort: Exposes the service on a specific port on each node.

  2. LoadBalancer: Integrates with cloud provider load balancers to provide a single external IP.

  3. Ingress: Provides advanced routing using hostnames or paths.


Real-World Example: Exposing NGINX

Scenario

You want to expose the NGINX service to external users, allowing them to access the application through a web browser.

Step 1: Service Creation

Define an NGINX service to route traffic to the NGINX pods:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  • Type: LoadBalancer creates an external load balancer.

  • Selector: Targets pods with the label app: nginx.

  • Port Mapping: Exposes port 80 to external users.

Step 2: External Access

  • Once deployed, the cloud provider assigns an external IP to the service (e.g., 52.14.32.10).

  • Users can access NGINX using http://52.14.32.10.


Advanced Concepts: Load Balancing and Ingress

Load Balancer

Cloud-managed load balancers distribute traffic to the service, ensuring high availability and fault tolerance.

Ingress

Ingress controllers route HTTP/S traffic to multiple services based on hostnames or paths.

Example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ecommerce-ingress
spec:
  rules:
    - host: shop.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 80

Debugging Kubernetes Networking

Scenario: Service is not accessible

  1. Check the Service:

     kubectl get svc nginx-service
    
  2. Verify Pods:

     kubectl get pods -l app=nginx
    
  3. Test DNS Resolution:

     kubectl exec -it <pod-name> -- nslookup nginx-service
    
  4. Inspect Kube-proxy:

     kubectl logs -n kube-system <kube-proxy-pod>
    

Final Thoughts

Kubernetes networking is designed to handle complex communication requirements seamlessly. Services like NGINX can be easily exposed to external users, while internal components communicate reliably through ClusterIPs and kube-proxy. By understanding the flow of traffic, you can confidently design and troubleshoot networking in Kubernetes clusters.