Skip to content

Commit 92131ca

Browse files
tnqnatiratree
authored andcommitted
UPSTREAM: 117245: Fix TopologyAwareHint not working when zone label is added after Node creation
The topology.kubernetes.io/zone label may be added by could provider asynchronously after the Node is created. The previous code didn't update the topology cache after receiving the Node update event, causing TopologyAwareHint to not work until kube-controller-manager restarts or other Node events trigger the update. Signed-off-by: Quan Tian <qtian@vmware.com>
1 parent 31b5a64 commit 92131ca

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

pkg/controller/endpointslice/endpointslice_controller.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,10 @@ func (c *Controller) updateNode(old, cur interface{}) {
520520
oldNode := old.(*v1.Node)
521521
curNode := cur.(*v1.Node)
522522

523-
if topologycache.NodeReady(oldNode.Status) != topologycache.NodeReady(curNode.Status) {
523+
// LabelTopologyZone may be added by cloud provider asynchronously after the Node is created.
524+
// The topology cache should be updated in this case.
525+
if topologycache.NodeReady(oldNode.Status) != topologycache.NodeReady(curNode.Status) ||
526+
oldNode.Labels[v1.LabelTopologyZone] != curNode.Labels[v1.LabelTopologyZone] {
524527
c.checkNodeTopologyDistribution()
525528
}
526529
}

pkg/controller/endpointslice/endpointslice_controller_test.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"time"
2626

2727
"github.com/stretchr/testify/assert"
28+
"github.com/stretchr/testify/require"
2829
v1 "k8s.io/api/core/v1"
2930
discovery "k8s.io/api/discovery/v1"
3031
"k8s.io/apimachinery/pkg/api/resource"
@@ -1877,6 +1878,80 @@ func Test_checkNodeTopologyDistribution(t *testing.T) {
18771878
}
18781879
}
18791880

1881+
func TestUpdateNode(t *testing.T) {
1882+
nodeReadyStatus := v1.NodeStatus{
1883+
Allocatable: map[v1.ResourceName]resource.Quantity{
1884+
v1.ResourceCPU: resource.MustParse("100m"),
1885+
},
1886+
Conditions: []v1.NodeCondition{
1887+
{
1888+
Type: v1.NodeReady,
1889+
Status: v1.ConditionTrue,
1890+
},
1891+
},
1892+
}
1893+
_, esController := newController(nil, time.Duration(0))
1894+
sliceInfo := &topologycache.SliceInfo{
1895+
ServiceKey: "ns/svc",
1896+
AddressType: discovery.AddressTypeIPv4,
1897+
ToCreate: []*discovery.EndpointSlice{
1898+
{
1899+
ObjectMeta: metav1.ObjectMeta{
1900+
Name: "svc-abc",
1901+
Namespace: "ns",
1902+
Labels: map[string]string{
1903+
discovery.LabelServiceName: "svc",
1904+
discovery.LabelManagedBy: controllerName,
1905+
},
1906+
},
1907+
Endpoints: []discovery.Endpoint{
1908+
{
1909+
Addresses: []string{"172.18.0.2"},
1910+
Zone: pointer.String("zone-a"),
1911+
Conditions: discovery.EndpointConditions{Ready: pointer.Bool(true)},
1912+
},
1913+
{
1914+
Addresses: []string{"172.18.1.2"},
1915+
Zone: pointer.String("zone-b"),
1916+
Conditions: discovery.EndpointConditions{Ready: pointer.Bool(true)},
1917+
},
1918+
},
1919+
AddressType: discovery.AddressTypeIPv4,
1920+
},
1921+
},
1922+
}
1923+
node1 := &v1.Node{
1924+
ObjectMeta: metav1.ObjectMeta{Name: "node-1"},
1925+
Status: nodeReadyStatus,
1926+
}
1927+
node2 := &v1.Node{
1928+
ObjectMeta: metav1.ObjectMeta{Name: "node-2"},
1929+
Status: nodeReadyStatus,
1930+
}
1931+
esController.nodeStore.Add(node1)
1932+
esController.nodeStore.Add(node2)
1933+
esController.addNode(node1)
1934+
esController.addNode(node2)
1935+
// The Nodes don't have the zone label, AddHints should fail.
1936+
_, _, eventsBuilders := esController.topologyCache.AddHints(sliceInfo)
1937+
require.Len(t, eventsBuilders, 1)
1938+
assert.Contains(t, eventsBuilders[0].Message, topologycache.InsufficientNodeInfo)
1939+
1940+
updateNode1 := node1.DeepCopy()
1941+
updateNode1.Labels = map[string]string{v1.LabelTopologyZone: "zone-a"}
1942+
updateNode2 := node2.DeepCopy()
1943+
updateNode2.Labels = map[string]string{v1.LabelTopologyZone: "zone-b"}
1944+
1945+
// After adding the zone label to the Nodes and calling the event handler updateNode, AddHints should succeed.
1946+
esController.nodeStore.Update(updateNode1)
1947+
esController.nodeStore.Update(updateNode2)
1948+
esController.updateNode(node1, updateNode1)
1949+
esController.updateNode(node2, updateNode2)
1950+
_, _, eventsBuilders = esController.topologyCache.AddHints(sliceInfo)
1951+
require.Len(t, eventsBuilders, 1)
1952+
assert.Contains(t, eventsBuilders[0].Message, topologycache.TopologyAwareHintsEnabled)
1953+
}
1954+
18801955
// Test helpers
18811956
func addPods(t *testing.T, esController *endpointSliceController, namespace string, podsCount int) {
18821957
t.Helper()

0 commit comments

Comments
 (0)