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.
This commit is contained in:
Yuxiang Zhu 2017-09-25 12:58:35 +08:00
parent 7f9f847ce9
commit 74a69d8e07

View File

@ -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
}