Networking
Understanding Kubernetes networking concepts and implementation
Kubernetes Networking
Kubernetes networking addresses four primary concerns: container-to-container, pod-to-pod, pod-to-service, and external-to-service communication. The networking model in Kubernetes is designed to provide a flat network where all pods can communicate with each other without NAT, regardless of which node they are running on.
The Kubernetes networking model is built on these fundamental requirements:
- All containers can communicate with all other containers without NAT
- All nodes can communicate with all containers without NAT
- The IP that a container sees itself as is the same IP that others see it as
This foundation creates a clean, backwards-compatible model where pods can be treated much like VMs or physical hosts from a port allocation, naming, service discovery, load balancing, application configuration, and migration perspective.
Pod Networking
Pod Network Model
- Each pod gets unique IP address across the entire cluster
- Containers within a pod share the pod's network namespace
- Direct communication between pods across nodes without NAT
- All containers in a pod share the same IP address and port space
- Containers within a pod can communicate via localhost
- Pods on the same node can communicate via pod IPs directly
- Pods on different nodes communicate through the cluster network
Container Network Interface (CNI)
- Network plugin architecture that defines how networking is implemented
- Popular plugins: Calico, Flannel, Weave Net, Cilium, AWS VPC CNI
- Implements pod networking according to the Kubernetes networking model
- Handles IP allocation, routing, and network policy enforcement
- Different CNI plugins offer various features:
- Calico: Network policy enforcement, high performance
- Flannel: Simple overlay network, easy to set up
- Cilium: eBPF-based networking with advanced security
- Weave Net: Mesh networking with encryption
- AWS VPC CNI: Native AWS VPC networking for EKS
Network Implementation
Services
Services provide a stable endpoint to access a group of pods that provide the same functionality. They enable loose coupling between dependent pods by abstracting away the specific IP addresses of individual pods.
ClusterIP
The default service type that exposes the service on an internal IP within the cluster. This makes the service only reachable from within the cluster.
Key aspects of ClusterIP:
- Only accessible within the cluster
- Provides load balancing across all matching pods
- Stable internal IP that remains constant even as pods come and go
- Used for internal communication between applications
- Implemented by kube-proxy using iptables or IPVS rules
- DNS name format:
<service-name>.<namespace>.svc.cluster.local
NodePort
Exposes the service on each node's IP at a static port. Creates a ClusterIP service, which it routes to. Accessible from outside the cluster using <NodeIP>:<NodePort>
.
Key aspects of NodePort:
- Makes service accessible from outside the cluster
- Automatically creates a ClusterIP service
- NodePort range is typically 30000-32767 (configurable)
- Each node proxies the allocated port to the service
- Useful for development or when external load balancers aren't available
- Not recommended for production due to limited port range and security concerns
LoadBalancer
Exposes the service using a cloud provider's load balancer. Creates NodePort and ClusterIP services, which it routes to.
Key aspects of LoadBalancer:
- Integrates with cloud provider's load balancing service
- Automatically creates NodePort and ClusterIP services
- Provides public IP address for external access
- Distributes traffic among pods
- Cloud provider provisions real load balancer (AWS ELB, GCP Load Balancer, etc.)
- Most appropriate for production workloads needing external access
- Can be costly as each service gets its own load balancer
ExternalName
Maps the service to the contents of the externalName
field (e.g., foo.bar.example.com
). Returns a CNAME record with the value.
Key aspects of ExternalName:
- No proxying involved, just DNS CNAME resolution
- Used for connecting to external services
- Provides an abstraction layer for external dependencies
- Useful for migrating services to Kubernetes
- No selectors, ports, or endpoints needed
Network Policies
Network Policies are application-centric constructs that specify how groups of pods are allowed to communicate with each other and with other network endpoints. They are essential for implementing security boundaries and enforcing the principle of least privilege in your cluster.
Key Components of Network Policies
- podSelector: Determines which pods the policy applies to
- policyTypes: Specifies whether policy applies to ingress, egress, or both
- ingress/egress rules: Defines allowed traffic patterns
- from/to selectors: Can select by pod, namespace, or IP block
- ports: Specifies which ports traffic is allowed on
Default Deny All Traffic
Allow Traffic From Specific Namespace
Note on Implementation
Network Policies require a network plugin that supports them, such as Calico, Cilium, or Weave Net. The default kubenet plugin does not support Network Policies.
Ingress Controllers
Ingress is an API object that manages external access to services in a cluster, typically HTTP/HTTPS. It provides load balancing, SSL termination, and name-based virtual hosting. Unlike Services, Ingress operates at the application layer (L7) of the network stack.
Ingress requires an Ingress controller to work. Multiple Ingress controllers are available, including NGINX, Traefik, HAProxy, and cloud provider-specific controllers.
Basic Ingress
Ingress Controller Installation
Most clusters don't come with an Ingress controller installed by default. You need to deploy one:
TLS Configuration
SSL/TLS termination for secure connections:
Creating a TLS secret:
Path-based Routing
Route traffic to different services based on URL path:
Host-based Routing
Route traffic to different services based on hostname:
Advanced Annotations
Different Ingress controllers support various annotations for advanced features:
DNS Service
Kubernetes provides a built-in DNS service for service discovery within the cluster. This DNS service allows pods to find and communicate with other services using consistent DNS names, regardless of the actual pod IP addresses.
CoreDNS
- Default DNS service in Kubernetes since v1.13
- Serves as the cluster's internal DNS server
- Enables service discovery through DNS names
- Provides Pod DNS resolution for containerized applications
- Highly configurable and extensible with plugins
- Implements service and pod DNS records according to Kubernetes specifications
- Records automatically updated when services or pods change
- Runs as Deployment in the kube-system namespace
DNS Naming Convention
- Services:
- Regular service:
<service-name>.<namespace>.svc.cluster.local
- Headless service pods:
<pod-name>.<service-name>.<namespace>.svc.cluster.local
- Example:
nginx.default.svc.cluster.local
- Regular service:
- Pods:
- Full:
<ip-with-dashes>.<namespace>.pod.cluster.local
- Example:
10-244-2-5.default.pod.cluster.local
(for IP 10.244.2.5)
- Full:
The .cluster.local
suffix is the default domain but can be configured. Within the same namespace, services can be referenced by just <service-name>
.
DNS Policies
DNS policies define how DNS resolution works for pods:
- ClusterFirst (default):
- Queries that don't match the cluster domain suffix are forwarded to upstream nameservers
- Enables both cluster service lookup and external domain resolution
- Most common and recommended for typical workloads
- Default:
- Pod inherits the name resolution configuration from the node it runs on
- Uses the node's
/etc/resolv.conf
- Doesn't use cluster DNS service
- Useful for pods that need to resolve external DNS exactly like the node
- None:
- Ignores DNS settings from the Kubernetes environment
- Requires manually setting DNS via
dnsConfig
property - Provides complete control over DNS configuration
- ClusterFirstWithHostNet:
- For pods running with
hostNetwork: true
- Forces using cluster DNS instead of host DNS
- Needed when pods use host networking but still need to resolve cluster services
- For pods running with
Custom DNS Configuration
You can customize DNS settings regardless of DNS policy:
Headless Services for Direct Pod Access
When you need direct access to individual pods rather than load-balanced access:
With a headless service, DNS will return the pod IPs directly instead of the service IP.
Best Practices
- Use appropriate service types
- Use ClusterIP for internal-only services
- Use NodePort only for development or edge cases
- Use LoadBalancer for production external services
- Use ExternalName for integrating with external services
- Consider Ingress for HTTP/HTTPS applications to consolidate multiple services
- Implement network policies
- Start with a default deny policy and explicitly allow required traffic
- Create separate policies for ingress and egress
- Apply the principle of least privilege to all services
- Label pods and namespaces consistently for policy targeting
- Test network policies thoroughly before enforcing in production
- Example default deny policy:
- Configure health checks for all services
- Implement readiness probes to control traffic routing
- Use liveness probes to restart unhealthy containers
- Configure appropriate probe timeouts and thresholds
- Make health check endpoints lightweight and reliable
- Consider startup probes for slow-starting applications
- Example:
- Use meaningful DNS names and service discovery
- Create services with descriptive, consistent names
- Use headless services for stateful applications that need direct pod addressing
- Leverage DNS for service discovery instead of hardcoding IPs
- Use fully qualified domain names in critical paths
- Consider external DNS controllers for external-facing services
- Example:
- Monitor network performance and connectivity
- Implement network monitoring with Prometheus metrics
- Track network latency between services
- Monitor service connection errors and timeouts
- Set up alerts for network issues
- Regularly test cross-node connectivity
- Use tools like ksniff or tcpdump for troubleshooting
- Example:
- Optimize for performance
- Use services with 'externalTrafficPolicy: Local' to preserve client source IPs and reduce hops
- Consider topology-aware service routing for multi-zone clusters
- Use the appropriate CNI plugin for your workload's performance needs
- Tune MTU settings for your network environment
- Example:
- Secure external access properly
- Terminate TLS at the Ingress level
- Use cert-manager for automated certificate management
- Implement rate limiting for public endpoints
- Consider a service mesh for mTLS between services
- Use WAF (Web Application Firewall) for critical services
- Example:
- Plan for DNS scalability
- Configure appropriate DNS caching
- Monitor CoreDNS performance and scale horizontally if needed
- Consider NodeLocal DNSCache for large clusters
- Set appropriate ndots value to reduce unnecessary lookups
- Example NodeLocal DNSCache: