Gateway classes
By default, this is disabled.
GatewayClass syncing lets tenant clusters use Gateway API controllers that run on the control plane cluster. Normally, each tenant cluster would need its own Gateway controller to program traffic. With GatewayClass syncing enabled, tenants reference host-controller GatewayClass resources by name instead.
Add labels to GatewayClass resources in the control plane cluster and configure vCluster to sync only those that match a label selector. When a tenant creates a Gateway that references a synced GatewayClass, the control plane cluster's Gateway controller handles the data plane.
This saves resources because you don't need a Gateway controller in every tenant cluster, and it gives you centralized control over which controllers and listener capabilities tenants can use.
Common use cases:
- Development environments: Sync only the
GatewayClassresources required for development tenants to reduce noise and avoid unnecessary exposure. - Tenant isolation: Let teams use their own
GatewayClassresources while sharing a single control plane cluster. - Security: Restrict which
GatewayClassresources are available in each tenant cluster to enforce access control and prevent unintended configurations.
Enable syncing​
When enabled, vCluster takes control of all GatewayClass resources in the tenant cluster. It only allows GatewayClass resources that are synced from the control plane cluster to exist.
This example configuration enables syncing all GatewayClass resources from the control plane cluster to the tenant cluster:
sync:
fromHost:
gatewayClasses:
enabled: true
If you try to create the GatewayClass resource directly in the tenant cluster, using for example kubectl create or kubectl apply, vCluster detects it and deletes it immediately. This prevents conflicts between locally created GatewayClass resources and those synced from the control plane cluster, ensuring that only GatewayClass resources from the control plane cluster exist in the tenant cluster.
When enabled, GatewayClass resource creation can only occur in the control plane cluster. Any GatewayClass resources created in the tenant cluster will be deleted.
How syncing works​
When GatewayClass syncing is enabled, vCluster can use a label selector to control which GatewayClass and Gateway resources are synchronized between the control plane and tenant clusters. This affects the resource types with separate unidirectional sync flows:
-
GatewayClass resources (control plane → tenant): vCluster syncs GatewayClass resources from the control plane cluster to the tenant cluster. You cannot create GatewayClass resources directly in the tenant cluster. If a selector is defined, only GatewayClass resources matching the selector will sync. If no selector is defined, all GatewayClass resources are synced.
-
Gateway resources (tenant → control plane): vCluster syncs Gateway resources from the tenant cluster to the control plane cluster only if any of the following is true:
- No selector is defined for GatewayClass syncing, which allows all Gateway resources to sync regardless of the
gatewayClassName. - The Gateway's
gatewayClassNamereferences a GatewayClass resource that matches the selector and is synced from the control plane cluster. - The Gateway has an empty
gatewayClassNamefield.
- No selector is defined for GatewayClass syncing, which allows all Gateway resources to sync regardless of the
The same selector controls both sync flows. The selector determines which GatewayClass resources are imported from the control plane cluster and which Gateway resources can sync to the control plane cluster based on the referenced GatewayClass resource.
Use selectors to filter​
Selectors provide precise control over which GatewayClass resources get synced from the control plane cluster and which Gateway resources gets synced to the control plane cluster. vCluster supports two types of selector criteria that follow standard Kubernetes label selector syntax.
Filter with matchLabels​
The matchLabels selector defines exact label key-value pairs that must be present on an GatewayClass for it to be synced. This provides straightforward filtering based on specific labels.
The following example syncs only GatewayClass resources with a environment: development label:
sync:
toHost:
gateways:
enabled: true
fromHost:
gatewayClasses:
enabled: true
selector:
matchLabels:
environment: development
Filter with matchExpressions​
The matchExpressions selector allows more flexible, set-based filtering with support for multiple operators:
In: Select all resources that has a specific key and the value is in the set of valuesNotIn: Select all resources that has a specific key and the value is not in the set of valuesExists: Select all resources including a label with the key; no values are checkedDoesNotExist: Select all resources without a label with the key; no values are checked
The following example syncs GatewayClass resources where the key of the label is gateway-demo.loft.sh/sync and the value of that label is either yes or no:
sync:
toHost:
gateways:
enabled: true
fromHost:
gatewayClasses:
enabled: true
selector:
matchExpressions:
- key: gateway-demo.loft.sh/sync
operator: In
values:
- yes
- no
Combined filter criteria​
Label conditions are additive meaning all specified label conditions must match for the GatewayClass resource to be selected to be synced. This means that if you define multiple matchLabels and matchExpressions, the GatewayClass resource must satisfy all criteria to be synced to the tenant cluster.
The following example syncs GatewayClass resources that match both label and expression criteria:
sync:
toHost:
gateways:
enabled: true
fromHost:
gatewayClasses:
enabled: true
selector:
matchLabels:
environment: development
matchExpressions:
- key: gateway-demo.loft.sh/sync
operator: In
values:
- yes
- no
In this example, the GatewayClass must have the following labels to sync to the tenant cluster:
environment: development- Either
gateway-demo.loft.sh/sync:yesorgateway-demo.loft.sh/sync:no
Sync behavior considerations​
Resource lifecycle​
Synced GatewayClass resources function like any other Kubernetes resource in the tenant cluster. You
can view them with kubectl get gatewayclass and reference them in your Gateway resource
specifications with the gatewayClassName field.
When you modify the GatewayClass resource in the control plane cluster, vCluster re-evaluates whether it still matches the selector criteria. If the GatewayClass continues to match, vCluster updates the corresponding resource in the tenant cluster to reflect the changes. If the GatewayClass no longer matches the selector criteria, vCluster removes it from the tenant cluster.
The selector system acts as both a resource filter and a validation mechanism. As a resource filter, it ensures that vCluster creates only GatewayClass resources matching the defined selector criteria. The selector also functions as a creation validation mechanism - when you create Gateway resources in the tenant cluster, the resources can only reference GatewayClass resources that exist in the tenant cluster.
Orphaned resources​
When vCluster removes a synced GatewayClass from the tenant cluster due to selector changes or deletion from the control plane cluster, any Gateway resources that reference it remain in the tenant and control plane clusters. These orphaned Gateway resources stop receiving updates but vCluster does not automatically delete them to prevent unintended data loss. To remove these orphaned resources, you must delete them manually in the tenant and control plane clusters. This manual approach ensures that you maintain full control over resource cleanup and can verify that deletions are intentional.
Error handling and troubleshooting​
When the GatewayClass resource doesn't match the selector criteria during evaluation, vCluster logs a warning in the syncer pod's output to help with troubleshooting and monitoring. This logging provides visibility into which resources are being filtered out and why.
When you creates the Gateway resource that references a GatewayClass not matching the selector criteria, several things occur to provide clear feedback:
- The Gateway fails to sync to the control plane cluster
- vCluster records an event on the Gateway resource in the tenant cluster
- The event indicates that the specified GatewayClass is not available according to the current selector configuration
The error output appears as a Kubernetes event that you can view using kubectl describe. The event message clearly states that the Gateway resource was not synced because the referenced GatewayClass does not match the defined selector criteria.
The error output looks like this:
vcluster-virtual-cluster-1:~$ kubectl describe gateway my-gateway
Name: my-gateway
Namespace: default
GatewayClass: no
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning SyncWarning 10s gateway-syncer did not sync gateway "my-gateway" to host because it does not match the selector under 'sync.fromHost.gatewayClasses.selector'
Example: select specific GatewayClass resources by label​
In the control plane cluster, label the GatewayClass resources you want exposed:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: gw-demo-11-allowed
labels:
gateway-demo.loft.sh/sync: "yes"
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
Then point vCluster at that label in vcluster.yaml:
sync:
fromHost:
gatewayClasses:
enabled: true
selector:
matchLabels:
gateway-demo.loft.sh/sync: "yes"
GatewayClass resources without the matching label remain only in the control plane cluster. If a tenant creates a Gateway that references an unsynced class, vCluster records a SyncWarning event on the tenant Gateway:
Warning SyncWarning Gateway "filtered-edge" sync skipped. The GatewayClass "gw-demo-11-filtered" does not match the selector under 'sync.fromHost.gatewayClasses.selector'
Inspect with:
kubectl get gatewayclass
kubectl describe gateway <name> -n <ns>
kubectl get events --field-selector type=Warning
Config reference​
gatewayClasses required object ​
GatewayClasses defines if gateway classes should get synced from the host cluster to the virtual cluster, but not back. When enabled, host GatewayClasses are the source of truth and virtual-only GatewayClasses are deleted.
gatewayClasses required object ​enabled required boolean false ​
Enabled defines if this option should be enabled.
enabled required boolean false ​patches required object[] ​
Patches patch the resource according to the provided specification.
patches required object[] ​path required string ​
Path is the path within the patch to target. If the path is not found within the patch, the patch is not applied.
path required string ​expression required string ​
Expression transforms the value according to the given JavaScript expression.
expression required string ​reverseExpression required string ​
ReverseExpression transforms the value according to the given JavaScript expression.
reverseExpression required string ​reference required object ​
Reference treats the path value as a reference to another object and will rewrite it based on the chosen mode
automatically. In single-namespace mode this will translate the name to "vxxxxxxxxx" to avoid conflicts with
other names, in multi-namespace mode this will not translate the name.
reference required object ​apiVersion required string ​
APIVersion is the apiVersion of the referenced object.
apiVersion required string ​apiVersionPath required string ​
APIVersionPath is optional relative path to use to determine the kind. If APIVersionPath is not found, will fallback to apiVersion.
apiVersionPath required string ​kind required string ​
Kind is the kind of the referenced object.
kind required string ​kindPath required string ​
KindPath is the optional relative path to use to determine the kind. If KindPath is not found, will fallback to kind.
kindPath required string ​namePath required string ​
NamePath is the optional relative path to the reference name within the object.
namePath required string ​namespacePath required string ​
NamespacePath is the optional relative path to the reference namespace within the object. If omitted or not found, namespacePath equals to the
metadata.namespace path of the object.
namespacePath required string ​labels required object ​
Labels treats the path value as a labels selector.
labels required object ​