Uplink
An Uplink is a Custom Resource Definition (CRD) used for inter-cluster service advertisement in multi-cluster deployments.
A child cluster declares an Uplink to advertise to a parent cluster that it can handle a particular workload. This advertisement is automatically materialized as a service on the parent cluster, enabling the parent to route traffic to the advertised workload.
Overview
The Uplink resource works with:
- Uplink Entry Points: Entry points on child clusters for inter-cluster communication
- Multi-Cluster Provider: Provider on parent clusters that discovers and routes to uplinks
Configuration Example
- Basic Uplink
- Uplink with EntryPoints
- Uplink with Health Check
- IngressRoute referencing Uplink
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
weight: 10
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
entryPoints:
- multicluster
weight: 5
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
entryPoints:
- multicluster
weight: 10
healthCheck:
path: /health
interval: 10s
timeout: 3s
status: 200
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
entryPoints:
- multicluster
weight: 10
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-route
namespace: apps
annotations:
hub.traefik.io/router.uplinks: "apps-api-workload"
spec:
routes:
- match: PathPrefix(`/api`)
kind: Rule
services:
- name: api-service
port: 8080
Configuration Options
| Field | Description | Default | Required |
|---|---|---|---|
kind | Resource kind. Must be Uplink. | - | Yes |
metadata.name | Name of the Uplink. Used to reference this uplink from routers and to create services on the parent cluster. | - | Yes |
metadata.namespace | Namespace of the Uplink. | - | Yes |
spec.exposeName | Custom name for the service exposed to parent clusters. Useful for controlling the service name independent of the resource name. | - | No |
spec.entryPoints | List of uplink entry point names this uplink is associated with. If not specified, uses default uplink entry points. | [] | No |
spec.weight | Weight for weighted round-robin load balancing when multiple child clusters advertise the same uplink. Higher weights receive proportionally more traffic. Must be >=0. | 1 | No |
spec.healthCheck | Active health check configuration for the parent cluster's load balancer. See Health Check Configuration for details. | - | No |
Uplink Naming
The Uplink name is used to:
- Reference from routers: IngressRoutes reference uplinks using the
hub.traefik.io/router.uplinksannotation - Create parent services: The parent cluster creates services using the uplink name
By default, Kubernetes Uplinks are named using the pattern <namespace>-<name>. You can override this with the spec.exposeName field.
When the uplink is registered with the parent cluster, the service name follows the pattern:
<uplink-name>@multicluster- Weighted round-robin across all children advertising this uplink<uplink-name>-<child-name>@multicluster- Direct access to a specific child
For example, an Uplink named api-workload in namespace apps creates:
apps-api-workload@multicluster- WRR serviceapps-api-workload-child-1@multicluster- Per-child service (wherechild-1is the child name from parent config)
Referencing Uplinks from Routers
IngressRoutes reference uplinks using the hub.traefik.io/router.uplinks annotation. The annotation value is a comma-separated list of fully-qualified uplink names (including namespace prefix).
When a router references an uplink:
- The router is advertised to parent clusters through the uplink
- The router must not specify
entryPoints(entry points come from the uplink) - The router must not specify
tlsconfiguration (TLS is handled by the uplink entry point)
- IngressRoute with Uplink
- Multiple Uplinks
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-route
namespace: apps
annotations:
# Reference the uplink using <namespace>-<name> format
hub.traefik.io/router.uplinks: "apps-api-workload"
spec:
# Note: No entryPoints - inherited from the uplink
routes:
- match: PathPrefix(`/api`)
kind: Rule
services:
- name: api-backend
port: 8080
middlewares:
- name: rate-limit
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-route
namespace: apps
annotations:
# Multiple uplinks separated by commas
hub.traefik.io/router.uplinks: "apps-primary-uplink,apps-secondary-uplink"
spec:
routes:
- match: PathPrefix(`/api`)
kind: Rule
services:
- name: api-backend
port: 8080
The following configurations are incorrect and will result in an error:
# Invalid: Router has both entryPoints and uplink annotation
metadata:
annotations:
hub.traefik.io/router.uplinks: "apps-my-uplink"
spec:
entryPoints:
- websecure # Not allowed with uplinks
# Invalid: Router has both TLS and uplink annotation
metadata:
annotations:
hub.traefik.io/router.uplinks: "apps-my-uplink"
spec:
tls: {} # Not allowed with uplinks
Weight Configuration
The weight field controls traffic distribution when multiple child clusters advertise the same uplink:
- Child 1 (Primary)
- Child 2 (Secondary)
- Parent Service (Auto-generated)
# On child cluster 1 - receives 90% of traffic
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
spec:
weight: 90
# On child cluster 2 - receives 10% of traffic
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
spec:
weight: 10
# Auto-generated on parent cluster
services:
apps-api-workload:
weighted:
services:
- name: apps-api-workload-child-1
weight: 90
- name: apps-api-workload-child-2
weight: 10
Health Check Configuration
The healthCheck field enables active health monitoring of child clusters from the parent cluster. When configured, the parent cluster periodically probes the child cluster's uplink endpoint to verify availability.
This enables automatic failover when a child becomes unavailable.
Health Check Fields
| Field | Description | Default | Required |
|---|---|---|---|
path | URL path for the health check endpoint (e.g., /health, /healthz). | - | No |
scheme | HTTP scheme to use for health check requests (http, https). | Uses uplink server scheme | No |
mode | Health check mode. Supported values: http (standard HTTP), grpc (gRPC health check protocol). | http | No |
method | HTTP method for health check requests. | GET | No |
status | Expected HTTP status code indicating a healthy response. | 200 | No |
port | Port for health check requests. | Uses uplink server port | No |
interval | Frequency of health checks for healthy targets (e.g., 10s, 30s). | 30s | No |
unhealthyInterval | Frequency of health checks for unhealthy targets. | Same as interval | No |
timeout | Maximum time to wait for a health check response before marking as unhealthy. | 5s | No |
hostname | Value of the Host header in health check requests. | Uses uplink hostname | No |
followRedirects | Whether to follow HTTP redirects during health checks. | true | No |
headers | Custom headers to include in health check requests. | - | No |
Basic Health Check Example
- HTTP Health Check
- Custom Headers
- gRPC Health Check
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
entryPoints:
- uplink
healthCheck:
path: /health
interval: 10s
timeout: 3s
status: 200
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
healthCheck:
path: /healthz
interval: 15s
timeout: 5s
headers:
X-Health-Check: "true"
Authorization: "Bearer token123"
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: grpc-service
namespace: apps
spec:
healthCheck:
mode: grpc
interval: 10s
timeout: 5s
Health Check Behavior
How It Works:
- Parent-Side Monitoring: Health checks run on the parent cluster's load balancer, probing the child cluster's uplink endpoint
- Automatic Status Updates:
- Healthy targets are checked at the
intervalfrequency (default 30s) - Unhealthy targets are checked at the
unhealthyIntervalfrequency (defaults to same asinterval)
- Healthy targets are checked at the
- Failover Integration:
- When a child fails health checks, it's automatically removed from the load balancing pool
- Traffic is redistributed among remaining healthy children
- When the child recovers, it's automatically re-added to the pool
Health Check with Failover:
# Child Cluster 1 (EU)
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
exposeName: api-workload-eu
healthCheck:
hostname: "api.eu.example.com"
path: /health
interval: 10s
timeout: 3s
status: 200
port: 443
---
# Child Cluster 2 (US)
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: api-workload
namespace: apps
spec:
exposeName: api-workload-us
healthCheck:
hostname: "api.us.example.com"
path: /health
interval: 10s
timeout: 3s
status: 200
port: 443
When EU cluster becomes unavailable, the parent cluster automatically routes all traffic to the US cluster.
Health checks probe the child cluster's uplink endpoint, not the backend service directly. Ensure your uplink endpoint is accessible and responds to health check requests.
Complete Example
This example shows a complete multi-cluster setup with an Uplink:
- Child Cluster - Static Config
- Child Cluster - Uplink
- Child Cluster - IngressRoute
- Parent Cluster - Static Config
- Parent Cluster - Router
# traefik.yaml (child cluster)
hub:
uplinkEntryPoints:
multicluster:
address: ":9443"
asDefault: true
http:
tls: {}
providers:
multicluster: {} # Enable multicluster on child to expose API
# uplink.yaml
apiVersion: hub.traefik.io/v1alpha1
kind: Uplink
metadata:
name: banking-api
namespace: banking
spec:
weight: 10
# ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: banking-route
namespace: banking
annotations:
hub.traefik.io/router.uplinks: "banking-banking-api"
spec:
routes:
- match: PathPrefix(`/accounts`) || PathPrefix(`/transactions`)
kind: Rule
services:
- name: banking-service
port: 8080
middlewares:
- name: rate-limit
- name: circuit-breaker
# traefik.yaml (parent cluster)
hub:
providers:
multicluster:
children:
child-1:
address: "https://child1.example.com:9443"
child-2:
address: "https://child2.example.com:9443"
# ingressroute.yaml (parent cluster)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: banking-parent
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.example.com`) && PathPrefix(`/banking`)
kind: Rule
services:
# Route to the auto-generated WRR service
- name: banking-banking-api@multicluster
kind: TraefikService
middlewares:
- name: strip-banking-prefix
tls: {}
Related Content
- Multi-Cluster Provider: Configure the parent cluster
- Uplink Entry Points: Configure entry points for inter-cluster communication
- IngressRoute: Define routers that reference uplinks
- Multi-Layer Routing: Hierarchical routing patterns
