Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks!--kube-proxy cannot use ipvs mode on Linux 4.19 due to a check for the module, which was changed to (). uses to check for : It should instead accept on Linux 4.19 or above. What happened: kube-proxy fell back from ipvs mode to iptables mode. What you expected to happen: kube-proxy using ipvs. How to reproduce it (as minimally and precisely as possible): Launch a cluster on an image using Linux 4.19 or above with kube-proxy using ipvs mode (see ). Environment: Kubernetes version (use ): All Kernel (e.g. ): 4.19 <!-- DO NOT EDIT BELOW THIS LINE --/kind bug
/sig network
/area ipvs /assign /cc
Okay, so should check {nfconntrackipv4 | nf_conntrack} and expect load at least one module?
I think so
Please just go ahead :)

Discussion:
{kubeNodePortLocalSetSCTP, string(KubeNodePortChain), "RETURN", "dst", "sctp"}, } <del> var ipvsModules = []string{ "ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack_ipv4", "nf_conntrack", } </del> // In IPVS proxy mode, the following flags need to be set const sysctlRouteLocalnet = "net/ipv4/conf/all/route_localnet" const sysctlBridgeCallIPTables = "net/bridge/bridge-nf-call-iptables"

// GetModules returns all installed kernel modules. func (handle *LinuxKernelHandler) GetModules() ([]string, error) { // Check whether IPVS required kernel modules are built-in <del> kernelVersionFile := "/proc/sys/kernel/osrelease" b, err := ioutil.ReadFile(kernelVersionFile) </del> <ins> kernelVersion, ipvsModules, err := utilipvs.GetKernelVersionAndIPVSMods(handle.executor) </ins> if err != nil { <del> glog.Errorf("Failed to read file %s with error %v", kernelVersionFile, err) </del> <ins> return nil, err </ins> } <del> kernelVersion := strings.TrimSpace(string(b)) </del> builtinModsFilePath := fmt.Sprintf("/lib/modules/%s/modules.builtin", kernelVersion) <del> b, err = ioutil.ReadFile(builtinModsFilePath) </del> <ins> b, err := ioutil.ReadFile(builtinModsFilePath) </ins> if err != nil { glog.Warningf("Failed to read file %s with error %v. You can ignore this message when kube-proxy is running inside container without mounting /lib/modules", builtinModsFilePath, err) }

} wantModules := sets.NewString() loadModules := sets.NewString() <ins> linuxKernelHandler := NewLinuxKernelHandler() _, ipvsModules, _ := utilipvs.GetKernelVersionAndIPVSMods(linuxKernelHandler.executor) </ins> wantModules.Insert(ipvsModules...) loadModules.Insert(mods...) modules := wantModules.Difference(loadModules).UnsortedList()

