#4142·vcluster

EndpointSlice sync does not translate kubernetes.io/service-name for custom-managed EndpointSlices

Author: pasztorlCreated Aug 11, 2026Updated Aug 11, 2026
Labelskind/bug

What happened?

With vCluster 0.33.1, some EndpointSlices synced from the virtual cluster to the host cluster keep the virtual Service name in the kubernetes.io/service-name label instead of using the translated host-side Service name.

This causes the synced EndpointSlice to no longer be associated with its corresponding host-side Service.

The issue was initially detected with MariaDB Operator *-secondary Services.

For example, inside the virtual cluster the Service is:

Namespace: example-prod
Service:   example-db-secondary

vCluster correctly translates the Service on the host cluster to:

Namespace: example
Service:   example-db-secondary-x-example-prod-x-vcluster
ClusterIP: 10.15.108.114

The corresponding EndpointSlice is also synced to the host with the translated resource name:

example-db-secondary-x-example-prod-x-vcluster

However, the EndpointSlice contains:

kubernetes.io/service-name=example-db-secondary

instead of:

kubernetes.io/service-name=example-db-secondary-x-example-prod-x-vcluster

Example host-side EndpointSlice:

Name:         example-db-secondary-x-example-prod-x-vcluster
Namespace:    example

Labels:
  endpointslice.kubernetes.io/managed-by=mariadb-operator.k8s.mariadb.com
  kubernetes.io/service-name=example-db-secondary
  vcluster.loft.sh/managed-by=vcluster
  vcluster.loft.sh/namespace=example-prod

Annotations:
  vcluster.loft.sh/object-host-name: example-db-secondary-x-example-prod-x-vcluster
  vcluster.loft.sh/object-host-namespace: example
  vcluster.loft.sh/object-kind: discovery.k8s.io/v1, Kind=EndpointSlice
  vcluster.loft.sh/object-name: example-db-secondary
  vcluster.loft.sh/object-namespace: example-prod

AddressType: IPv4

Ports:
  mariadb  3306/TCP

Endpoints:
  10.15.104.41  Ready=true  Pod/example-db-1-x-example-prod-x-vcluster
  10.15.107.9   Ready=true  Pod/example-db-0-x-example-prod-x-vcluster

Notice that other references, including the EndpointSlice name and Pod targetRefs, are translated correctly. Only the kubernetes.io/service-name label remains the virtual Service name.

Because of this:

bash
kubectl -n example get endpointslice \
  -l kubernetes.io/service-name=example-db-secondary-x-example-prod-x-vcluster

returns no EndpointSlices.

Impact

The host cluster uses Cilium with kube-proxy replacement.

Because Cilium cannot associate the EndpointSlice with the translated host Service, the ClusterIP is not installed in the Cilium service/LB maps.

For example:

bash
cilium-dbg service list | grep 10.15.108.114

returned nothing on freshly started Cilium agents.

Direct connectivity to both endpoint Pod IPs worked, so the backend networking itself was healthy.

After manually fixing the EndpointSlice label:

bash
kubectl -n example label endpointslice \
  example-db-secondary-x-example-prod-x-vcluster \
  kubernetes.io/service-name=example-db-secondary-x-example-prod-x-vcluster \
  --overwrite

Cilium immediately created the Service on multiple nodes without any restart:

10.15.108.114:3306/TCP  ClusterIP
    1 => 10.15.104.41:3306/TCP (active)
    2 => 10.15.107.9:3306/TCP (active)

This demonstrates that the only required change was correcting the kubernetes.io/service-name label.

The inspected broken EndpointSlice is managed by:

endpointslice.kubernetes.io/managed-by=mariadb-operator.k8s.mariadb.com

This suggests the problem may specifically affect EndpointSlices created by an external/custom controller rather than EndpointSlices generated by Kubernetes' normal Service EndpointSlice controller.

What did you expect to happen?

When vCluster translates a Service from:

example-prod/example-db-secondary

to:

example/example-db-secondary-x-example-prod-x-vcluster

the corresponding EndpointSlice should also be translated from:

yaml
metadata:
  labels:
    kubernetes.io/service-name: example-db-secondary

to:

yaml
metadata:
  labels:
    kubernetes.io/service-name: example-db-secondary-x-example-prod-x-vcluster

The label should reference the actual translated Service name in the host cluster.

How can we reproduce it (as minimally and precisely as possible)?

  1. Install vCluster 0.33.1.

  2. Enable Service and EndpointSlice syncing:

yaml
sync:
  toHost:
    endpointSlices:
      enabled: true
    endpoints:
      enabled: true
    services:
      enabled: true
  1. Inside the vCluster, create/use a controller that manages an EndpointSlice directly. In our case this is MariaDB Operator and its secondary Service.

Example virtual Service:

example-prod/example-db-secondary
  1. Check the translated Service on the host:
bash
kubectl -n example get svc \
  example-db-secondary-x-example-prod-x-vcluster
  1. Check the translated EndpointSlice:
bash
kubectl -n example describe endpointslice \
  example-db-secondary-x-example-prod-x-vcluster
  1. Observe that the resource name is translated but the Service reference is not:
EndpointSlice name:
  example-db-secondary-x-example-prod-x-vcluster

kubernetes.io/service-name:
  example-db-secondary
  1. Manually change the label to the translated Service name:
bash
kubectl -n example label endpointslice \
  example-db-secondary-x-example-prod-x-vcluster \
  kubernetes.io/service-name=example-db-secondary-x-example-prod-x-vcluster \
  --overwrite

The EndpointSlice is then correctly associated with the host Service and downstream Service consumers immediately see the correct backends.

Anything else we need to know?

https://github.com/mariadb-operator/mariadb-operator

MariaDB operator version: 25.10.2

Host cluster Kubernetes version

bash
$ kubectl version
Client Version: v1.33.7
Kustomize Version: v5.6.0
Server Version: v1.33.7

vcluster version

Installed with helm, running 0.33.1.

VCluster Config

sync:
  toHost:
    endpointSlices:
      enabled: true
    endpoints:
      enabled: true
    services:
      enabled: true

    namespaces:
      enabled: false
      mappingsOnly: false