Skip to content

PATTERN Cited by 1 source

Shared ALB with path-based multi-cluster routing

Pattern

Use one internet-facing Application Load Balancer (with an ACM certificate terminating HTTPS) to serve applications running in many different virtual clusters on a shared host EKS cluster. Each application's Ingress object — declared inside its own vcluster — gets synced to the host cluster and aggregated by the AWS Load Balancer Controller into a single ALB with per-path rules (/app1, /app2, …).

Problem it solves

The naive shared- host-cluster-with-virtual-clusters topology still costs 1 ALB + 1 Route 53 record + 1 ACM certificate per virtual cluster if each vcluster stands up its own independent ingress. At 50+ vclusters that's 50+ ALBs — collapsing the vcluster-density cost savings and reintroducing operational surface (50 ALBs to monitor, 50 DNS records to manage, 50 ACM certs to rotate).

Structure

  Internet users
       │ HTTPS
  ┌──────────────────────────────────────────┐
  │       One ALB (TLS via one ACM cert)     │
  │     group.name = "vcluster"              │
  │   ┌──────────────────────────────────┐   │
  │   │  Listener rules (path-based):    │   │
  │   │    /app1  →  TG for app1         │   │
  │   │    /app2  →  TG for app2         │   │
  │   │    /appN  →  TG for appN         │   │
  │   └──────────────────────────────────┘   │
  └──────────────────────────────────────────┘
             ▼  (targets are host-side pods)
  ┌────────────────────────────────────────────┐
  │           Host EKS cluster                  │
  │   ┌────────┐   ┌────────┐   ┌────────┐    │
  │   │vcluster│   │vcluster│   │vcluster│    │
  │   │   1    │   │   2    │   │   N    │    │
  │   │(app1)  │   │(app2)  │   │(appN)  │    │
  │   └────────┘   └────────┘   └────────┘    │
  │   AWS Load Balancer Controller (one)      │
  └────────────────────────────────────────────┘

Key config details (from Deloitte's walkthrough)

On the host cluster, declare an IngressClassParams with a shared group name and make it the default ingress class:

apiVersion: eks.amazonaws.com/v1
kind: IngressClassParams
metadata:
  name: alb
spec:
  scheme: internet-facing
  group:
    name: vcluster                   # ← the magic: all Ingresses with
                                      #    this group share one ALB
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: alb
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: eks.amazonaws.com/alb
  parameters:
    apiGroup: eks.amazonaws.com
    kind: IngressClassParams
    name: alb

Per vcluster, enable Ingress sync to the host so the host's controller sees the vcluster's Ingresses:

sync:
  fromHost:
    ingressClasses:
      enabled: true
    storageClasses:
      enabled: true
  toHost:
    ingresses:
      enabled: true

Per application in each vcluster, declare an Ingress that references the shared ALB by name and sets the rule order:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echoserver
  namespace: echoserver
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: vcluster-alb
    alb.ingress.kubernetes.io/subnets: <subnet ids>
    alb.ingress.kubernetes.io/certificate-arn: <acm arn>
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/group.order: "-999"
spec:
  ingressClassName: alb
  rules:
    - host: <domain name>
      http:
        paths:
          - path: /<app name>
            pathType: ImplementationSpecific
            backend:
              service:
                name: echoserver
                port:
                  number: 80

The load-balancer-name: vcluster-alb annotation is identical across all vclusters' app Ingresses — that's how the AWS LB Controller knows to aggregate them into one ALB. The group.order controls rule precedence in the listener.

What this buys you

  • One ALB cost instead of N — at 50+ vclusters, material cost difference.
  • One ACM certificate instead of N — one cert rotation cadence instead of 50.
  • One Route 53 alias instead of N — one DNS record to maintain.
  • Simpler monitoring and troubleshooting — one access-log stream, one target-group dashboard.
  • Unified request-level observability — all traffic across vclusters funnels through one ALB, so a single place surfaces aggregate RPS / error rates.

Trade-offs

Costs / risks:

  • Single point of failure — the one ALB outage impacts all 50+ vclusters' applications simultaneously. For QA / pre-prod this is usually acceptable; for production it would not be (use multi-ALB + weighted DNS, or separate ALB groups per criticality tier).
  • Shared listener-rule budget — ALBs have listener-rule limits (default 100 rules per ALB, higher with limit increases). At high vcluster density with multiple paths per vcluster, you can hit this.
  • Host / path collision discipline — two vclusters trying to claim the same path on the same host is a silent misconfig. The group.order annotation makes precedence explicit but doesn't prevent conflict by construction.
  • Cross-vcluster blast radius at the LB layer — an application bug in vcluster-A that causes the ALB target group to fail health checks can affect shared-ALB capacity planning for vcluster-B.
  • TLS cert fate-sharing — one ACM cert rotation bug affects every vcluster's public HTTPS.

Mitigations:

  • Partition ALB groups by criticality or team (one group.name: vcluster-qa ALB, another vcluster-preprod, etc.) to scope blast radius.
  • Use WAF + rate-limiting rules at the ALB to protect against per-vcluster traffic anomalies.
  • Operate the shared ALB under tighter SLO discipline than the individual applications, since it's now fate-shared.

When to use

  • QA / pre-prod environments where cost simplification dominates blast-radius concerns.
  • Test fleets with 10+ concurrent isolated applications sharing one host cluster.

When not to use

  • Production workloads with diverse SLOs — use separate ALBs per service tier.
  • Workloads requiring per-vcluster TLS cert identity (mTLS with vcluster-specific client cert validation) — the shared ALB uses one server cert.

Seen in

  • sources/2026-04-27-aws-deloitte-optimizes-eks-environment-provisioning-with-vcluster — canonical anchor. Deloitte's architecture: one internet-facing ALB named vcluster-alb, one ACM-terminated HTTPS listener, path-based rules for each app across 50+ virtual clusters. Verbatim framing: "The architecture was further streamlined by implementing a single load balancer capable of serving traffic to applications across multiple virtual clusters. This reduced complexity and simplified monitoring and troubleshooting." Figure 6 of the post shows the aggregated ALB listener with per-app rules. Full walkthrough config captured on the source page.
Last updated · 427 distilled / 1,229 read