NodePort & LoadBalancer
[!NOTE] This module explores the core principles of NodePort & LoadBalancer, deriving solutions from first principles and hardware constraints to build world-class, production-ready expertise.
1. NodePort: The Quick & Dirty Way
ClusterIP is great for internal traffic, but how do external users reach your app?
NodePort opens a specific port on every node in your cluster.
- Port Range: By default, Kubernetes allocates a port between 30000-32767.
- Accessibility: You can access the service via
<AnyNodeIP>:<NodePort>. - Routing:
kube-proxyrules on the node forward traffic from that port to the Service’s ClusterIP, which then load-balances to a Pod.
Limitations
- Security: Opening high ports on every node increases the attack surface.
- Client Complexity: Clients must know the IP address of your nodes. If a node dies, the client must switch IPs.
- Port Management: You have to manage port conflicts.
2. LoadBalancer: The Production Standard
If you run on a cloud provider (AWS, GCP, Azure), you can use the LoadBalancer type.
This asks the Cloud Controller Manager (CCM) to provision a real, physical (or software-defined) Load Balancer outside your cluster.
- Provisioning: Kubernetes talks to the cloud API (e.g., AWS EC2 API).
- Configuration: It configures the Cloud LB to forward traffic to the Kubernetes Nodes on a specific NodePort.
- Access: You get a stable external IP or DNS name (e.g.,
my-lb-123.us-east-1.elb.amazonaws.com).
[!IMPORTANT] Cost Warning: Each
LoadBalancerservice typically provisions a dedicated cloud resource (like an AWS Classic ELB or NLB), which costs money per hour.
3. Interactive: Traffic Flow Visualizer
Trace the packet path from an external user to your Pod via LoadBalancer and NodePort.
User
LoadBalancer
NodePort
Pod
4. Code Example: Manifests
apiVersion: v1
kind: Service
metadata:
name: public-api
annotations:
# AWS Specific Annotation to create Network Load Balancer
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: api
ports:
- protocol: TCP
port: 80 # Port exposed on the Load Balancer
targetPort: 8080 # Port on the Pod
apiVersion: v1
kind: Service
metadata:
name: debug-svc
spec:
type: NodePort
selector:
app: debug
ports:
- protocol: TCP
port: 80
nodePort: 30007 # Optional: Manually specify port (30000-32767)
targetPort: 8080
5. External Traffic Policy
By default, when traffic hits a NodePort, it is load-balanced to any pod in the cluster (even if it’s on a different node). This causes an extra network hop (SNAT).
To preserve the client IP address and avoid the hop, set externalTrafficPolicy: Local.
spec:
type: LoadBalancer
externalTrafficPolicy: Local
Trade-off: If a node has no pods for that service, traffic sent to that node will be dropped (health checks usually handle this).