Skip to content

Commit 7478cf2

Browse files
Merge pull request #1190 from ricky-rav/dev_2040715_nodestatus
Bug 2040715: UPSTREAM: 108284: fix: exclude non-ready nodes from azure load balancer
2 parents fe7796f + a59fd94 commit 7478cf2

File tree

2 files changed

+82
-17
lines changed

2 files changed

+82
-17
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/azure.go

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ func (az *Cloud) updateNodeCaches(prevNode, newNode *v1.Node) {
793793
}
794794
}
795795

796-
//Remove from nodeZones cache if using depreciated LabelFailureDomainBetaZone
796+
// Remove from nodeZones cache if using deprecated LabelFailureDomainBetaZone
797797
prevZoneFailureDomain, ok := prevNode.ObjectMeta.Labels[v1.LabelFailureDomainBetaZone]
798798
if ok && az.isAvailabilityZone(prevZoneFailureDomain) {
799799
az.nodeZones[prevZone].Delete(prevNode.ObjectMeta.Name)
@@ -808,16 +808,17 @@ func (az *Cloud) updateNodeCaches(prevNode, newNode *v1.Node) {
808808
delete(az.nodeResourceGroups, prevNode.ObjectMeta.Name)
809809
}
810810

811-
// Remove from unmanagedNodes cache.
812811
managed, ok := prevNode.ObjectMeta.Labels[managedByAzureLabel]
813-
if ok && managed == "false" {
812+
isNodeManagedByCloudProvider := !ok || managed != "false"
813+
814+
// Remove unmanagedNodes cache
815+
if !isNodeManagedByCloudProvider {
814816
az.unmanagedNodes.Delete(prevNode.ObjectMeta.Name)
815-
az.excludeLoadBalancerNodes.Delete(prevNode.ObjectMeta.Name)
816817
}
817818

818-
// Remove from excludeLoadBalancerNodes cache.
819-
if _, hasExcludeBalancerLabel := prevNode.ObjectMeta.Labels[v1.LabelNodeExcludeBalancers]; hasExcludeBalancerLabel {
820-
az.excludeLoadBalancerNodes.Delete(prevNode.ObjectMeta.Name)
819+
if newNode == nil {
820+
// the node is being deleted from the cluster, exclude it from load balancers
821+
az.excludeLoadBalancerNodes.Insert(prevNode.ObjectMeta.Name)
821822
}
822823
}
823824

@@ -840,16 +841,26 @@ func (az *Cloud) updateNodeCaches(prevNode, newNode *v1.Node) {
840841
az.nodeResourceGroups[newNode.ObjectMeta.Name] = strings.ToLower(newRG)
841842
}
842843

843-
// Add to unmanagedNodes cache.
844+
_, hasExcludeBalancerLabel := newNode.ObjectMeta.Labels[v1.LabelNodeExcludeBalancers]
844845
managed, ok := newNode.ObjectMeta.Labels[managedByAzureLabel]
845-
if ok && managed == "false" {
846+
isNodeManagedByCloudProvider := !ok || managed != "false"
847+
848+
// update unmanagedNodes cache
849+
if !isNodeManagedByCloudProvider {
846850
az.unmanagedNodes.Insert(newNode.ObjectMeta.Name)
847-
az.excludeLoadBalancerNodes.Insert(newNode.ObjectMeta.Name)
848851
}
849-
850-
// Add to excludeLoadBalancerNodes cache.
851-
if _, hasExcludeBalancerLabel := newNode.ObjectMeta.Labels[v1.LabelNodeExcludeBalancers]; hasExcludeBalancerLabel {
852+
// update excludeLoadBalancerNodes cache
853+
switch {
854+
case !isNodeManagedByCloudProvider:
855+
az.excludeLoadBalancerNodes.Insert(newNode.ObjectMeta.Name)
856+
case hasExcludeBalancerLabel:
852857
az.excludeLoadBalancerNodes.Insert(newNode.ObjectMeta.Name)
858+
case !isNodeReady(newNode):
859+
az.excludeLoadBalancerNodes.Insert(newNode.ObjectMeta.Name)
860+
default:
861+
// Nodes not falling into the three cases above are valid backends and
862+
// are removed from excludeLoadBalancerNodes cache.
863+
az.excludeLoadBalancerNodes.Delete(newNode.ObjectMeta.Name)
853864
}
854865
}
855866
}
@@ -975,3 +986,14 @@ func (az *Cloud) ShouldNodeExcludedFromLoadBalancer(nodeName string) (bool, erro
975986

976987
return az.excludeLoadBalancerNodes.Has(nodeName), nil
977988
}
989+
990+
// This, along with the few lines that call this function in updateNodeCaches, should be
991+
// replaced by https://github.com/kubernetes-sigs/cloud-provider-azure/pull/1195 once that merges.
992+
func isNodeReady(node *v1.Node) bool {
993+
for _, cond := range node.Status.Conditions {
994+
if cond.Type == v1.NodeReady && cond.Status == v1.ConditionTrue {
995+
return true
996+
}
997+
}
998+
return false
999+
}

staging/src/k8s.io/legacy-cloud-providers/azure/azure_test.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3248,12 +3248,13 @@ func TestUpdateNodeCaches(t *testing.T) {
32483248
Name: "prevNode",
32493249
},
32503250
}
3251-
3251+
// node is deleted from the cluster
32523252
az.updateNodeCaches(&prevNode, nil)
32533253
assert.Equal(t, 0, len(az.nodeZones[zone]))
32543254
assert.Equal(t, 0, len(az.nodeResourceGroups))
32553255
assert.Equal(t, 0, len(az.unmanagedNodes))
3256-
assert.Equal(t, 0, len(az.excludeLoadBalancerNodes))
3256+
// deleted node should be excluded from load balancer
3257+
assert.Equal(t, 1, len(az.excludeLoadBalancerNodes))
32573258
assert.Equal(t, 0, len(az.nodeNames))
32583259

32593260
newNode := v1.Node{
@@ -3267,12 +3268,12 @@ func TestUpdateNodeCaches(t *testing.T) {
32673268
Name: "newNode",
32683269
},
32693270
}
3270-
3271+
// new node is added to the cluster
32713272
az.updateNodeCaches(nil, &newNode)
32723273
assert.Equal(t, 1, len(az.nodeZones[zone]))
32733274
assert.Equal(t, 1, len(az.nodeResourceGroups))
32743275
assert.Equal(t, 1, len(az.unmanagedNodes))
3275-
assert.Equal(t, 1, len(az.excludeLoadBalancerNodes))
3276+
assert.Equal(t, 2, len(az.excludeLoadBalancerNodes))
32763277
assert.Equal(t, 1, len(az.nodeNames))
32773278
}
32783279

