Skip to main content
Source

This page is generated from skills/eks-best-practices/references/networking-ingress-dns.md. Edit the source, not this page.

EKS Networking — Ingress, Load Balancing & DNS

Part of: eks-best-practices Purpose: Ingress patterns (ALB, NLB, Gateway API), AWS Load Balancer Controller, service mesh, DNS/CoreDNS tuning, private cluster connectivity

For VPC CNI, subnet planning, IPv6, and IP management, see: Networking For network policies and traffic control, see: Security — Runtime & Network


Table of Contents

  1. Ingress Patterns
  2. AWS Load Balancer Controller — ALB
  3. AWS Load Balancer Controller — NLB
  4. Gateway API
  5. Service Mesh Options
  6. DNS and CoreDNS
  7. Private Cluster Patterns
  8. Network Policies

Ingress Patterns

Ingress Controller Decision Matrix

ControllerProtocolUse WhenKey Feature
AWS ALB (via LBC)HTTP/HTTPS, gRPCWeb apps, REST APIsNative WAF, Cognito auth
AWS NLB (via LBC)TCP/UDP, TLSNon-HTTP, ultra-low latencyStatic IPs, preserve source IP
Gateway API + LBCHTTP/HTTPSNew standard, future-proofMulti-team route management
VPC LatticeHTTP/HTTPSCross-VPC, service-to-serviceNo ingress controller needed
NGINX IngressHTTP/HTTPSComplex routing, rate limitingMost configurable
Istio GatewayHTTP/HTTPS, TCPService mesh usersIntegrated with Istio

ALB vs NLB Quick Decision

FactorNLBALB
ProtocolTCP, UDP, TLSHTTP, HTTPS, gRPC (L7)
LatencyLower (L4)Higher (L7 processing)
Static IPsYes (Elastic IPs)No
Source IP preservationNativeVia X-Forwarded-For header
WAF integrationNoYes
Auth integrationNoYes (Cognito, OIDC)
Best forTCP/UDP, gRPC, low latencyHTTP web apps, WAF, auth

AWS Load Balancer Controller (ALB)

The AWS Load Balancer Controller provisions Application Load Balancers for Kubernetes Ingress resources. ALB is the default ingress pattern for HTTP/HTTPS workloads, with native AWS WAF, Cognito, and ACM integration.

ALB Ingress Example

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip # Required for Fargate
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:...
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06
alb.ingress.kubernetes.io/wafv2-acl-arn: arn:aws:wafv2:...
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80

Key ALB Annotations

AnnotationPurposeCommon Values
alb.ingress.kubernetes.io/schemeInternet-facing or internalinternet-facing, internal
alb.ingress.kubernetes.io/target-typeHow pods are registeredip (recommended), instance
alb.ingress.kubernetes.io/group.nameShare ALB across IngressesAny string (e.g., shared-alb)
alb.ingress.kubernetes.io/listen-portsListener ports[{"HTTPS":443}]
alb.ingress.kubernetes.io/certificate-arnACM certificateACM ARN
alb.ingress.kubernetes.io/ssl-redirectHTTP to HTTPS redirect443
alb.ingress.kubernetes.io/wafv2-acl-arnWAF integrationWAF ACL ARN
alb.ingress.kubernetes.io/auth-typeAuthenticationcognito, oidc
alb.ingress.kubernetes.io/ip-address-typeIPv4 or dual-stackipv4, dualstack

IP Mode vs Instance Mode

FactorIP ModeInstance Mode
Target registrationPod IP directlyNode IP + NodePort
Network hopsFewer (ALB → pod)More (ALB → node → pod)
Pod densityBetter (no NodePort exhaustion)Limited by NodePort range
Fargate supportYesNo
RecommendationDefault choiceLegacy or specific requirements

✅ DO:

  • Use IP target type for new deployments — fewer hops, better performance
  • Use group.name to share a single ALB across multiple Ingress resources — reduces cost and avoids ALB limits
  • Enable SSL redirect (HTTP → HTTPS) for all internet-facing ALBs
  • Attach WAF ACL for internet-facing ALBs
  • Configure appropriate health check paths — ALB defaults may not match your app

❌ DON'T:

  • Create one ALB per Ingress without grouping — expensive and hits ALB quotas
  • Use instance target type with Fargate (not supported)
  • Mix Ingress annotations from different controllers

AWS Load Balancer Controller (NLB)

The LBC provisions Network Load Balancers for Kubernetes Services of type LoadBalancer. NLB handles TCP/UDP workloads, gRPC, and scenarios requiring static IPs or source IP preservation.

NLB Service Example

apiVersion: v1
kind: Service
metadata:
name: app-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: internet-facing
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 443
targetPort: 8443
protocol: TCP

Key NLB Annotations

AnnotationPurposeCommon Values
service.beta.kubernetes.io/aws-load-balancer-typeUse LBC (not in-tree)external
service.beta.kubernetes.io/aws-load-balancer-nlb-target-typeTarget registrationip (recommended), instance
service.beta.kubernetes.io/aws-load-balancer-schemeInternet-facing or internalinternet-facing, internal
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol-v2-enabledProxy protocoltrue, false
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabledCross-AZ balancingtrue
service.beta.kubernetes.io/aws-load-balancer-ssl-certTLS termination at NLBACM ARN

✅ DO:

  • Use aws-load-balancer-type: external to ensure LBC manages the NLB (not the legacy in-tree controller)
  • Use IP target type for consistency with ALB and fewer network hops
  • Enable cross-zone load balancing for even traffic distribution

