What happened:
#9937 introduced a bug where load balancer rules and probes are not properly cleaned up or service migration is incorrectly blocked during service external/internal transitions.
-
Secondary service transitions
- Two Services share the same frontend IP.
- Change the secondary Service to internal.
- LB rules and probes are not cleaned up.
-
Secondary service + LB config change
- Two Services share the same frontend IP.
- Change the secondary Service to internal and annotate it to a different LB.
- LB rules and probes are not cleaned up.
-
Primary service external → internal → external
- Two Services share an IP on lb-1.
- Change the primary Service to internal (lb-1-internal).
- Change it back to external and remove LB config annotation.
- Reconciliation is blocked with error (cannot migrate from load balancer "lb-1" to "lb-2").
- At this point, the controller loses the original LB hint, picks a sibling LB (lb-2) with fewer rules, incorrectly blocks reuse of the existing shared IP.
-
Primary service external → internal + target lb-2 → external
- Two Services share an IP on lb-1.
- Change the primary Service to internal and annotate it to lb-2-internal.
- Change it back to external and remove LB config annotation.
- Reconciliation is blocked with error
What you expected to happen:
Load balancer rules and probes should be cleaned up correctly when a Service transitions from external ↔ internal, regardless of whether it is the primary or secondary Service sharing the IP.
External ↔ internal transitions should not block reuse of an existing shared frontend IP.
Behavior should be consistent with the non-multi-SLB case, where the existing IP is reused.
How to reproduce it (as minimally and precisely as possible):
- Enable multi-SLB with at least two eligible LB configs, for example lb-1 and lb-2.
- Create 2 external type: LoadBalancer services sharing the same frontend IP that lands on lb-1.
- Test the following internal transitions by setting service.beta.kubernetes.io/azure-load-balancer-internal: "true":
- Change the secondary service to internal and remove the IP pin.
- Change the secondary service to internal, remove the IP pin, and annotate it to lb-2.
- Change the primary service from external → internal → external.
- Change the primary service from external → internal and annotate it to lb-2 → external and remove lb annotation.
- Observe:
- Orphaned LB rules / probes.
- Blocked reconciliation due to perceived LB migration despite reuse of the same IP.
Anything else we need to know?:
This is a follow-up bug introduced by #9937 to fix #9867
Likely overlaps in root cause with #10050
Environment:
- Kubernetes version (use
kubectl version):
- Cloud provider or hardware configuration:
- OS (e.g:
cat /etc/os-release):
- Kernel (e.g.
uname -a):
- Install tools:
- Network plugin and version (if this is a network-related bug):
- Others:
What happened:
#9937 introduced a bug where load balancer rules and probes are not properly cleaned up or service migration is incorrectly blocked during service external/internal transitions.
Secondary service transitions
Secondary service + LB config change
Primary service external → internal → external
Primary service external → internal + target lb-2 → external
What you expected to happen:
Load balancer rules and probes should be cleaned up correctly when a Service transitions from external ↔ internal, regardless of whether it is the primary or secondary Service sharing the IP.
External ↔ internal transitions should not block reuse of an existing shared frontend IP.
Behavior should be consistent with the non-multi-SLB case, where the existing IP is reused.
How to reproduce it (as minimally and precisely as possible):
Anything else we need to know?:
This is a follow-up bug introduced by #9937 to fix #9867
Likely overlaps in root cause with #10050
Environment:
kubectl version):cat /etc/os-release):uname -a):