When deploying your application on EKS, using ALB to expose it is the most cloud-native approach. The AWS Load Balancer Controller
simplifies the process of converting Kubernetes-native Ingress into AWS-native ALB automatically.
The Ingress
objects are namespace-scoped. What happens if your applications are deployed in multiple namespaces? By default, the AWS Load Balancer Controller will create a separate ALB for each ingress object. Even if there are multiple Ingress
objects in the same namespace, you will end up having an individual ALB for each of them. And that's perfectly fine.
However, if you have 50 or 100 namespaces, and your application needs to be deployed in multiple namespaces, you will incur higher costs because each ALB will charge you for the number of hours they remain active, even if you do not use them.
There is a simple trick to consolidate all Ingress
objects into a single ALB, where all those routes will be combined into ALB rule
groups. All you need to do is annotate each Ingress
with the following labels.
alb.ingress.kubernetes.io/group.name: myapp
For all matching group.name
labels in all namespaces, the AWS Load Balancer Controller
will create a single ALB with multiple rules inside it. Here is a detailed example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-1:987654321:certificate/37c33c94-e3be-41cc-9ec8-fd16b2873bd4
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-name: myapp
alb.ingress.kubernetes.io/group.name: myapp
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: "200"
alb.ingress.kubernetes.io/target-type: instance
kubernetes.io/ingress.class: alb
name: myapp-dev
namespace: myapp-dev
spec:
rules:
- host: myapp-dev.example.com
http:
paths:
- backend:
service:
name: app
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-1:987654321:certificate/37c33c94-e3be-41cc-9ec8-fd16b2873bd4
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-name: myapp
alb.ingress.kubernetes.io/group.name: myapp
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: "200"
alb.ingress.kubernetes.io/target-type: instance
kubernetes.io/ingress.class: alb
name: myapp-stage
namespace: myapp-prstageod
spec:
rules:
- host: myapp-stage.example.com
http:
paths:
- backend:
service:
name: app
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-1:987654321:certificate/37c33c94-e3be-41cc-9ec8-fd16b2873bd4
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-name: myapp
alb.ingress.kubernetes.io/group.name: myapp
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: "200"
alb.ingress.kubernetes.io/target-type: instance
kubernetes.io/ingress.class: alb
name: myapp-prod
namespace: myapp-prod
spec:
rules:
- host: myapp.example.com
http:
paths:
- backend:
service:
name: app
port:
number: 80
path: /
pathType: Prefix
You can find all available annotations here: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/guide/ingress/annotations/