Skip to content

Commit 9530aae

Browse files
committed
Reduce node events caused by zone cluster controller
On every node event, ZCC will call kube patch. Reduce it to a single time. Before patch: trozet@fedora:~/go/src/github.com/ovn-org/ovn-kubernetes/go-controller$ go test -mod=vendor -v ./pkg/clustermanager -ginkgo.v -ginkgo.focus=".*Node subnet allocations.*Linux nodes$" | grep -i "setting annotations" I0218 11:18:14.168191 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:3] on node node1 I0218 11:18:14.168187 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:2] on node node2 I0218 11:18:14.168200 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:4] on node node3 I0218 11:18:14.168964 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:3] on node node1 I0218 11:18:14.169120 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:4] on node node3 I0218 11:18:14.169152 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:2] on node node2 I0218 11:18:14.169395 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:3] on node node1 I0218 11:18:14.169430 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:2] on node node2 I0218 11:18:14.169492 310203 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:4] on node node3 After patch: trozet@fedora:~/go/src/github.com/ovn-org/ovn-kubernetes/go-controller$ go test -mod=vendor -v ./pkg/clustermanager -ginkgo.v -ginkgo.focus=".*Node subnet allocations.*Linux nodes$" | grep -i "setting annotations" I0218 11:28:16.991114 338949 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:2] on node node2 I0218 11:28:16.991133 338949 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:4] on node node3 I0218 11:28:16.991130 338949 kube.go:130] Setting annotations map[k8s.ovn.org/node-id:3] on node node1 Signed-off-by: Tim Rozet <[email protected]>
1 parent 836ec36 commit 9530aae

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

go-controller/pkg/clustermanager/zone_cluster_controller.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,23 @@ func (zcc *zoneClusterController) Stop() {
131131
}
132132
}
133133

134+
func needsZoneAllocation(node *corev1.Node) bool {
135+
if config.HybridOverlay.Enabled && util.NoHostSubnet(node) {
136+
// skip hybrid overlay nodes
137+
return false
138+
}
139+
140+
if _, ok := node.Annotations[util.OvnNodeID]; !ok {
141+
return true
142+
}
143+
if config.OVNKubernetesFeature.EnableInterconnect {
144+
if _, ok := node.Annotations[util.OvnTransitSwitchPortAddr]; !ok {
145+
return true
146+
}
147+
}
148+
return false
149+
}
150+
134151
// handleAddUpdateNodeEvent handles the add or update node event
135152
func (zcc *zoneClusterController) handleAddUpdateNodeEvent(node *corev1.Node) error {
136153
if config.HybridOverlay.Enabled && util.NoHostSubnet(node) {
@@ -226,6 +243,8 @@ type zoneClusterControllerEventHandler struct {
226243
objType reflect.Type
227244
zcc *zoneClusterController
228245
syncFunc func([]interface{}) error
246+
247+
nodeSyncFailed sync.Map
229248
}
230249

231250
func (h *zoneClusterControllerEventHandler) FilterOutResource(_ interface{}) bool {
@@ -246,9 +265,11 @@ func (h *zoneClusterControllerEventHandler) AddResource(obj interface{}, _ bool)
246265
return fmt.Errorf("could not cast %T object to *corev1.Node", obj)
247266
}
248267
if err = h.zcc.handleAddUpdateNodeEvent(node); err != nil {
268+
h.nodeSyncFailed.Store(node.Name, true)
249269
return fmt.Errorf("node add failed for %s, will try again later: %w",
250270
node.Name, err)
251271
}
272+
h.nodeSyncFailed.Delete(node.Name)
252273
default:
253274
return fmt.Errorf("no add function for object type %s", h.objType)
254275
}
@@ -267,10 +288,16 @@ func (h *zoneClusterControllerEventHandler) UpdateResource(_, newObj interface{}
267288
if !ok {
268289
return fmt.Errorf("could not cast %T object to *corev1.Node", newObj)
269290
}
291+
_, nodeFailed := h.nodeSyncFailed.Load(node.GetName())
292+
if !nodeFailed && !needsZoneAllocation(node) {
293+
// node ID and transit switch IP are assigned by us and cannot change
294+
return nil
295+
}
270296
if err = h.zcc.handleAddUpdateNodeEvent(node); err != nil {
271297
return fmt.Errorf("node update failed for %s, will try again later: %w",
272298
node.Name, err)
273299
}
300+
h.nodeSyncFailed.Delete(node.GetName())
274301
default:
275302
return fmt.Errorf("no update function for object type %s", h.objType)
276303
}
@@ -286,7 +313,11 @@ func (h *zoneClusterControllerEventHandler) DeleteResource(obj, _ interface{}) e
286313
if !ok {
287314
return fmt.Errorf("could not cast obj of type %T to *knet.Node", obj)
288315
}
289-
return h.zcc.handleDeleteNode(node)
316+
err := h.zcc.handleDeleteNode(node)
317+
if err != nil {
318+
return err
319+
}
320+
h.nodeSyncFailed.Delete(node.GetName())
290321
}
291322
return nil
292323
}

