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?
- Pod Communication: Pods need to communicate with each other and external services.
- Service Discovery: Applications require a mechanism to locate other services dynamically.
- Traffic Management: Efficient routing of traffic into the cluster.
Key Concepts in Kubernetes Networking
- Cluster Networking: Pods within a cluster can communicate directly using their IP addresses.
- Services: Abstract a stable endpoint for accessing Pods.
- Ingress: Manage external access to the cluster using HTTP and HTTPS routes.
- 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
- Leverage Services: Use ClusterIP for internal traffic and LoadBalancer for external.
- Implement Ingress: Consolidate routing rules for multiple services.
- Enable Resource Quotas: Limit resources to avoid network bottlenecks.
- 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:
- How Kubernetes networking connects Pods, Services, and external users.
- How to expose services using Service types and Ingress.
- How to troubleshoot and monitor networking issues.