From 74a69d8e079852d8e28dbd12efb50347eb359fb9 Mon Sep 17 00:00:00 2001 From: Yuxiang Zhu Date: Mon, 25 Sep 2017 12:58:35 +0800 Subject: [PATCH] kube-proxy IPVS: Fix IPVS availability check The current implementation of `CanUseIPVSProxier()` reads `/proc/modules` to check whether IPVS related kernel modules can be loaded. You might get a false-negative when the kernel modules are installed to the system but haven't been loaded into the kernel. This patch firstly try to run `modprobe` to load specified kernel modules, then just log warnings if error occured. Secondly, it will check loaded kernel modules by reading `/proc/modules`, return an error if any required module is missing. This change will not break the compatability of existing implementation. Running kube-proxy in a container without mounting `/lib/modules` will cause `modprobe` warnings, but not raise an error if all required modules are present in the host kernel. --- pkg/proxy/ipvs/proxier.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/proxy/ipvs/proxier.go b/pkg/proxy/ipvs/proxier.go index 12b0bb93590..87353b8443c 100644 --- a/pkg/proxy/ipvs/proxier.go +++ b/pkg/proxy/ipvs/proxier.go @@ -649,10 +649,19 @@ func (em proxyEndpointsMap) unmerge(other proxyEndpointsMap) { } // CanUseIPVSProxier returns true if we can use the ipvs Proxier. -// This is determined by checking if all the required kernel modules are loaded. It may +// This is determined by checking if all the required kernel modules can be loaded. It may // return an error if it fails to get the kernel modules information without error, in which // case it will also return false. func CanUseIPVSProxier() (bool, error) { + // Try to load IPVS required kernel modules using modprobe + for _, kmod := range ipvsModules { + err := utilexec.New().Command("modprobe", "--", kmod).Run() + if err != nil { + glog.Warningf("Failed to load kernel module %v with modprobe. "+ + "You can ignore this message when kube-proxy is running inside container without mounting /lib/modules", kmod) + } + } + // Find out loaded kernel modules out, err := utilexec.New().Command("cut", "-f1", "-d", " ", "/proc/modules").CombinedOutput() if err != nil { @@ -666,7 +675,7 @@ func CanUseIPVSProxier() (bool, error) { loadModules.Insert(mods...) modules := wantModules.Difference(loadModules).List() if len(modules) != 0 { - return false, fmt.Errorf("Failed to load kernel modules: %v", modules) + return false, fmt.Errorf("IPVS proxier will not be used because the following required kernel modules are not loaded: %v", modules) } return true, nil }