@@ -3310,6 +3311,48 @@ func TestUpdateNodeCacheExcludeLoadBalancer(t *testing.T) {
33103311
az.updateNodeCaches(&prevNode, &newNode)
33113312
assert.Equal(t, 1, len(az.excludeLoadBalancerNodes))
33123313

3314+
// non-ready node should be excluded
3315+
az.unmanagedNodes = sets.NewString()
3316+
az.excludeLoadBalancerNodes = sets.NewString()
3317+
az.nodeNames = sets.NewString()
3318+
nonReadyNode := v1.Node{
3319+
ObjectMeta: metav1.ObjectMeta{
3320+
Labels: map[string]string{
3321+
v1.LabelTopologyZone: zone,
3322+
},
3323+
Name: "aNode",
3324+
},
3325+
Status: v1.NodeStatus{
3326+
Conditions: []v1.NodeCondition{
3327+
{
3328+
Type: v1.NodeReady,
3329+
Status: v1.ConditionFalse,
3330+
},
3331+
},
3332+
},
3333+
}
3334+
az.updateNodeCaches(nil, &nonReadyNode)
3335+
assert.Equal(t, 1, len(az.excludeLoadBalancerNodes))
3336+
// node becomes ready
3337+
readyNode := v1.Node{
3338+
ObjectMeta: metav1.ObjectMeta{
3339+
Labels: map[string]string{
3340+
v1.LabelTopologyZone: zone,
3341+
},
3342+
Name: "aNode",
3343+
},
3344+
Status: v1.NodeStatus{
3345+
Conditions: []v1.NodeCondition{
3346+
{
3347+
Type: v1.NodeReady,
3348+
Status: v1.ConditionTrue,
3349+
},
3350+
},
3351+
},
3352+
}
3353+
az.updateNodeCaches(&nonReadyNode, &readyNode)
3354+
assert.Equal(t, 0, len(az.excludeLoadBalancerNodes))
3355+
33133356
}
33143357

33153358
func TestGetActiveZones(t *testing.T) {

0 commit comments

Comments
 (0)