Chapter 9: Kubernetes Networking – Services, Ingress, and DNS

Introduction to Kubernetes Networking

Kubernetes networking enables communication between Pods, external users, and cluster services. It abstracts the complexities of networking, providing a consistent way to manage traffic within and outside the cluster.

Why is Networking Important?

  1. Pod Communication: Pods need to communicate with each other and external services.
  2. Service Discovery: Applications require a mechanism to locate other services dynamically.
  3. Traffic Management: Efficient routing of traffic into the cluster.

Key Concepts in Kubernetes Networking

  1. Cluster Networking: Pods within a cluster can communicate directly using their IP addresses.
  2. Services: Abstract a stable endpoint for accessing Pods.
  3. Ingress: Manage external access to the cluster using HTTP and HTTPS routes.
  4. CoreDNS: Kubernetes’ internal DNS for service discovery.

Step-by-Step Implementation

Step 1: Exposing a Pod Using a Service

Service Types

  • ClusterIP: Default. Exposes the service within the cluster.
  • NodePort: Exposes the service on each Node’s IP at a static port.
  • LoadBalancer: Integrates with cloud providers to expose the service via an external load balancer.

Example: ClusterIP Service

Deploy an NGINX Pod:

kubectl run nginx --image=nginx --port=80

Create a Service YAML (service-clusterip.yaml):

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    run: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: ClusterIP

Apply the Service:

kubectl apply -f service-clusterip.yaml

Verify the Service:

kubectl get service nginx-service

Access the Service from another Pod:

kubectl run test-pod --rm -it --image=busybox -- sh
wget -qO- http://nginx-service

Example: NodePort Service

Update the Service type in service-clusterip.yaml:

type: NodePort

Reapply the Service:

kubectl apply -f service-clusterip.yaml

Retrieve the NodePort:

kubectl get service nginx-service

Access the service using <Node-IP>:<NodePort> from a browser or curl.

Step 2: Load Balancer Services

Example: External Load Balancer

Modify the Service YAML:

type: LoadBalancer

Reapply:

kubectl apply -f service-clusterip.yaml

Retrieve the external IP:

kubectl get service nginx-service

Step 3: Using Ingress for Advanced Routing

Install Ingress Controller

Use a popular Ingress controller such as NGINX Ingress.

For Minikube:

minikube addons enable ingress

Verify the Ingress controller:

kubectl get pods -n kube-system | grep ingress

Example: Ingress Resource

Create an Ingress YAML (ingress-example.yaml):

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

Apply the Ingress:

kubectl apply -f ingress-example.yaml

Update your /etc/hosts file to map nginx.example.com to the Minikube IP:

echo "$(minikube ip) nginx.example.com" | sudo tee -a /etc/hosts

Access the service:

curl http://nginx.example.com

Step 4: DNS and Service Discovery

Kubernetes uses CoreDNS to resolve service names.

Service Discovery Example

Deploy an additional service:

kubectl run redis --image=redis

Access the service DNS name:

kubectl exec test-pod -- nslookup redis

The output confirms the DNS resolution.

Monitoring and Troubleshooting Networking

Inspect Services:

kubectl get services
kubectl describe service <service-name>

Check Pod Connectivity:

kubectl exec <pod-name> -- ping <service-name>

Debug Ingress:

kubectl logs -n kube-system <ingress-controller-pod>

Check DNS Resolution:

kubectl exec <pod-name> -- nslookup <service-name>

Best Practices

  1. Leverage Services: Use ClusterIP for internal traffic and LoadBalancer for external.
  2. Implement Ingress: Consolidate routing rules for multiple services.
  3. Enable Resource Quotas: Limit resources to avoid network bottlenecks.
  4. Monitor Traffic: Use tools like Prometheus and Grafana to monitor network health.

Production Example: Deploying a Web App with Networking

Scenario

Deploy a web application accessible via a custom domain.

App Deployment YAML

Save this as webapp-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: myregistry/webapp:v1
        ports:
        - containerPort: 8080

Service YAML

Save this as webapp-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  selector:
    app: webapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

Ingress YAML

Save this as webapp-ingress.yaml:

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

Apply the resources:

kubectl apply -f webapp-deployment.yaml
kubectl apply -f webapp-service.yaml
kubectl apply -f webapp-ingress.yaml

Update /etc/hosts:

echo "$(minikube ip) webapp.example.com" | sudo tee -a /etc/hosts

Access the application:

curl http://webapp.example.com

Conclusion

In this chapter, you learned:

  1. How Kubernetes networking connects Pods, Services, and external users.
  2. How to expose services using Service types and Ingress.
  3. How to troubleshoot and monitor networking issues.

Leave a Reply