From 36ed0ac6c5203a3f9d6da68869a0d1991a524b96 Mon Sep 17 00:00:00 2001 From: Antonio Ojea Date: Tue, 6 Jun 2023 10:20:14 +0000 Subject: [PATCH] kube-proxy avoid race condition using LocalModeNodeCIDR Since kube-proxy in LocalModeNodeCIDR needs to obtain the PodCIDR assigned to the node it watches for the Node object. However, kube-proxy startup process requires to have these watches in different places, that opens the possibility of having a race condition if the same node is recreated and a different PodCIDR is assigned. Initializing the second watch with the value obtained in the first one allows us to detect this situation. Change-Id: I6adeedb6914ad2afd3e0694dcab619c2a66135f8 Signed-off-by: Antonio Ojea --- cmd/kube-proxy/app/server.go | 3 ++- cmd/kube-proxy/app/server_others.go | 7 +++++-- pkg/proxy/node.go | 6 ++++++ pkg/proxy/node_test.go | 5 +++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 0aff9d2ca317..6751e3466e1f 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -545,6 +545,7 @@ type ProxyServer struct { ConfigSyncPeriod time.Duration HealthzServer healthcheck.ProxierHealthUpdater localDetectorMode kubeproxyconfig.LocalMode + podCIDRs []string // only used for LocalModeNodeCIDR } // createClients creates a kube client and an event client from the given config and masterOverride. @@ -767,7 +768,7 @@ func (s *ProxyServer) Run() error { nodeConfig := config.NewNodeConfig(currentNodeInformerFactory.Core().V1().Nodes(), s.ConfigSyncPeriod) // https://issues.k8s.io/111321 if s.localDetectorMode == kubeproxyconfig.LocalModeNodeCIDR { - nodeConfig.RegisterEventHandler(&proxy.NodePodCIDRHandler{}) + nodeConfig.RegisterEventHandler(proxy.NewNodePodCIDRHandler(s.podCIDRs)) } nodeConfig.RegisterEventHandler(s.Proxier) diff --git a/cmd/kube-proxy/app/server_others.go b/cmd/kube-proxy/app/server_others.go index 9836584bfa4f..8733e9acf4a4 100644 --- a/cmd/kube-proxy/app/server_others.go +++ b/cmd/kube-proxy/app/server_others.go @@ -134,16 +134,18 @@ func newProxyServer( } var nodeInfo *v1.Node + podCIDRs := []string{} if detectLocalMode == proxyconfigapi.LocalModeNodeCIDR { klog.InfoS("Watching for node, awaiting podCIDR allocation", "hostname", hostname) nodeInfo, err = waitForPodCIDR(client, hostname) if err != nil { return nil, err } - klog.InfoS("NodeInfo", "PodCIDR", nodeInfo.Spec.PodCIDR, "PodCIDRs", nodeInfo.Spec.PodCIDRs) + podCIDRs = nodeInfo.Spec.PodCIDRs + klog.InfoS("NodeInfo", "podCIDR", nodeInfo.Spec.PodCIDR, "podCIDRs", nodeInfo.Spec.PodCIDRs) } - klog.V(2).InfoS("DetectLocalMode", "LocalMode", string(detectLocalMode)) + klog.V(2).InfoS("DetectLocalMode", "localMode", string(detectLocalMode)) primaryProtocol := utiliptables.ProtocolIPv4 if netutils.IsIPv6(nodeIP) { @@ -341,6 +343,7 @@ func newProxyServer( ConfigSyncPeriod: config.ConfigSyncPeriod.Duration, HealthzServer: healthzServer, localDetectorMode: detectLocalMode, + podCIDRs: podCIDRs, }, nil } diff --git a/pkg/proxy/node.go b/pkg/proxy/node.go index 007699a3f7bb..a9d3cec6caa7 100644 --- a/pkg/proxy/node.go +++ b/pkg/proxy/node.go @@ -33,6 +33,12 @@ type NodePodCIDRHandler struct { podCIDRs []string } +func NewNodePodCIDRHandler(podCIDRs []string) *NodePodCIDRHandler { + return &NodePodCIDRHandler{ + podCIDRs: podCIDRs, + } +} + var _ config.NodeHandler = &NodePodCIDRHandler{} // OnNodeAdd is a handler for Node creates. diff --git a/pkg/proxy/node_test.go b/pkg/proxy/node_test.go index ab20130b0336..2f6d7b54ad7b 100644 --- a/pkg/proxy/node_test.go +++ b/pkg/proxy/node_test.go @@ -37,6 +37,11 @@ func TestNodePodCIDRHandlerAdd(t *testing.T) { name: "initialized correctly", newNodePodCIDRs: []string{"192.168.1.0/24", "fd00:1:2:3::/64"}, }, + { + name: "already initialized and same node", + oldNodePodCIDRs: []string{"10.0.0.0/24", "fd00:3:2:1::/64"}, + newNodePodCIDRs: []string{"10.0.0.0/24", "fd00:3:2:1::/64"}, + }, { name: "already initialized and different node", oldNodePodCIDRs: []string{"192.168.1.0/24", "fd00:1:2:3::/64"},