From 4e57dcd195992dd6d19b2d1a731d6673c9ee2e4b Mon Sep 17 00:00:00 2001 From: Periyasamy Palanisamy Date: Fri, 17 Jan 2025 13:34:23 +0100 Subject: [PATCH] =?UTF-8?q?Keep=20ovn=20ipsec=20enabled=20during=20the=20u?= =?UTF-8?q?pgrade=20=C2=A0=20=C2=A0=20The=20following=20change=20on=20the?= =?UTF-8?q?=20machine=20pool=20`status.MachineCount=20=3D=3D=20status.Upda?= =?UTF-8?q?tedMachineCount=20&&=20hasSourceInMachineConfigStatus(status,?= =?UTF-8?q?=20machineConfigs)`=20is=20introduced=20with=20PR=20https://git?= =?UTF-8?q?hub.com/openshift/cluster-network-operator/pull/2349=20which=20?= =?UTF-8?q?ensures=20IPsec=20machine=20config=20is=20always=20installed=20?= =?UTF-8?q?on=20all=20the=20nodes=20in=20the=20cluster,=20So=20this=20is?= =?UTF-8?q?=20deleting=20the=20IPsec=20daemonset=20as=20per=20the=20CNO=20?= =?UTF-8?q?state=20machine=20for=20IPsec=20when=20the=20condition=20is=20n?= =?UTF-8?q?ot=20met.=20But=20this=20is=20also=20accidentally=20disabling?= =?UTF-8?q?=20IPsec=20in=20OVN=20which=20is=20not=20an=20expected=20behavi?= =?UTF-8?q?or.=20This=20causes=20ovs-monitor-ipsec=20to=20refresh=20existi?= =?UTF-8?q?ng=20ipsec=20connections=20unnecessarily=20when=20IPsec=20pod?= =?UTF-8?q?=20comes=20up=20as=20it=20is=20not=20able=20to=20find=20remote?= =?UTF-8?q?=5Fname=20from=20the=20tunnel.=20This=20may=20also=20trigger=20?= =?UTF-8?q?deleting=20IPsec=20connection=20entries=20from=20openshift.conf?= =?UTF-8?q?=20file=20if=20ovs-monitor-ipsec=20is=20not=20killed=20timely?= =?UTF-8?q?=20when=20ipsec=20daemonset=20is=20removed.=20So=20this=20commi?= =?UTF-8?q?t=20enables=20ovn=20ipsec=20option=20as=20long=20as=20the=20API?= =?UTF-8?q?=20is=20set=20with=20Full=20mode.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Periyasamy Palanisamy --- pkg/network/ovn_kubernetes.go | 97 ++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/pkg/network/ovn_kubernetes.go b/pkg/network/ovn_kubernetes.go index da943e3b9d..a7ffaf0045 100644 --- a/pkg/network/ovn_kubernetes.go +++ b/pkg/network/ovn_kubernetes.go @@ -613,69 +613,72 @@ func IsIPsecLegacyAPI(conf *operv1.OVNKubernetesConfig) bool { return conf.IPsecConfig == nil || conf.IPsecConfig.Mode == "" } -// shouldRenderIPsec method ensures the have following IPsec states for upgrade path from 4.14 to 4.15 or later versions: -// When 4.14 cluster is already installed with MachineConfig for IPsec extension and ipsecConfig is set in network operator -// config (i.e. IPsec for NS+EW), then render CNO's IPsec MC extension and ipsec-host daemonset. -// When 4.14 cluster is just running with ipsecConfig set in network operator config (i.e. IPsec for EW only), then activate -// IPsec MachineConfig and render ipsec-host daemonset. -// When 4.14 cluster is just installed with MachineConfig for IPsec extension (i.e. IPsec for NS only), then just keep MachineConfig -// to be in the same state without rendering IPsec daemonsets. -// When 4.14 cluster is Hypershift cluster running with ipsecConfig set, then just render ovn-ipsec-containerized daemonset as -// MachineConfig kind is not supported there. -// For Upgrade path from pre-4.14 to 5.15 or later versions: -// When pre-4.14 cluster is just running with ipsecConfig set in network operator config (i.e. IPsec for EW only), then activate -// IPsec MachineConfig and render ipsec-host daemonset. -// When pre-4.14 cluster is Hypershift cluster running with ipsecConfig set, then just render ovn-ipsec-containerized daemonset as -// MachineConfig kind is not supported there. -// All Other cases are not supported in pre-4.14 deployments. +// shouldRenderIPsec method ensures the needed states when enabling, disabling +// or upgrading IPsec func shouldRenderIPsec(conf *operv1.OVNKubernetesConfig, bootstrapResult *bootstrap.BootstrapResult) (renderCNOIPsecMachineConfig, renderIPsecDaemonSet, renderIPsecOVN, renderIPsecHostDaemonSet, renderIPsecContainerizedDaemonSet, renderIPsecDaemonSetAsCreateWaitOnly bool) { + + // Note on 4.14 to 4.15 legacy IPsec upgrade for self managed clusters: + // during this upgrade both host and containerized daemonsets are rendered. + // Internally, these damonsets coordinate when they are active or dormant: + // before the IPsec MachineConfig extensions are active, the containerized + // daemonset is active and the host daemonset is dormant; after rebooting + // with the the IPsec MachineConfig extensions active, the containerized + // daemonset is dormant and the host daemonset is active. When the upgrade + // finishes, the containerized daemonset is then not rendered. + isHypershiftHostedCluster := bootstrapResult.Infra.HostedControlPlane != nil - isIpsecUpgrade := bootstrapResult.OVN.IPsecUpdateStatus != nil && bootstrapResult.OVN.IPsecUpdateStatus.LegacyIPsecUpgrade + isIpsecLegacyUpgrade := bootstrapResult.OVN.IPsecUpdateStatus != nil && bootstrapResult.OVN.IPsecUpdateStatus.LegacyIPsecUpgrade isOVNIPsecActive := bootstrapResult.OVN.IPsecUpdateStatus != nil && bootstrapResult.OVN.IPsecUpdateStatus.OVNIPsecActive mode := GetIPsecMode(conf) - // On upgrade, we will just remove any existing ipsec deployment without making any - // change to them. So during upgrade, we must keep track if IPsec MachineConfigs are - // active or not for non Hybrid hosted cluster. - isIPsecMachineConfigActive := isIPsecMachineConfigActive(bootstrapResult.Infra) - isIPsecMachineConfigNotActiveOnUpgrade := isIpsecUpgrade && !isIPsecMachineConfigActive && !isHypershiftHostedCluster - isMachineConfigClusterOperatorReady := bootstrapResult.Infra.MachineConfigClusterOperatorReady - isCNOIPsecMachineConfigPresent := isCNOIPsecMachineConfigPresent(bootstrapResult.Infra) - isUserDefinedIPsecMachineConfigPresent := isUserDefinedIPsecMachineConfigPresent(bootstrapResult.Infra) - // We render the ipsec deployment if IPsec is already active in OVN // or if EW IPsec config is enabled. renderIPsecDaemonSet = isOVNIPsecActive || mode == operv1.IPsecModeFull - // If ipsec is enabled, we render the host ipsec deployment except for - // hypershift hosted clusters and we need to wait for the ipsec MachineConfig - // extensions to be active first. We must also render host ipsec deployment - // at the time of upgrade though user created IPsec Machine Config is not - // present/active. - renderIPsecHostDaemonSet = (renderIPsecDaemonSet && isIPsecMachineConfigActive && !isHypershiftHostedCluster) || isIPsecMachineConfigNotActiveOnUpgrade - - // The containerized ipsec deployment is only rendered during upgrades or - // for hypershift hosted clusters. - renderIPsecContainerizedDaemonSet = (renderIPsecDaemonSet && isHypershiftHostedCluster) || isIPsecMachineConfigNotActiveOnUpgrade - - // MachineConfig IPsec extensions rollout is needed for the ipsec enablement and are used in both External and Full modes. - // except when the containerized deployment is used in hypershift hosted clusters. Also do not render Machine Config if - // user already created their own machine config for IPsec. + // To enable IPsec, specific MachineConfig extensions need to be rolled out + // first with the following exceptions: + // - not needed for the containerized deployment is used in hypershift + // hosted clusters + // - not needed if the user already created their own + isMachineConfigClusterOperatorReady := bootstrapResult.Infra.MachineConfigClusterOperatorReady + isCNOIPsecMachineConfigPresent := isCNOIPsecMachineConfigPresent(bootstrapResult.Infra) + isUserDefinedIPsecMachineConfigPresent := isUserDefinedIPsecMachineConfigPresent(bootstrapResult.Infra) renderCNOIPsecMachineConfig = (mode != operv1.IPsecModeDisabled || renderIPsecDaemonSet) && !isHypershiftHostedCluster && !isUserDefinedIPsecMachineConfigPresent // Wait for MCO to be ready unless we had already rendered the IPsec MachineConfig. renderCNOIPsecMachineConfig = renderCNOIPsecMachineConfig && (isCNOIPsecMachineConfigPresent || isMachineConfigClusterOperatorReady) - // We render OVN IPsec if East-West IPsec is enabled or it's upgrade is in progress. - // If NS IPsec is enabled as well, we need to wait to IPsec MachineConfig - // to be active if it's not an upgrade and not a hypershift hosted cluster. - renderIPsecOVN = (renderIPsecHostDaemonSet || renderIPsecContainerizedDaemonSet) && mode == operv1.IPsecModeFull - - // While OVN ipsec is being upgraded and IPsec MachineConfigs deployment is in progress - // (or) IPsec config in OVN is being disabled, then ipsec deployment is not updated. - renderIPsecDaemonSetAsCreateWaitOnly = isIPsecMachineConfigNotActiveOnUpgrade || (isOVNIPsecActive && !renderIPsecOVN) + // As a general rule, we need to wait until the IPsec MachineConfig + // extensions are active before rendendering the IPsec daemonsets. Note that + // during upgrades or node reboots there is a period of time where the IPsec + // machine configs are not active and the daemonset won't be rendered but + // that is fine since the IPsec configuration should persist. The exception + // is 4.14 to 4.15 legacy IPsec upgrade as noted above. + isIPsecMachineConfigActive := isIPsecMachineConfigActive(bootstrapResult.Infra) + isIPsecMachineConfigNotActiveOnLegacyUpgrade := isIpsecLegacyUpgrade && !isIPsecMachineConfigActive && !isHypershiftHostedCluster + + // We render the host ipsec deployment for self managed clusters after the + // ipsec MachineConfig extensions have been rolled out, except for the 4.14 + // to 4.15 legacy IPsec upgrade as noted above. + renderIPsecHostDaemonSet = (renderIPsecDaemonSet && isIPsecMachineConfigActive && !isHypershiftHostedCluster) || isIPsecMachineConfigNotActiveOnLegacyUpgrade + + // We render the containerized ipsec deployment for hosted clusters. It does + // not depend on any machine config extension however we also render it for + // the 4.14 to 4.15 legacy IPsec upgrade as noted above. + renderIPsecContainerizedDaemonSet = (renderIPsecDaemonSet && isHypershiftHostedCluster) || isIPsecMachineConfigNotActiveOnLegacyUpgrade + + // We render OVN IPsec if EW IPsec is enabled not before the daemon sets are + // rendered. If it is already rendered, keep it rendered unless disabled. + renderIPsecOVN = (renderIPsecHostDaemonSet || renderIPsecContainerizedDaemonSet || isOVNIPsecActive) && mode == operv1.IPsecModeFull + + // Keep IPsec daemonsets updated (but avoid creating) in the following circumstances: + // - on the 4.14 to 4.15 legacy IPsec upgrade, where we just want to update + // them as noted above + // - when disabling OVN IPsec, we want to keep the daemonsets until after + // OVN IPsec is disabled + renderIPsecDaemonSetAsCreateWaitOnly = isIPsecMachineConfigNotActiveOnLegacyUpgrade || (isOVNIPsecActive && !renderIPsecOVN) return }