Kubernetes Networking
A comprehensive guide to Kubernetes networking covering CNI plugins, Services, Ingress controllers, NetworkPolicy, DNS, service discovery, and troubleshooting with detailed explanations and practical examples.
Kubernetes networking is a complex but fundamental aspect of container orchestration. It enables communication between pods, services, and external clients. Kubernetes follows a set of core networking principles that all implementations must satisfy:
- Pod-to-Pod: Every pod must be able to communicate with every other pod on any node without NAT
- Pod-to-Service: Every pod must be able to communicate with every service
- Service-to-External: External clients must be able to access services via Ingress or LoadBalancer
- Pod-to-Node: Each pod should have a unique IP address within the cluster network
- Every pod gets its own IP address (no port conflicts)
- Pod IPs are routable within the cluster
- Services provide stable endpoints with load balancing
- Network policies enable micro-segmentation
The Container Network Interface (CNI) is a standard for configuring network interfaces in Linux containers. CNI plugins implement the network connectivity between pods and provide features like IPAM, network policies, and service mesh integration.
Calico
Cilium
Flannel
Weave Net
# Install Calico
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27/manifests/calico.yaml
# Install Cilium (with Helm)
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --namespace kube-system \
--set ipam.mode=kubernetes \
--set routingMode=native \
--set hubble.enabled=true
# Install Flannel
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
# Check CNI configuration
ls -la /etc/cni/net.d/
cat /etc/cni/net.d/10-calico.conflist
# Check CNI plugin status
kubectl get pods -n kube-system | grep -E "calico|cilium|flannel|weave"
# Network interface in pod
kubectl exec -it <pod-name> -- ip addr show
kubectl exec -it <pod-name> -- ip route show
Services provide stable network endpoints for accessing pods. They abstract the dynamic nature of pod IPs and provide load balancing, service discovery, and external exposure.
ClusterIP
NodePort
LoadBalancer
Headless Service
# ClusterIP Service
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
protocol: TCP
# NodePort Service
apiVersion: v1
kind: Service
metadata:
name: my-nodeport
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # Optional, Kubernetes will assign if not set
# LoadBalancer Service
apiVersion: v1
kind: Service
metadata:
name: my-lb
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
# Headless Service (for StatefulSet)
apiVersion: v1
kind: Service
metadata:
name: my-statefulset
spec:
clusterIP: None
selector:
app: my-statefulset
ports:
- port: 3306
targetPort: 3306
# Service with session affinity
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- port: 80
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
# Check services
kubectl get svc
kubectl describe svc my-service
# Check endpoints (pods behind service)
kubectl get endpoints my-service
Ingress manages external access to services in a cluster, typically HTTP and HTTPS. It provides load balancing, SSL/TLS termination, and name-based virtual hosting.
NGINX Ingress
AWS ALB Ingress
Traefik
Istio Ingress Gateway
# Install NGINX Ingress Controller
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace
# Basic Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
# TLS/SSL Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
# Multi-service Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-service-ingress
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /api/v1
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /web
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# Canary Ingress (NGINX annotations)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-service
port:
number: 80
- Use TLS for all production ingress
- Implement rate limiting at the ingress level
- Use ingress class to manage multiple ingress controllers
- Implement health checks for backend services
- Use annotations for advanced routing (canary, A/B testing)
NetworkPolicy enables fine-grained control over pod-to-pod communication. It's like a firewall for your Kubernetes cluster, allowing you to enforce zero-trust networking principles.
# Default deny all ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {} # Applies to all pods
policyTypes:
- Ingress
# Default deny all egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector: {}
policyTypes:
- Egress
# Allow ingress from same namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-namespace-ingress
spec:
podSelector:
matchLabels:
app: my-app
ingress:
- from:
- podSelector: {} # All pods in same namespace
policyTypes:
- Ingress
# Allow from specific namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-monitoring
spec:
podSelector:
matchLabels:
app: my-app
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
policyTypes:
- Ingress
# Allow from specific pod with label
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-frontend
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
protocol: TCP
policyTypes:
- Ingress
# Allow egress to specific external IP
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-external
spec:
podSelector:
matchLabels:
app: my-app
egress:
- to:
- ipBlock:
cidr: 192.168.1.0/24
ports:
- port: 5432
protocol: TCP
policyTypes:
- Egress
# Apply network policies
kubectl apply -f network-policy.yaml
# Check network policies
kubectl get networkpolicies
kubectl describe networkpolicy deny-all-ingress
Kubernetes provides built-in DNS-based service discovery through CoreDNS (or kube-dns). Services are automatically registered with DNS, enabling pods to discover services by name.
# CoreDNS configuration
# Check CoreDNS deployment
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get configmap coredns -n kube-system
# Service DNS format
# <service-name>.<namespace>.svc.cluster.local
# Example: my-service.default.svc.cluster.local
# Pod DNS format (via headless service or statefulset)
# <pod-name>.<service-name>.<namespace>.svc.cluster.local
# Example: nginx-0.nginx-svc.default.svc.cluster.local
# Test DNS resolution from a pod
kubectl run test-pod --image=busybox -it --rm --restart=Never -- nslookup kubernetes.default.svc.cluster.local
# Check DNS configuration inside a pod
kubectl exec -it <pod-name> -- cat /etc/resolv.conf
# CoreDNS configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
# Custom DNS entries (hostAliases)
apiVersion: v1
kind: Pod
metadata:
name: custom-dns-pod
spec:
hostAliases:
- ip: "192.168.1.100"
hostnames:
- "internal.example.com"
- "db.internal"
containers:
- name: app
image: nginx
- Use fully qualified domain names for service discovery
- Monitor CoreDNS performance and scale accordingly
- Use headless services for stateful applications requiring direct pod DNS
- Consider using ExternalDNS for automated DNS record management
Troubleshooting Kubernetes networking issues requires a systematic approach. Here are common techniques and tools.
# Check network connectivity between pods
kubectl run busybox --image=busybox -it --rm --restart=Never -- wget -O- http://<pod-ip>:<port>
# Check service resolution
kubectl run busybox --image=busybox -it --rm --restart=Never -- nslookup <service-name>.<namespace>.svc.cluster.local
# Check pod network interface
kubectl exec -it <pod-name> -- ip addr show
# Check network policies
kubectl get networkpolicies --all-namespaces
kubectl describe networkpolicy <policy-name> -n <namespace>
# Check CNI logs
kubectl logs -n kube-system -l k8s-app=calico-node
kubectl logs -n kube-system -l k8s-app=cilium
# Check kube-proxy
kubectl logs -n kube-system -l k8s-app=kube-proxy
# Debug with ephemeral container
kubectl debug -it <pod-name> --image=busybox --target=<container-name>
# Check network connectivity with netcat
kubectl run test-pod --image=busybox -it --rm --restart=Never -- sh -c "nc -zv <host> <port>"
# Check IPVS rules (if using IPVS mode)
kubectl exec -n kube-system <kube-proxy-pod> -- ipvsadm -L -n
# Check iptables rules (if using iptables mode)
kubectl exec -n kube-system <kube-proxy-pod> -- iptables -t nat -L -n
- Check if CNI pods are running (
kubectl get pods -n kube-system) - Verify service endpoints (
kubectl get endpoints) - Test DNS resolution from within pods
- Check network policy enforcement
- Review kube-proxy logs
- Check node network configuration
Kubernetes networking is the backbone of container orchestration. Master these concepts to build resilient, secure, and scalable applications on Kubernetes.