Zum Inhalt springen

Application Load Balancer (ALB) Ingress

Zuletzt aktualisiert am

The STACKIT Application Load Balancer Controller Manager (ALBCM) exposes HTTP/HTTPS applications by provisioning and configuring managed STACKIT ALBs based on native Kubernetes Ingress resources.

The Application Load Balancer integration is disabled by default and can be activated for your cluster through the SKE-API by setting the enabled field to true inside the applicationLoadBalancer block under extensions:

{
"extensions": {
"applicationLoadBalancer": {
"enabled": true
}
}
}

To expose an application, you need to deploy three core resources: an IngressClass to provision the ALB, a Service to expose your pods, and an Ingress to define the routing.

Creating an IngressClass provisions the managed ALB instance. By default, the ALB is assigned a public ephemeral IP address, unless you configure it as an internal ALB or assign a pre-existing static IP using annotations (see Configuration).

If no Ingress resources are linked to this class, the ALB acts as an empty listener that returns an HTTP 404 Not Found.

You must include the alb.stackit.cloud/network-mode: "NodePort" annotation on the IngressClass. This is mandatory because it tells the ALB how to reach your cluster, instructing the load balancer to route incoming traffic directly to the node ports on your cluster’s worker nodes. At the moment, NodePort is the only supported network mode.

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: stackit-alb
annotations:
alb.stackit.cloud/network-mode: "NodePort"
spec:
controller: stackit.cloud/alb-ingress

Expose your application pods using a Kubernetes Service.

apiVersion: v1
kind: Service
metadata:
name: service-a
namespace: default
labels:
app: service-a
spec:
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: service-a

Create the Ingress resource to route incoming traffic to your backend Service. Link it to your ALB by referencing the IngressClass name.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: service-ingress
namespace: default
spec:
ingressClassName: stackit-alb
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-a
port:
number: 80

The controller automatically merges all Ingress resources that reference the same IngressClass onto a single, shared ALB instance. To provision completely isolated ALBs (for example, to separate public and internal traffic or to assign different static IPs) you must create a distinct IngressClass for each one.

If you delete all Ingress resources associated with a specific class, the controller does not delete the underlying ALB infrastructure. Instead, it transitions the ALB into an empty state that returns HTTP 404 responses. This behavior preserves your allocated IP address and prevents unnecessary infrastructure recreation delays.

To completely delete the ALB and release its associated resources, you must delete the IngressClass.

When multiple Ingress resources share an ALB, their routing rules are evaluated chronologically by default, meaning older Ingress resources take precedence based on their CreationTimestamp.

You can override this default order by adding the alb.stackit.cloud/priority annotation to an Ingress. Higher integer values are evaluated first, and in the event of a tie, the controller falls back to the creation timestamp.

The top-to-bottom order of paths defined within a single Ingress YAML is non-deterministic. If your application requires strict ordering, you must split the rules into separate Ingress resources and assign explicit priority annotations to each.

The minimal Ingress example under Getting started shows a plain, unencrypted HTTP configuration. To expose your application securely through HTTPS, the ALB Ingress controller supports TLS offloading using standard Kubernetes TLS Secrets.

This functionality integrates seamlessly with tools like cert-manager to automate certificate provisioning and renewal. When a Secret is referenced in the Ingress tls block, the controller automatically handles the certificate deployment on the ALB. It continuously monitors the Secret for changes, such as during automated certificate rotation, and updates the ALB without manual intervention. Once a TLS Secret is no longer referenced by any Ingress on that ALB, it is automatically removed.

By default, standard unencrypted HTTP traffic is still be possible alongside HTTPS to make automated ACME certificate challenges possible. If you want to restrict traffic so the Ingress is not reachable through standard HTTP, you can add the alb.stackit.cloud/https-only: "true" annotation to your Ingress or IngressClass resource.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-ingress
namespace: default
spec:
ingressClassName: stackit-alb
tls:
- hosts:
- secure.example.com
secretName: my-tls-secret
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-a
port:
number: 80

The STACKIT ALB Ingress controller only supports Kubernetes Service backends. Routing traffic to Resource backends (such as individual Pods or other custom resources) is not supported at this time.

The ALB integration deploys a background validating webhook running alongside the ALB Ingress controller. This webhook automatically reviews incoming Ingress and IngressClass object modifications (creations and updates) preventing invalid properties or conflicting parameters from being applied.

Optimizing traffic with externalTrafficPolicy

Section titled “Optimizing traffic with externalTrafficPolicy”

By default, Kubernetes Services use externalTrafficPolicy: Cluster. Under this policy, every worker node passes the ALB’s health checks because kube-proxy accepts the incoming traffic on any node and automatically routes it over the internal network to a node that is actually running your pod.

However, this setup can cause issues when pods are shutting down or nodes are scaling down. Because the ALB relies on passively probing the data port, it only detects failures through connection timeouts. This means the ALB might still send traffic to a node while its pods are actively shutting down, or during the brief window after a node goes down but before the next health probe officially fails. Routing incoming user requests during this delay results in dropped connections and timeout errors.

To prevent these dropped connections during deployments and cluster scale-down, you can change your Service to use externalTrafficPolicy: Local.

When correctly configured, Kubernetes exposes a dedicated health check port (healthCheckNodePort) on every node. The STACKIT ALB controller automatically detects this and reconfigures the ALB to probe this health port instead of the standard data port.

If a node lacks active pods, or if its pods enter a Terminating state, the health port instantly returns an HTTP 503 error. The ALB registers the failure immediately and pulls the node out of rotation before user connections can be dropped. As an added benefit, this policy also prevents internal network hops and preserves the client’s original IP address.

To enable this behavior, update your backend Service configuration:

apiVersion: v1
kind: Service
metadata:
name: service-a
namespace: default
labels:
app: service-a
spec:
type: LoadBalancer
loadBalancerClass: alb
externalTrafficPolicy: Local
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: service-a

The following limitations are imposed directly by the STACKIT ALB API (not the controller itself):

  • Maximum targets per pool: An individual target pool can contain a maximum of 250 targets.
  • Maximum listeners per ALB: A single ALB instance supports a maximum of 20 listeners.

A “target” in a pool corresponds directly to a worker node in your cluster. If you run a large cluster with a high number of worker nodes, or expect your cluster to dynamically scale to a large size, keep this limit in mind since a single backend Service port mapping cannot route traffic to more than 250 worker nodes simultaneously.

Because each IngressClass provisions a dedicated ALB instance, hitting the 20-listener threshold is rarely an issue for a basic setup but becomes a real risk when you start stacking custom ports across multiple applications sharing that same ALB.

If your Ingress resources use the alb.stackit.cloud/http-port or alb.stackit.cloud/https-port annotations to expose different apps on unique custom port numbers, each distinctive port allocates its own listener on the shared ALB instance.

This risk compounds when those applications also require TLS encryption; since the controller must keep an extra HTTP listener active alongside the HTTPS listener to process automated ACME certificate challenges, a single secure app immediately consumes two slots instead of one, accelerating how fast you approach the API limit if multiple unique custom ports are configured.

Configure the STACKIT Application Load Balancer using the following annotations:

  • defaultBackend support:
    The ALB Ingress Controller does not support the defaultBackend field on Ingress resources.