The AWS Load Balancer Controller, formerly known as the ALB Ingress Controller, is how you get your EKS-hosted applications accessible from the outside world. It watches Kubernetes Ingress resources and provisions AWS Application Load Balancers (ALBs) to match.

Let’s see it in action.

Imagine you have a simple web service running in EKS.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-webapp
  template:
    metadata:
      labels:
        app: my-webapp
    spec:
      containers:
      - name: webapp
        image: nginx:latest # Replace with your actual web app image
        ports:
        - containerPort: 80

This deploys two pods running Nginx. Now, to expose this, we need an Ingress resource.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-webapp-service # This service needs to exist
            port:
              number: 80

This Ingress object tells the AWS Load Balancer Controller:

  • kubernetes.io/ingress.class: alb: Use the ALB controller.
  • alb.ingress.kubernetes.io/scheme: internet-facing: Create a public-facing ALB.
  • alb.ingress.kubernetes.io/target-type: ip: The ALB will target pods directly using their IP addresses. This is generally preferred for EKS.
  • alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]': The ALB should listen on HTTP port 80.
  • The spec.rules define that any traffic to the root path (/) should be routed to the my-webapp-service on port 80.

Before applying the Ingress, you must have a Kubernetes Service that selects your deployment’s pods.

apiVersion: v1
kind: Service
metadata:
  name: my-webapp-service
spec:
  selector:
    app: my-webapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

Once you apply both the Deployment, Service, and Ingress resources to your EKS cluster, the AWS Load Balancer Controller will detect the Ingress object. It will then call the AWS API to provision an ALB. This process takes a few minutes. You can check the status of the ALB provisioning by looking at the Ingress object’s events:

kubectl describe ingress my-ingress

You’ll see events indicating the ALB is being created and eventually, an ADDRESS field will populate with the DNS name of your ALB. You can then access your web application via this DNS name.

The controller manages the lifecycle of the ALB. If you delete the Ingress resource, the controller will automatically delete the associated ALB. If you update the Ingress (e.g., change the path or target service), the controller will update the ALB’s listener rules and target groups accordingly.

The controller itself is deployed as a Kubernetes Deployment within your cluster, typically in the kube-system namespace. It requires specific IAM permissions to create and manage AWS resources like ALBs, Target Groups, and Listener Rules. You grant these permissions by attaching an IAM policy to the IAM role associated with the controller’s Kubernetes service account.

One crucial aspect often overlooked is how the controller handles health checks. By default, for ip target types, it configures a TCP health check on the targetPort specified in your Kubernetes Service. However, if your application requires a specific HTTP endpoint for health checks (e.g., /healthz), you can configure this using an annotation on the Ingress resource: alb.ingress.kubernetes.io/healthcheck-path: /healthz. The controller will then update the ALB’s Target Group health check configuration to use this path and an HTTP protocol, ensuring the ALB only sends traffic to healthy application instances.

The controller can also manage multiple hostnames and paths within a single Ingress resource, creating multiple listener rules on the ALB to route traffic based on host headers and URL paths. This allows for sophisticated routing configurations without needing multiple ALBs for simple scenarios.

The next step in exposing services is often dealing with TLS termination for HTTPS traffic, which involves configuring certificates and listener rules on the ALB.

Want structured learning?

Take the full Eks course →