Amazon EKS — NLB Services
Network Load Balancers operate at Layer 4, handling TCP, UDP, and TLS traffic. On EKS, an NLB is created when you annotate a Service of type LoadBalancer.
Basic NLB Service
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: production
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
spec:
type: LoadBalancer
selector:
app: api
ports:
- port: 443
targetPort: 8443
protocol: TCP
Instance vs IP Target Types
| Target Type | How It Works | When to Use |
|---|---|---|
| ip | NLB targets pod IPs directly | Recommended; lower latency; required for Fargate |
| instance | NLB targets node IPs with NodePort | Legacy; source IP preservation without proxy protocol |
# IP mode (recommended)
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
# Instance mode
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"
Internal NLB
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internal"
Cross-Zone Load Balancing
annotations:
service.beta.kubernetes.io/aws-load-balancer-attributes: "load_balancing.cross_zone.enabled=true"
Without cross-zone, traffic stays within the AZ of the NLB node — this can cause uneven distribution if pods aren’t evenly spread.
Static IP with Elastic IPs
NLB supports Elastic IP assignment for static IPs:
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-eip-allocations: "eipalloc-aaa,eipalloc-bbb,eipalloc-ccc"
service.beta.kubernetes.io/aws-load-balancer-subnets: "subnet-aaa,subnet-bbb,subnet-ccc"
Static IPs are essential for:
- DNS whitelisting
- Firewall rules
- Partner API integrations
Health Checks
annotations:
service.beta.kubernetes.io/aws-load-balancer-healthcheck-protocol: "HTTP"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-path: "/healthz"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "8080"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "10"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "2"
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "2"
Source IP Preservation
| Target Type | Source IP Preserved? | Notes |
|---|---|---|
| ip | Yes | Client IP visible directly |
| instance | Yes (with proxy protocol) | Enable proxy protocol on NLB |
For IP mode, the client’s source IP is preserved by default. For instance mode:
annotations:
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
NLB vs ALB Comparison
| Feature | ALB | NLB |
|---|---|---|
| Layer | 7 (HTTP/HTTPS) | 4 (TCP/UDP/TLS) |
| K8s resource | Ingress | Service |
| Path routing | Yes | No |
| Static IP | No | Yes (Elastic IP) |
| WAF | Yes | No |
| Performance | ~100ms added latency | Millions of requests/sec, ultra-low latency |
| Idle timeout | 60s (up to 4000s) | 350s |
| Price | ~$16/month + LCU | ~$16/month + NLCU |
| Use case | Web apps, APIs | gRPC, gaming, IoT, TCP services |
Key Annotations Reference
| Annotation | Description | Example |
|---|---|---|
aws-load-balancer-type |
Controller type | "external" |
aws-load-balancer-nlb-target-type |
ip or instance | "ip" |
aws-load-balancer-scheme |
Facing | "internet-facing" |
aws-load-balancer-subnets |
Subnet IDs or names | "subnet-a,subnet-b" |
aws-load-balancer-eip-allocations |
Elastic IP allocations | "eipalloc-a,eipalloc-b" |
aws-load-balancer-attributes |
NLB attributes | "load_balancing.cross_zone.enabled=true" |
aws-load-balancer-ssl-cert |
ACM cert ARN | "arn:aws:acm:..." |
aws-load-balancer-ssl-ports |
TLS listener ports | "443" |
Best Practices
- Use IP target type — lower latency, required for Fargate
- Enable cross-zone load balancing — prevents uneven traffic distribution
- Use Elastic IPs when you need static addressable endpoints
- Choose NLB for TCP/UDP workloads — gRPC, databases, gaming, IoT
- Choose ALB for HTTP/HTTPS — path routing, WAF, header-based routing