go-controller/pkg/util/node_annotations.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,12 @@ const (
129129
OvnNodeMigratedZoneName = "k8s.ovn.org/remote-zone-migrated"
130130
/** HACK END **/
131131

132-
// ovnTransitSwitchPortAddr is the annotation to store the node Transit switch port ips.
132+
// OvnTransitSwitchPortAddr is the annotation to store the node Transit switch port ips.
133133
// It is set by cluster manager.
134-
ovnTransitSwitchPortAddr = "k8s.ovn.org/node-transit-switch-port-ifaddr"
134+
OvnTransitSwitchPortAddr = "k8s.ovn.org/node-transit-switch-port-ifaddr"
135135

136-
// ovnNodeID is the id (of type integer) of a node. It is set by cluster-manager.
137-
ovnNodeID = "k8s.ovn.org/node-id"
136+
// OvnNodeID is the id (of type integer) of a node. It is set by cluster-manager.
137+
OvnNodeID = "k8s.ovn.org/node-id"
138138

139139
// InvalidNodeID indicates an invalid node id
140140
InvalidNodeID = -1
@@ -646,11 +646,11 @@ func parseJoinSubnetAnnotation(nodeAnnotations map[string]string, annotationName
646646
// CreateNodeTransitSwitchPortAddrAnnotation creates the node annotation for the node's Transit switch port addresses.
647647
func CreateNodeTransitSwitchPortAddrAnnotation(nodeAnnotation map[string]interface{}, nodeIPNetv4,
648648
nodeIPNetv6 *net.IPNet) (map[string]interface{}, error) {
649-
return createPrimaryIfAddrAnnotation(ovnTransitSwitchPortAddr, nodeAnnotation, nodeIPNetv4, nodeIPNetv6)
649+
return createPrimaryIfAddrAnnotation(OvnTransitSwitchPortAddr, nodeAnnotation, nodeIPNetv4, nodeIPNetv6)
650650
}
651651

652652
func NodeTransitSwitchPortAddrAnnotationChanged(oldNode, newNode *corev1.Node) bool {
653-
return oldNode.Annotations[ovnTransitSwitchPortAddr] != newNode.Annotations[ovnTransitSwitchPortAddr]
653+
return oldNode.Annotations[OvnTransitSwitchPortAddr] != newNode.Annotations[OvnTransitSwitchPortAddr]
654654
}
655655

656656
// CreateNodeMasqueradeSubnetAnnotation sets the IPv4 / IPv6 values of the node's Masquerade subnet.
@@ -870,7 +870,7 @@ func ParseNodeGatewayRouterJoinAddrs(node *corev1.Node, netName string) ([]*net.
870870
// ParseNodeTransitSwitchPortAddrs returns the IPv4 and/or IPv6 addresses for the node's transit switch port
871871
// stored in the 'ovnTransitSwitchPortAddr' annotation
872872
func ParseNodeTransitSwitchPortAddrs(node *corev1.Node) ([]*net.IPNet, error) {
873-
return parsePrimaryIfAddrAnnotation(node, ovnTransitSwitchPortAddr)
873+
return parsePrimaryIfAddrAnnotation(node, OvnTransitSwitchPortAddr)
874874
}
875875

876876
// ParseNodeMasqueradeSubnet returns the IPv4 and/or IPv6 networks for the node's gateway router port
@@ -1228,22 +1228,22 @@ func GetSecondaryHostNetworkContainingIP(node *corev1.Node, ip net.IP) (string,
12281228
return match.String(), nil
12291229
}
12301230

1231-
// UpdateNodeIDAnnotation updates the ovnNodeID annotation with the node id in the annotations map
1231+
// UpdateNodeIDAnnotation updates the OvnNodeID annotation with the node id in the annotations map
12321232
// and returns it.
12331233
func UpdateNodeIDAnnotation(annotations map[string]interface{}, nodeID int) map[string]interface{} {
12341234
if annotations == nil {
12351235
annotations = make(map[string]interface{})
12361236
}
12371237

1238-
annotations[ovnNodeID] = strconv.Itoa(nodeID)
1238+
annotations[OvnNodeID] = strconv.Itoa(nodeID)
12391239
return annotations
12401240
}
12411241

1242-
// GetNodeID returns the id of the node set in the 'ovnNodeID' node annotation.
1243-
// Returns InvalidNodeID (-1) if the 'ovnNodeID' node annotation is not set or if the value is
1242+
// GetNodeID returns the id of the node set in the 'OvnNodeID' node annotation.
1243+
// Returns InvalidNodeID (-1) if the 'OvnNodeID' node annotation is not set or if the value is
12441244
// not an integer value.
12451245
func GetNodeID(node *corev1.Node) int {
1246-
nodeID, ok := node.Annotations[ovnNodeID]
1246+
nodeID, ok := node.Annotations[OvnNodeID]
12471247
if !ok {
12481248
return InvalidNodeID
12491249
}
@@ -1255,9 +1255,9 @@ func GetNodeID(node *corev1.Node) int {
12551255
return id
12561256
}
12571257

1258-
// NodeIDAnnotationChanged returns true if the ovnNodeID in the corev1.Nodes doesn't match
1258+
// NodeIDAnnotationChanged returns true if the OvnNodeID in the corev1.Nodes doesn't match
12591259
func NodeIDAnnotationChanged(oldNode, newNode *corev1.Node) bool {
1260-
return oldNode.Annotations[ovnNodeID] != newNode.Annotations[ovnNodeID]
1260+
return oldNode.Annotations[OvnNodeID] != newNode.Annotations[OvnNodeID]
12611261
}
12621262

12631263
// SetNodeZone sets the node's zone in the 'ovnNodeZoneName' node annotation.

0 commit comments

Comments
 (0)