Amazon EKS — ALB Ingress

2 minute read

The AWS Load Balancer Controller creates an Application Load Balancer (ALB) for each Ingress resource. ALBs provide Layer 7 routing with path-based, host-based, and header-based rules.


Basic Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  namespace: production
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
spec:
  ingressClassName: alb
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-app
                port:
                  number: 80

Path-Based Routing

Route different paths to different backend services:

spec:
  ingressClassName: alb
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /api/v1
            pathType: Prefix
            backend:
              service:
                name: api-v1
                port:
                  number: 80
          - path: /api/v2
            pathType: Prefix
            backend:
              service:
                name: api-v2
                port:
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-frontend
                port:
                  number: 80

Host-Based Routing

spec:
  ingressClassName: alb
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: main-app
                port:
                  number: 80
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80

Target Types

Type How It Works Use Case
ip ALB sends directly to pod IP Default; best performance; required for Fargate
instance ALB sends to node’s NodePort Legacy; higher latency (extra hop through kube-proxy)
annotations:
  alb.ingress.kubernetes.io/target-type: ip    # Recommended

Internet-Facing vs Internal

# Internet-facing (public subnets)
annotations:
  alb.ingress.kubernetes.io/scheme: internet-facing

# Internal (private subnets)
annotations:
  alb.ingress.kubernetes.io/scheme: internal

IngressGroup — Shared ALB

By default, each Ingress creates a separate ALB. Use IngressGroup to share one ALB across multiple Ingresses:

# Ingress A — team-alpha
metadata:
  annotations:
    alb.ingress.kubernetes.io/group.name: shared-alb
    alb.ingress.kubernetes.io/group.order: "1"
spec:
  rules:
    - host: alpha.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: alpha-service
                port:
                  number: 80
---
# Ingress B — team-beta
metadata:
  annotations:
    alb.ingress.kubernetes.io/group.name: shared-alb
    alb.ingress.kubernetes.io/group.order: "2"
spec:
  rules:
    - host: beta.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: beta-service
                port:
                  number: 80

Both Ingress resources share one ALB — saves cost.


WAF Integration

Attach an AWS WAF Web ACL to the ALB:

annotations:
  alb.ingress.kubernetes.io/waf-acl-id: "arn:aws:wafv2:us-east-1:123456789:regional/webacl/my-web-acl/abc123"

Health Checks

annotations:
  alb.ingress.kubernetes.io/healthcheck-path: /healthz
  alb.ingress.kubernetes.io/healthcheck-port: "8080"
  alb.ingress.kubernetes.io/healthcheck-interval-seconds: "15"
  alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5"
  alb.ingress.kubernetes.io/healthy-threshold-count: "2"
  alb.ingress.kubernetes.io/unhealthy-threshold-count: "3"
  alb.ingress.kubernetes.io/success-codes: "200-299"

Key Annotations Reference

Annotation Description Example
scheme Internet-facing or internal internet-facing
target-type ip or instance ip
listen-ports Listeners '[{"HTTPS":443}]'
certificate-arn ACM certificate arn:aws:acm:...
ssl-redirect HTTP→HTTPS redirect port "443"
group.name Shared ALB group my-shared-alb
waf-acl-id WAF Web ACL ARN arn:aws:wafv2:...
subnets Explicit subnet IDs subnet-a,subnet-b
security-groups ALB security groups sg-abc,sg-def

Best Practices

  1. Use IP target type — reduces latency, required for Fargate, avoids NodePort exhaustion
  2. Use IngressGroup for shared ALBs — each ALB costs ~$16/month; sharing saves money
  3. Always use HTTPS with ACM certificates — see TLS & ACM Integration
  4. Attach WAF for internet-facing ALBs — protects against common web exploits
  5. Configure health checks — match your application’s actual health endpoint

Updated: