test for and set route_localnet sysctl

This commit is contained in:
Tim Hockin 2015-08-14 22:15:12 -07:00
parent f1a48574a6
commit 9cf33772b4

View File

@ -25,7 +25,9 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/base32" "encoding/base32"
"fmt" "fmt"
"io/ioutil"
"net" "net"
"path"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
@ -60,10 +62,11 @@ const iptablesNodePortsChain utiliptables.Chain = "KUBE-NODEPORTS"
// the mark we apply to traffic needing SNAT // the mark we apply to traffic needing SNAT
const iptablesMasqueradeMark = "0x4d415351" const iptablesMasqueradeMark = "0x4d415351"
// ShouldUseIptablesProxier returns true if we should use the iptables Proxier instead of // ShouldUseIptablesProxier returns true if we should use the iptables Proxier
// the userspace Proxier. // instead of the "classic" userspace Proxier. This is determined by checking
// This is determined by the iptables version. It may return an erorr if it fails to get the // the iptables version and for the existence of kernel features. It may return
// itpables version without error, in which case it will also return false. // an error if it fails to get the itpables version without error, in which
// case it will also return false.
func ShouldUseIptablesProxier() (bool, error) { func ShouldUseIptablesProxier() (bool, error) {
exec := utilexec.New() exec := utilexec.New()
minVersion, err := semver.NewVersion(IPTABLES_MIN_VERSION) minVersion, err := semver.NewVersion(IPTABLES_MIN_VERSION)
@ -80,7 +83,38 @@ func ShouldUseIptablesProxier() (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
return !version.LessThan(*minVersion), nil 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 = getSysctl(sysctlRouteLocalnet)
if err != nil {
return false, err
}
return true, nil
}
const sysctlBase = "/proc/sys"
const sysctlRouteLocalnet = "net/ipv4/conf/all/route_localnet"
func getSysctl(sysctl string) (int, error) {
data, err := ioutil.ReadFile(path.Join(sysctlBase, sysctl))
if err != nil {
return -1, err
}
val, err := strconv.Atoi(strings.Trim(string(data), " \n"))
if err != nil {
return -1, err
}
return val, nil
}
func setSysctl(sysctl string, newVal int) error {
return ioutil.WriteFile(path.Join(sysctlBase, sysctl), []byte(strconv.Itoa(newVal)), 0640)
} }
// internal struct for string service information // internal struct for string service information
@ -128,6 +162,12 @@ func NewProxier(ipt utiliptables.Interface, syncPeriod time.Duration) (*Proxier,
glog.V(2).Info("Tearing down userspace rules. Errors here are acceptable.") glog.V(2).Info("Tearing down userspace rules. Errors here are acceptable.")
// remove iptables rules/chains from the userspace Proxier // remove iptables rules/chains from the userspace Proxier
tearDownUserspaceIptables(ipt) tearDownUserspaceIptables(ipt)
// Set the route_localnet sysctl we need for
if err := setSysctl(sysctlRouteLocalnet, 1); err != nil {
return nil, fmt.Errorf("can't set sysctl route_localnet: %v", err)
}
return &Proxier{ return &Proxier{
serviceMap: make(map[proxy.ServicePortName]*serviceInfo), serviceMap: make(map[proxy.ServicePortName]*serviceInfo),
syncPeriod: syncPeriod, syncPeriod: syncPeriod,