"kernelcheck_unsupported.go", ], importpath = "k8s.io/kubernetes/pkg/util/ipvs", <del> deps = select({ "@io_bazel_rules_go//go/platform:android": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:darwin": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:dragonfly": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:freebsd": [ "//vendor/k8s.io/utils/exec:go_default_library", ], </del> <ins> deps = [ "//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library", "//vendor/k8s.io/utils/exec:go_default_library", ] + select({ </ins> "@io_bazel_rules_go//go/platform:linux": [ "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//vendor/github.com/docker/libnetwork/ipvs:go_default_library", "//vendor/github.com/golang/glog:go_default_library", <del> "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:nacl": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:netbsd": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:openbsd": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:plan9": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:solaris": [ "//vendor/k8s.io/utils/exec:go_default_library", ], "@io_bazel_rules_go//go/platform:windows": [ "//vendor/k8s.io/utils/exec:go_default_library", </del> ], "//conditions:default": [], }),

import ( "net" "strconv" <ins> "strings" "fmt" "k8s.io/apimachinery/pkg/util/version" "k8s.io/utils/exec" </ins> ) // Interface is an injectable interface for running ipvs commands.  Implementations must be goroutine-safe.

IPVSProxyMode = "ipvs" ) <del> // Sets of IPVS required kernel modules. var ipvsModules = []string{ "ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack_ipv4", } </del> <ins> // IPVS required kernel modules. const ( // ModIPVS is the kernel module "ip_vs" ModIPVS string = "ip_vs" // ModIPVSRR is the kernel module "ip_vs_rr" ModIPVSRR string = "ip_vs_rr" // ModIPVSWRR is the kernel module "ip_vs_wrr" ModIPVSWRR string = "ip_vs_wrr" // ModIPVSSH is the kernel module "ip_vs_sh" ModIPVSSH string = "ip_vs_sh" // ModNfConntrackIPV4 is the module "nf_conntrack_ipv4" ModNfConntrackIPV4 string = "nf_conntrack_ipv4" // ModNfConntrack is the kernel module "nf_conntrack" ModNfConntrack string = "nf_conntrack" ) </ins> // Equal check the equality of virtual server. // We don't use struct == since it doesn't work because of slice.

return rs.Address.Equal(other.Address) && rs.Port == other.Port } <ins> // GetKernelVersionAndIPVSMods returns the linux kernel version and the required ipvs modules func GetKernelVersionAndIPVSMods(Executor exec.Interface) (kernelVersion string, ipvsModules []string, err error) { kernelVersionFile := "/proc/sys/kernel/osrelease" out, err := Executor.Command("cut", "-f1", "-d", " ", kernelVersionFile).CombinedOutput() if err != nil { return "", nil, fmt.Errorf("error getting os release kernel version: %v(%s)", err, out) } kernelVersion = strings.TrimSpace(string(out)) // parse kernel version ver1, err := version.ParseGeneric(kernelVersion) if err != nil { return kernelVersion, nil, fmt.Errorf("error parsing kernel version: %v(%s)", err, kernelVersion) } // "nf_conntrack_ipv4" has been removed since v4.19 // see https://github.com/torvalds/linux/commit/a0ae2562c6c4b2721d9fddba63b7286c13517d9f ver2, _ := version.ParseGeneric("4.19") // get required ipvs modules if ver1.LessThan(ver2) { ipvsModules = append(ipvsModules, ModIPVS, ModIPVSRR, ModIPVSWRR, ModIPVSSH, ModNfConntrackIPV4) } else { ipvsModules = append(ipvsModules, ModIPVS, ModIPVSRR, ModIPVSWRR, ModIPVSSH, ModNfConntrack) } return kernelVersion, ipvsModules, nil } </ins>

func (r RequiredIPVSKernelModulesAvailableCheck) Check() (warnings, errors []error) { glog.V(1).Infoln("validating the kernel module IPVS required exists in machine or not") <ins> kernelVersion, ipvsModules, err := GetKernelVersionAndIPVSMods(r.Executor) if err != nil { errors = append(errors, err) } </ins> // Find out loaded kernel modules out, err := r.Executor.Command("cut", "-f1", "-d", " ", "/proc/modules").CombinedOutput() if err != nil {

// Check builtin modules exist or not if len(modules) != 0 { <del> kernelVersionFile := "/proc/sys/kernel/osrelease" b, err := r.Executor.Command("cut", "-f1", "-d", " ", kernelVersionFile).CombinedOutput() if err != nil { errors = append(errors, fmt.Errorf("error getting os release kernel version: %v(%s)", err, out)) return nil, errors } kernelVersion := strings.TrimSpace(string(b)) </del> builtinModsFilePath := fmt.Sprintf("/lib/modules/%s/modules.builtin", kernelVersion) out, err := r.Executor.Command("cut", "-f1", "-d", " ", builtinModsFilePath).CombinedOutput() if err != nil {

for i, tc := range cases { fcmd := fakeexec.FakeCmd{ CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{ <del> func() ([]byte, error) { return []byte(cases[i].loadedKernel), nil }, </del> func() ([]byte, error) { return []byte(cases[i].kernelVersion), nil }, <ins> func() ([]byte, error) { return []byte(cases[i].loadedKernel), nil }, </ins> func() ([]byte, error) { return []byte(cases[i].builtinKernel), nil }, }, }