EndpointSlice sync does not translate kubernetes.io/service-name for custom-managed EndpointSlices · Issue #4142 · loft-sh/vcluster · GitHub
Skip to content

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

Open

Description

@pasztorl

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:

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:

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:

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:

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

to:

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:

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:
kubectl -n example get svc \
  example-db-secondary-x-example-prod-x-vcluster
  1. Check the translated EndpointSlice:
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:
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

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

vcluster version

Details

Installed with helm, running 0.33.1.

VCluster Config

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

    namespaces:
      enabled: false
      mappingsOnly: false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions