func (lkct LinuxKernelCompatTester) IsCompatible() error { // Check for the required sysctls. We don't care about the value, just // that it exists. If this Proxier is chosen, we'll initialize it as we // need. _, err := utilsysctl.GetSysctl(sysctlRouteLocalnet) return err }
// setupKernelTunables validates kernel tunable flags are set as expected // depending upon the specified option, it will either warn, error, or modify the kernel tunable flags func setupKernelTunables(option KernelTunableBehavior) error { desiredState := map[string]int{ utilsysctl.VmOvercommitMemory: utilsysctl.VmOvercommitMemoryAlways, utilsysctl.VmPanicOnOOM: utilsysctl.VmPanicOnOOMInvokeOOMKiller, utilsysctl.KernelPanic: utilsysctl.KernelPanicRebootTimeout, utilsysctl.KernelPanicOnOops: utilsysctl.KernelPanicOnOopsAlways, } errList := []error{} for flag, expectedValue := range desiredState { val, err := utilsysctl.GetSysctl(flag) if err != nil { errList = append(errList, err) continue } if val == expectedValue { continue } switch option { case KernelTunableError: errList = append(errList, fmt.Errorf("Invalid kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val)) case KernelTunableWarn: glog.V(2).Infof("Invalid kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val) case KernelTunableModify: glog.V(2).Infof("Updating kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val) err = utilsysctl.SetSysctl(flag, expectedValue) if err != nil { errList = append(errList, err) } } } return utilerrors.NewAggregate(errList) }
// ShouldUseIptablesProxier returns true if we should use the iptables Proxier // instead of the "classic" userspace Proxier. This is determined by checking // the iptables version and for the existence of kernel features. It may return // an error if it fails to get the iptables version without error, in which // case it will also return false. func ShouldUseIptablesProxier() (bool, error) { exec := utilexec.New() minVersion, err := semver.NewVersion(iptablesMinVersion) if err != nil { return false, err } // returns "X.X.X", err versionString, err := utiliptables.GetIptablesVersionString(exec) if err != nil { return false, err } version, err := semver.NewVersion(versionString) if err != nil { return false, err } if version.LessThan(*minVersion) { return false, nil } // Check for the required sysctls. We don't care about the value, just // that it exists. If this Proxier is chosen, we'll iniialize it as we // need. _, err = utilsysctl.GetSysctl(sysctlRouteLocalnet) if err != nil { return false, err } return true, nil }
// CanUseIptablesProxier returns true if we should use the iptables Proxier // instead of the "classic" userspace Proxier. This is determined by checking // the iptables version and for the existence of kernel features. It may return // an error if it fails to get the iptables version without error, in which // case it will also return false. func CanUseIptablesProxier(iptver IptablesVersioner) (bool, error) { minVersion, err := semver.NewVersion(iptablesMinVersion) if err != nil { return false, err } // returns "X.Y.Z" versionString, err := iptver.GetVersion() if err != nil { return false, err } version, err := semver.NewVersion(versionString) if err != nil { return false, err } if version.LessThan(*minVersion) { return false, nil } // Check for the required sysctls. We don't care about the value, just // that it exists. If this Proxier is chosen, we'll iniialize it as we // need. // TODO: we should inject a sysctl.Interface like we do for iptables _, err = utilsysctl.GetSysctl(sysctlRouteLocalnet) if err != nil { return false, err } return true, nil }
// NewProxier returns a new Proxier given an iptables Interface instance. // Because of the iptables logic, it is assumed that there is only a single Proxier active on a machine. // An error will be returned if iptables fails to update or acquire the initial lock. // Once a proxier is created, it will keep iptables up to date in the background and // will not terminate if a particular iptables call fails. func NewProxier(ipt utiliptables.Interface, exec utilexec.Interface, syncPeriod time.Duration, masqueradeAll bool, masqueradeBit int, clusterCIDR string) (*Proxier, error) { // Set the route_localnet sysctl we need for if err := utilsysctl.SetSysctl(sysctlRouteLocalnet, 1); err != nil { return nil, fmt.Errorf("can't set sysctl %s: %v", sysctlRouteLocalnet, err) } // Proxy needs br_netfilter and bridge-nf-call-iptables=1 when containers // are connected to a Linux bridge (but not SDN bridges). Until most // plugins handle this, log when config is missing if val, err := utilsysctl.GetSysctl(sysctlBridgeCallIptables); err == nil && val != 1 { glog.Infof("missing br-netfilter module or unset sysctl br-nf-call-iptables; proxy may not work as intended") } // Generate the masquerade mark to use for SNAT rules. if masqueradeBit < 0 || masqueradeBit > 31 { return nil, fmt.Errorf("invalid iptables-masquerade-bit %v not in [0, 31]", masqueradeBit) } masqueradeValue := 1 << uint(masqueradeBit) masqueradeMark := fmt.Sprintf("%#08x/%#08x", masqueradeValue, masqueradeValue) return &Proxier{ serviceMap: make(map[proxy.ServicePortName]*serviceInfo), endpointsMap: make(map[proxy.ServicePortName][]string), portsMap: make(map[localPort]closeable), syncPeriod: syncPeriod, iptables: ipt, masqueradeAll: masqueradeAll, masqueradeMark: masqueradeMark, exec: exec, clusterCIDR: clusterCIDR, }, nil }
// sysctlSomaxconn returns the value of net.core.somaxconn, i.e. // maximum number of connections that can be queued for acceptance // http://nginx.org/en/docs/http/ngx_http_core_module.html#listen func sysctlSomaxconn() int { maxConns, err := sysctl.GetSysctl("net.core.somaxconn") if err != nil || maxConns < 512 { glog.Warningf("system net.core.somaxconn=%v. Using NGINX default (511)", maxConns) return 511 } return maxConns }
// disableKernelMemoryOvercommitHandling tells the kernel to perform no memory over-commit handling. // Under this setting, the potential for memory overload is increased, but so is performance for // memory-intensive tasks // sets /proc/sys/vm/overcommit_memory to 1 func disableKernelMemoryOvercommitHandling() error { val, err := utilsysctl.GetSysctl(sysctlVmOvercommitMemory) if err != nil { return err } if val == 1 { return nil } glog.V(2).Infof("Updating kernel memory overcommit flag from %v to %v", val, 1) err = utilsysctl.SetSysctl(sysctlVmOvercommitMemory, 1) if err != nil { return err } return nil }