Repository navigation
Some IPs in the pool for MetalLB are not available when creating svc LoadBalancer in a tenant cluster #1563
Description
Activity
- addedkind/bugCategorizes issue or PR as related to a bugCategorizes issue or PR as related to a bug
on Oct 31, 2025 This issue is likely related to how endpoints are propagated from tenant clusters to the root cluster, especially for IPs that were previously used in older CozyStack versions. There's a known bug where a panic in the kubevirt cloud controller manager prevents endpoints from being correctly created in the root cluster, which causes MetalLB to report "no active endpoints" and not announce the IP externally—even though everything works inside the tenant cluster. This matches your symptoms and has been discussed in detail here.
To troubleshoot, check for errors or panics in the kubevirt cloud controller manager logs in the root cluster. If you see signs of a crash or nil pointer dereference, this is almost certainly the cause. The fix for this was prepared upstream and merged into CozyStack (PR link), so make sure your environment includes this patch.
If you suspect stale resources, you can manually check for leftover endpoints, NodePorts, or IP allocations in both clusters. Use
kubectl get endpoints -Aandkubectl get svc -Ain both root and tenant clusters to look for services with missing endpoints or NodePorts. If you find any, try deleting and recreating the affected LoadBalancer service to force a fresh allocation and endpoint mapping.Also, confirm that your MetalLB IP pool only contains unused IPs and that routing is correct for all IPs in the pool (docs). Sometimes, previously used IPs may be blocked by lingering resources or misconfigured routes.
If the issue persists after cleanup and patching, review the events and logs for MetalLB and kubevirt controllers for clues about resource propagation failures.
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
- changed the title
[-]Some IPs in the pool for MetalLB are not available when creating svc LoadBalancer in a tenant cluster[/-][+]Some IPs in the pool for MetalLB are not available when creating svc `LoadBalancer` in a tenant cluster[/+]on Oct 31, 2025 Thanks to the bot, I checked the KCCM log and found a multiple svc error. However, I don't have multiple svc, so these are probably old entries in etcd.
# kc logs kubernetes-qwerty-xxx-xxx-xxx-1-kccm-644dcdbdc5-p9gfm -n tenant-qwerty I1031 16:09:10.967274 1 event.go:307] "Event occurred" object="default/lb-test1" fieldPath="" kind="Service" apiVersion="v1" type="Normal" reason="EnsuringLoadBalancer" message="Ensuring load balancer" I1031 16:09:10.986155 1 kubevirteps_controller.go:117] Service added: tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:10.986209 1 kubevirteps_controller.go:419] Reconciling: ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:10.986234 1 kubevirteps_controller.go:376] Searching for EndpointSlices in infra cluster for service tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:10.988637 1 kubevirteps_controller.go:357] Searching for endpoints on tenant cluster kubernetes-qwerty-xxx-xxx-xxx-1 for service lb-test1 in namespace default. I1031 16:09:10.990292 1 kubevirteps_controller.go:124] Service updated: tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:10.992723 1 kubevirteps_controller_utils.go:62] Adding EndpointSlice lb-test1-nxzlk to the tenantEPSTracker I1031 16:09:10.992758 1 kubevirteps_controller.go:802] Desired nodes for service tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927: [] I1031 16:09:10.992794 1 kubevirteps_controller.go:419] Reconciling: ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:10.992817 1 kubevirteps_controller.go:376] Searching for EndpointSlices in infra cluster for service tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:11.008071 1 kubevirteps_controller.go:124] Service updated: tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:11.089502 1 kubevirteps_controller.go:357] Searching for endpoints on tenant cluster kubernetes-qwerty-xxx-xxx-xxx-1 for service lb-test1 in namespace default. I1031 16:09:11.095813 1 kubevirteps_controller_utils.go:62] Adding EndpointSlice lb-test1-nxzlk to the tenantEPSTracker I1031 16:09:11.095850 1 kubevirteps_controller.go:802] Desired nodes for service tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927: [] I1031 16:09:11.095888 1 kubevirteps_controller.go:419] Reconciling: ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:11.095912 1 kubevirteps_controller.go:376] Searching for EndpointSlices in infra cluster for service tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927 I1031 16:09:11.098119 1 kubevirteps_controller.go:357] Searching for endpoints on tenant cluster kubernetes-qwerty-xxx-xxx-xxx-1 for service lb-test1 in namespace default. I1031 16:09:11.102150 1 kubevirteps_controller_utils.go:62] Adding EndpointSlice lb-test1-nxzlk to the tenantEPSTracker I1031 16:09:11.102182 1 kubevirteps_controller.go:802] Desired nodes for service tenant-qwerty/ab0bfc6fcc5734eeca75375a0a996927: [] I1031 16:09:13.165503 1 kubevirteps_controller.go:159] get Infra Service for Tenant EndpointSlice: default/lb-test1-nxzlk E1031 16:09:13.168818 1 kubevirteps_controller.go:342] Multiple services found for tenant endpoint slice lb-test1-nxzlk in namespace default E1031 16:09:13.168848 1 kubevirteps_controller.go:163] Failed to get Service in Infra cluster for EndpointSlice default/lb-test1-nxzlk: multiple services found for tenant endpoint slice I1031 16:09:15.988253 1 event.go:307] "Event occurred" object="default/lb-test1" fieldPath="" kind="Service" apiVersion="v1" type="Normal" reason="EnsuredLoadBalancer" message="Ensured load balancer"The "multiple services found for tenant endpoint slice" error in the CCM logs happens when the controller detects more than one Service resource associated with the same EndpointSlice in the infra cluster. This usually means there are stale or orphaned Service entries lingering in etcd or the infra cluster—often from previous CozyStack versions or failed deletions—even if they're not visible with standard kubectl commands. These hidden resources can block correct endpoint mapping and break MetalLB LoadBalancer provisioning, especially for IPs reused from older clusters or services.
There isn't a built-in automated cleanup for this in CozyStack. The recommended approach is to manually identify and remove any leftover Service or EndpointSlice resources in the infra cluster's etcd. You can try:
- Listing all Services and EndpointSlices in the affected namespace with
kubectl get svc -Aandkubectl get endpointslices -Ain both tenant and infra clusters. - If you suspect hidden resources, you may need to use
etcdctldirectly on the infra cluster's etcd to search for and remove orphaned Service or EndpointSlice keys. - Deleting and recreating the affected LoadBalancer Service in the tenant cluster can sometimes force a fresh mapping and clear the error.
This issue is more likely to occur with IPs that were previously allocated, so cleaning up these stale resources should resolve the mapping conflict and restore MetalLB functionality. For more background, see the discussion and upstream fix here: cozystack/cozystack#1017.
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
- Listing all Services and EndpointSlices in the affected namespace with
# (@dosu) How can I determine that endpointslice has multiple svc?
The CCM error "multiple services found for tenant endpoint slice" means the controller found more than one Service resource associated with a single EndpointSlice—usually due to stale or orphaned resources in etcd that aren't visible with normal kubectl commands.
To check for this:
-
List all EndpointSlices and Services in the affected namespace with:
kubectl get endpointslices -n <namespace> kubectl get svc -n <namespace> -
For a specific EndpointSlice (e.g.,
lb-test1-nxzlk), inspect its labels and ownerReferences:kubectl get endpointslice lb-test1-nxzlk -n <namespace> -o yamlLook for labels like
kubernetes.io/service-nameor ownerReferences pointing to a Service. -
List all Services and check if more than one has a matching label or selector for that EndpointSlice. For example:
kubectl get svc -n <namespace> -o yaml | grep lb-test1If you see more than one Service referencing the same EndpointSlice, that's the conflict.
If you suspect hidden resources, you may need to use
etcdctlon the infra cluster to search for duplicate Service or EndpointSlice keys. The CCM log itself is a strong indicator—if you see this error, there are definitely multiple Service objects (even if not visible via kubectl) associated with the EndpointSlice in etcd or the infra cluster. Cleaning up these stale resources should resolve the issue.For more context, see the discussion in cozystack/cozystack#1017.
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
-
# (@dosu) how to find duplicates through etcdctl
To find duplicate or orphaned Service and EndpointSlice resources in etcd using etcdctl (v3), first make sure you have access to the etcd cluster and a backup before making changes.
Kubernetes stores Services under /registry/services/ and EndpointSlices under /registry/endpointslices/. You can list all keys with:
etcdctl get /registry/services/ --prefix --keys-only etcdctl get /registry/endpointslices/ --prefix --keys-only
To inspect a specific resource, use:
etcdctl get <key>
For example, to see all EndpointSlices for a namespace (e.g., default):
etcdctl get /registry/endpointslices/default/ --prefix --keys-only
Look for multiple keys with similar names or the same service name/namespace. To check if multiple Service objects exist for the same logical service, compare the key suffixes and inspect their values for metadata like
metadata.nameandmetadata.namespace.To match EndpointSlices to Services, inspect the EndpointSlice value and look for labels like
kubernetes.io/service-nameor ownerReferences. If you find more than one Service object referencing the same EndpointSlice, or multiple EndpointSlices with the same service label, that's a sign of duplication or stale resources.If you confirm a duplicate or orphaned entry, you can remove it with:
etcdctl del <key>
Be careful—deleting the wrong key can break your cluster. Always back up etcd first.
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other
i think i'm getting same issue. Any improvement?
I got around the problem using
exposeType: Proxied. I also simply recreated the cluster differently, with a new name. I haven't had time yet to figure out how to connect to the root etcd. However, creating a separate etcd for each tenant might also be a good idea.I think I understand what the problem was. We use external-dns to register the ingress URL in DNS. It seems that because txtOwnerID was the same on different tenant clusters, MetalLB couldn't determine the active endpoint.
Alekperov Fuad (@fuad00) If your problem has been resolved, may I close the thread?
Reacted by Alekperov Fuadsolved!
Describe the bug
Some IPs in the pool for MetalLB are not available when creating svc
LoadBalancerin a tenant cluster:Example:
These IPs have already been used in previous versions of CozyStack. If I create multiple LBs, and the pool will issue IPs that have not been used before, then everything is fine.
Debugging shows that metallb complains that there are no Endpoints, although there are EPs inside the tenant cluster, and if I do port forwarding to svc LB inside tenant cluster, everything works:
IPs that are successfully announced have an endpoint. This endpoint is the IP address of virt-launcher pod in the root cluster, i.e., the node of the tenant k8s. And the NodePort is the external port of that root k8s node where virt-launcher is located. This NodePort is open externally if you try to connect to it on the IP node of root k8s.
Also, metallb-controller and metalb-speaker respond, and there are entries in Events.
The external node port of the problematic svc is unavailable, and the speakers have no records:
And in the logs, there is a message saying that there are no endpoints.
Please tell me what else I can check?
Environment