From d22e18ad4f9eadab2b8d08ac61af2088596569b7 Mon Sep 17 00:00:00 2001 From: "Christopher M. Luciano" Date: Tue, 25 Feb 2020 14:47:53 -0500 Subject: [PATCH] ipvs: only attempt setting of sysctlconnreuse on supported kernels This builds on previous work but only sets the sysctlConnReuse value if the kernel is known to be above 4.19. To avoid calling GetKernelVersion twice, I store the value from the CanUseIPVS method and then check the version constraint at time of expected sysctl call. Signed-off-by: Christopher M. Luciano --- cmd/kube-proxy/app/server_others.go | 2 ++ pkg/proxy/ipvs/proxier.go | 28 ++++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/cmd/kube-proxy/app/server_others.go b/cmd/kube-proxy/app/server_others.go index 15d3a1ae178..c6f24c89620 100644 --- a/cmd/kube-proxy/app/server_others.go +++ b/cmd/kube-proxy/app/server_others.go @@ -276,6 +276,7 @@ func newProxyServer( healthzServer, config.IPVS.Scheduler, config.NodePortAddresses, + kernelHandler, ) } else { var localDetector proxyutiliptables.LocalTrafficDetector @@ -306,6 +307,7 @@ func newProxyServer( healthzServer, config.IPVS.Scheduler, config.NodePortAddresses, + kernelHandler, ) } if err != nil { diff --git a/pkg/proxy/ipvs/proxier.go b/pkg/proxy/ipvs/proxier.go index 5b3eda42960..605317ae6a3 100644 --- a/pkg/proxy/ipvs/proxier.go +++ b/pkg/proxy/ipvs/proxier.go @@ -88,6 +88,8 @@ const ( // DefaultDummyDevice is the default dummy interface which ipvs service address will bind to it. DefaultDummyDevice = "kube-ipvs0" + + connReuseMinSupportedKernelVersion = "4.1" ) // iptablesJumpChain is tables of iptables chains that ipvs proxier used to install iptables or cleanup iptables. @@ -341,6 +343,7 @@ func NewProxier(ipt utiliptables.Interface, healthzServer healthcheck.ProxierHealthUpdater, scheduler string, nodePortAddresses []string, + kernelHandler KernelHandler, ) (*Proxier, error) { // Set the route_localnet sysctl we need for if val, _ := sysctl.GetSysctl(sysctlRouteLocalnet); val != 1 { @@ -363,10 +366,22 @@ func NewProxier(ipt utiliptables.Interface, } } - // Set the connection reuse mode - if val, _ := sysctl.GetSysctl(sysctlConnReuse); val != 0 { - if err := sysctl.SetSysctl(sysctlConnReuse, 0); err != nil { - return nil, fmt.Errorf("can't set sysctl %s: %v", sysctlConnReuse, err) + kernelVersionStr, err := kernelHandler.GetKernelVersion() + if err != nil { + return nil, fmt.Errorf("error determining kernel version to find required kernel modules for ipvs support: %v", err) + } + kernelVersion, err := version.ParseGeneric(kernelVersionStr) + if err != nil { + return nil, fmt.Errorf("error parsing kernel version %q: %v", kernelVersionStr, err) + } + if kernelVersion.LessThan(version.MustParseGeneric(connReuseMinSupportedKernelVersion)) { + klog.Errorf("can't set sysctl %s, kernel version must be at least %s", sysctlConnReuse, connReuseMinSupportedKernelVersion) + } else { + // Set the connection reuse mode + if val, _ := sysctl.GetSysctl(sysctlConnReuse); val != 0 { + if err := sysctl.SetSysctl(sysctlConnReuse, 0); err != nil { + return nil, fmt.Errorf("can't set sysctl %s: %v", sysctlConnReuse, err) + } } } @@ -503,6 +518,7 @@ func NewDualStackProxier( healthzServer healthcheck.ProxierHealthUpdater, scheduler string, nodePortAddresses []string, + kernelHandler KernelHandler, ) (proxy.Provider, error) { safeIpset := newSafeIpset(ipset) @@ -512,7 +528,7 @@ func NewDualStackProxier( exec, syncPeriod, minSyncPeriod, filterCIDRs(false, excludeCIDRs), strictARP, tcpTimeout, tcpFinTimeout, udpTimeout, masqueradeAll, masqueradeBit, localDetectors[0], hostname, nodeIP[0], - recorder, healthzServer, scheduler, nodePortAddresses) + recorder, healthzServer, scheduler, nodePortAddresses, kernelHandler) if err != nil { return nil, fmt.Errorf("unable to create ipv4 proxier: %v", err) } @@ -521,7 +537,7 @@ func NewDualStackProxier( exec, syncPeriod, minSyncPeriod, filterCIDRs(true, excludeCIDRs), strictARP, tcpTimeout, tcpFinTimeout, udpTimeout, masqueradeAll, masqueradeBit, localDetectors[1], hostname, nodeIP[1], - nil, nil, scheduler, nodePortAddresses) + nil, nil, scheduler, nodePortAddresses, kernelHandler) if err != nil { return nil, fmt.Errorf("unable to create ipv6 proxier: %v", err) }