ServiceLB DaemonSet keeps stale nodeSelector after the enablelb label is removed
Environmental Info: K3s Version: v1.36.4+k3s1
Cluster Configuration: 1 server
Describe the bug:
When you use the svccontroller.k3s.cattle.io/enablelb label to restrict
ServiceLB to specific nodes, and then later remove that label from the last
labeled node, the svclb DaemonSet keeps its nodeSelector. It never goes back
to running on all nodes the way it does by default, so the LoadBalancer can
end up with no pods.
Steps To Reproduce:
- Installed K3s:
curl -sfL https://get.k3s.io | sh - - Create a LoadBalancer service (or use an existing one).
- Confirm the svclb DaemonSet has no nodeSelector:
kubectl -n kube-system get ds -o custom-columns=NAME:.metadata.name,SEL:.spec.template.spec.nodeSelector - Label the node:
kubectl label node NODENAME svccontroller.k3s.cattle.io/enablelb=true→ the DaemonSet gets nodeSelectorsvccontroller.k3s.cattle.io/enablelb=true - Remove the label:
kubectl label node NODENAME svccontroller.k3s.cattle.io/enablelb-
Expected behavior: With no node carrying the enablelb label, ServiceLB returns to its default of running on all nodes — the DaemonSet nodeSelector is cleared.
Actual behavior:
The DaemonSet keeps nodeSelector svccontroller.k3s.cattle.io/enablelb=true.
It stays that way indefinitely, and a full k3s restart does not clear it.
Additional context / logs:
Looks like onChangeNode in pkg/cloudprovider/servicelb.go returns early when
the changed node doesn't have the enablelb label, so updateDaemonSets() never
runs on the removal. Possibly the same underlying issue as k3s-io/klipper-lb#73.
Source: k3s-io/k3s