❌ DON'T:

  • Use NLB for HTTP workloads that need WAF or Cognito — use ALB instead
  • Forget to set externalTrafficPolicy: Local if you need source IP preservation with instance targets

Gateway API

Gateway API is the successor to the Ingress resource, offering role-oriented resource model and multi-team route management. Recommended for new deployments.

# GatewayClass (one per cluster — defines which controller)
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: amazon-alb
spec:
controllerName: application-networking.k8s.aws/gateway-api-controller

---
# Gateway (per team/environment — defines listeners)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: app-gateway
spec:
gatewayClassName: amazon-alb
listeners:
- name: https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- name: app-cert

---
# HTTPRoute (per service — defines routing rules)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-route
spec:
parentRefs:
- name: app-gateway
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 80

Why Gateway API over Ingress:

  • Role separation — infrastructure teams manage GatewayClass/Gateway, application teams manage HTTPRoutes
  • Multi-team — multiple HTTPRoutes can attach to one Gateway without annotation conflicts
  • Richer routing — header matching, traffic splitting, URL rewriting built-in
  • Portable — same resources work across ALB, NLB, NGINX, Istio, and other implementations

✅ DO:

  • Use target-type: ip for pod-direct traffic (required for Fargate)
  • Use Gateway API for new multi-team setups — cleaner separation of concerns than Ingress

❌ DON'T:

  • Mix Gateway API and Ingress for the same service — pick one approach
  • Forget to set health check paths on ALB target groups

Service Mesh Options

OptionManagedComplexityBest For
VPC LatticeFully managedLowCross-VPC, AWS-native
Istio (on EKS)Self-managedHighFull service mesh features
App MeshAWS managedMediumMaintenance mode — avoid for new projects

VPC Lattice is recommended for new AWS-native service-to-service networking:

  • No sidecar proxies needed
  • Cross-VPC and cross-account routing
  • IAM-based auth policies
  • Integrates with Gateway API

DNS and CoreDNS

CoreDNS Tuning for Large Clusters

Scale CoreDNS with cluster size:

# Enable CoreDNS autoscaling via proportional autoscaler
apiVersion: apps/v1
kind: Deployment
metadata:
name: dns-autoscaler
namespace: kube-system
spec:
# Scales CoreDNS replicas based on node/core count
# linear: {"coresPerReplica": 256, "nodesPerReplica": 16, "min": 2, "max": 10}

Optimize DNS resolution:

# Pod DNS config — reduce search domain lookups
apiVersion: v1
kind: Pod
spec:
dnsConfig:
options:
- name: ndots
value: "2" # Default is 5, causing unnecessary search domain queries
dnsPolicy: ClusterFirst

Deploy NodeLocal DNSCache for clusters >100 nodes — reduces CoreDNS load by 80%+. Note: NodeLocal DNSCache is not supported with Security Groups for Pods in strict mode, because strict mode routes all traffic through the VPC (including traffic to the node).

✅ DO:

  • Deploy NodeLocal DNSCache for clusters >100 nodes
  • Set ndots: 2 for pods making many external DNS calls
  • Monitor CoreDNS metrics (cache hit rate, latency, errors)
  • Use proportional autoscaler — don't manually set replica counts

❌ DON'T:

  • Run CoreDNS with only 2 replicas on large clusters
  • Ignore DNS latency as source of application slowness
  • Enable DNS64 on subnets with IPv6 pods unless you intend NAT64 routing (causes unexpected NAT GW costs)

External DNS

# Auto-manage Route 53 records for Services/Ingresses
helm install external-dns external-dns/external-dns \
--set provider=aws \
--set policy=sync \
--set registry=txt \
--set txtOwnerId=my-cluster

Private Cluster Patterns

Fully Private Cluster

No public endpoint, all traffic stays within VPC:

# Terraform configuration
resource "aws_eks_cluster" "private" {
vpc_config {
endpoint_private_access = true
endpoint_public_access = false
subnet_ids = var.private_subnet_ids
}
}

Required VPC endpoints:

  • com.amazonaws.<region>.eks — EKS API
  • com.amazonaws.<region>.eks-auth — EKS auth
  • com.amazonaws.<region>.ecr.api — ECR API
  • com.amazonaws.<region>.ecr.dkr — ECR Docker
  • com.amazonaws.<region>.s3 (Gateway) — ECR image layers
  • com.amazonaws.<region>.sts — STS for IRSA/Pod Identity
  • com.amazonaws.<region>.logs — CloudWatch Logs
  • com.amazonaws.<region>.ec2 — EC2 API (for nodes)
  • com.amazonaws.<region>.elasticloadbalancing — ELB (if using LBC)

Access Patterns for Private Clusters

Access MethodComplexityUse When
VPN/Direct ConnectMediumExisting corporate network
SSM Session ManagerLowAd-hoc access via bastion
PrivateLinkMediumCross-VPC or cross-account
Cloud9 in VPCLowDevelopment/testing

Network Policies

For detailed network policy guidance including default-deny patterns, DNS allow rules, and policy engine comparison (VPC CNI native, Calico, Cilium), see Security — Runtime & Network.

Quick summary:

OptionStandardEKS SupportFeatures
VPC CNI Network PolicyK8s NetworkPolicyNative (v1.14+)L3/L4 policies, eBPF-based
CalicoK8s + Calico extendedAdd-onL3/L4 + DNS-based policies
CiliumK8s + Cilium extendedSelf-managedL3/L4/L7 + DNS + identity

Recommendation: Use VPC CNI native network policies for most workloads. Use Cilium or Calico only if you need L7 policies or advanced features like DNS hostname rules.


Sources: