mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	implement ipvs mode of kube-proxy
Conflicts: pkg/util/ipvs/ipvs_unsupported.go
This commit is contained in:
		@@ -21,4 +21,5 @@ CROSS_BUILD_COPY qemu-ARCH-static /usr/bin/
 | 
				
			|||||||
RUN clean-install \
 | 
					RUN clean-install \
 | 
				
			||||||
    iptables \
 | 
					    iptables \
 | 
				
			||||||
    ebtables \
 | 
					    ebtables \
 | 
				
			||||||
    conntrack
 | 
					    conntrack \
 | 
				
			||||||
 | 
					    module-init-tools
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ go_library(
 | 
				
			|||||||
        "//pkg/apis/componentconfig/v1alpha1:go_default_library",
 | 
					        "//pkg/apis/componentconfig/v1alpha1:go_default_library",
 | 
				
			||||||
        "//pkg/client/clientset_generated/internalclientset:go_default_library",
 | 
					        "//pkg/client/clientset_generated/internalclientset:go_default_library",
 | 
				
			||||||
        "//pkg/client/informers/informers_generated/internalversion:go_default_library",
 | 
					        "//pkg/client/informers/informers_generated/internalversion:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/features:go_default_library",
 | 
				
			||||||
        "//pkg/kubectl/cmd/util:go_default_library",
 | 
					        "//pkg/kubectl/cmd/util:go_default_library",
 | 
				
			||||||
        "//pkg/kubelet/qos:go_default_library",
 | 
					        "//pkg/kubelet/qos:go_default_library",
 | 
				
			||||||
        "//pkg/master/ports:go_default_library",
 | 
					        "//pkg/master/ports:go_default_library",
 | 
				
			||||||
@@ -25,11 +26,13 @@ go_library(
 | 
				
			|||||||
        "//pkg/proxy/config:go_default_library",
 | 
					        "//pkg/proxy/config:go_default_library",
 | 
				
			||||||
        "//pkg/proxy/healthcheck:go_default_library",
 | 
					        "//pkg/proxy/healthcheck:go_default_library",
 | 
				
			||||||
        "//pkg/proxy/iptables:go_default_library",
 | 
					        "//pkg/proxy/iptables:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/proxy/ipvs:go_default_library",
 | 
				
			||||||
        "//pkg/proxy/userspace:go_default_library",
 | 
					        "//pkg/proxy/userspace:go_default_library",
 | 
				
			||||||
        "//pkg/proxy/winuserspace:go_default_library",
 | 
					        "//pkg/proxy/winuserspace:go_default_library",
 | 
				
			||||||
        "//pkg/util/configz:go_default_library",
 | 
					        "//pkg/util/configz:go_default_library",
 | 
				
			||||||
        "//pkg/util/dbus:go_default_library",
 | 
					        "//pkg/util/dbus:go_default_library",
 | 
				
			||||||
        "//pkg/util/iptables:go_default_library",
 | 
					        "//pkg/util/iptables:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/util/ipvs:go_default_library",
 | 
				
			||||||
        "//pkg/util/mount:go_default_library",
 | 
					        "//pkg/util/mount:go_default_library",
 | 
				
			||||||
        "//pkg/util/netsh:go_default_library",
 | 
					        "//pkg/util/netsh:go_default_library",
 | 
				
			||||||
        "//pkg/util/node:go_default_library",
 | 
					        "//pkg/util/node:go_default_library",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,11 +58,13 @@ import (
 | 
				
			|||||||
	proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
 | 
						proxyconfig "k8s.io/kubernetes/pkg/proxy/config"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/proxy/healthcheck"
 | 
						"k8s.io/kubernetes/pkg/proxy/healthcheck"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/proxy/iptables"
 | 
						"k8s.io/kubernetes/pkg/proxy/iptables"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/proxy/ipvs"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/proxy/userspace"
 | 
						"k8s.io/kubernetes/pkg/proxy/userspace"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/proxy/winuserspace"
 | 
						"k8s.io/kubernetes/pkg/proxy/winuserspace"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/configz"
 | 
						"k8s.io/kubernetes/pkg/util/configz"
 | 
				
			||||||
	utildbus "k8s.io/kubernetes/pkg/util/dbus"
 | 
						utildbus "k8s.io/kubernetes/pkg/util/dbus"
 | 
				
			||||||
	utiliptables "k8s.io/kubernetes/pkg/util/iptables"
 | 
						utiliptables "k8s.io/kubernetes/pkg/util/iptables"
 | 
				
			||||||
 | 
						utilipvs "k8s.io/kubernetes/pkg/util/ipvs"
 | 
				
			||||||
	utilnetsh "k8s.io/kubernetes/pkg/util/netsh"
 | 
						utilnetsh "k8s.io/kubernetes/pkg/util/netsh"
 | 
				
			||||||
	utilnode "k8s.io/kubernetes/pkg/util/node"
 | 
						utilnode "k8s.io/kubernetes/pkg/util/node"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/oom"
 | 
						"k8s.io/kubernetes/pkg/util/oom"
 | 
				
			||||||
@@ -76,17 +78,19 @@ import (
 | 
				
			|||||||
	"github.com/prometheus/client_golang/prometheus"
 | 
						"github.com/prometheus/client_golang/prometheus"
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
	"github.com/spf13/pflag"
 | 
						"github.com/spf13/pflag"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	proxyModeUserspace = "userspace"
 | 
						proxyModeUserspace = "userspace"
 | 
				
			||||||
	proxyModeIPTables  = "iptables"
 | 
						proxyModeIPTables  = "iptables"
 | 
				
			||||||
 | 
						proxyModeIPVS      = "ipvs"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// checkKnownProxyMode returns true if proxyMode is valid.
 | 
					// checkKnownProxyMode returns true if proxyMode is valid.
 | 
				
			||||||
func checkKnownProxyMode(proxyMode string) bool {
 | 
					func checkKnownProxyMode(proxyMode string) bool {
 | 
				
			||||||
	switch proxyMode {
 | 
						switch proxyMode {
 | 
				
			||||||
	case "", proxyModeUserspace, proxyModeIPTables:
 | 
						case "", proxyModeUserspace, proxyModeIPTables, proxyModeIPVS:
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
@@ -122,7 +126,8 @@ type Options struct {
 | 
				
			|||||||
func AddFlags(options *Options, fs *pflag.FlagSet) {
 | 
					func AddFlags(options *Options, fs *pflag.FlagSet) {
 | 
				
			||||||
	fs.StringVar(&options.ConfigFile, "config", options.ConfigFile, "The path to the configuration file.")
 | 
						fs.StringVar(&options.ConfigFile, "config", options.ConfigFile, "The path to the configuration file.")
 | 
				
			||||||
	fs.StringVar(&options.WriteConfigTo, "write-config-to", options.WriteConfigTo, "If set, write the default configuration values to this file and exit.")
 | 
						fs.StringVar(&options.WriteConfigTo, "write-config-to", options.WriteConfigTo, "If set, write the default configuration values to this file and exit.")
 | 
				
			||||||
	fs.BoolVar(&options.CleanupAndExit, "cleanup-iptables", options.CleanupAndExit, "If true, cleanup iptables rules and exit.")
 | 
						fs.MarkDeprecated("cleanup-iptables", "This flag is replaced by cleanup-proxyrules.")
 | 
				
			||||||
 | 
						fs.BoolVar(&options.CleanupAndExit, "cleanup", options.CleanupAndExit, "If true cleanup iptables and ipvs rules and exit.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// All flags below here are deprecated and will eventually be removed.
 | 
						// All flags below here are deprecated and will eventually be removed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -137,10 +142,12 @@ func AddFlags(options *Options, fs *pflag.FlagSet) {
 | 
				
			|||||||
	fs.StringVar(&options.config.ClientConnection.KubeConfigFile, "kubeconfig", options.config.ClientConnection.KubeConfigFile, "Path to kubeconfig file with authorization information (the master location is set by the master flag).")
 | 
						fs.StringVar(&options.config.ClientConnection.KubeConfigFile, "kubeconfig", options.config.ClientConnection.KubeConfigFile, "Path to kubeconfig file with authorization information (the master location is set by the master flag).")
 | 
				
			||||||
	fs.Var(componentconfig.PortRangeVar{Val: &options.config.PortRange}, "proxy-port-range", "Range of host ports (beginPort-endPort, inclusive) that may be consumed in order to proxy service traffic. If unspecified (0-0) then ports will be randomly chosen.")
 | 
						fs.Var(componentconfig.PortRangeVar{Val: &options.config.PortRange}, "proxy-port-range", "Range of host ports (beginPort-endPort, inclusive) that may be consumed in order to proxy service traffic. If unspecified (0-0) then ports will be randomly chosen.")
 | 
				
			||||||
	fs.StringVar(&options.config.HostnameOverride, "hostname-override", options.config.HostnameOverride, "If non-empty, will use this string as identification instead of the actual hostname.")
 | 
						fs.StringVar(&options.config.HostnameOverride, "hostname-override", options.config.HostnameOverride, "If non-empty, will use this string as identification instead of the actual hostname.")
 | 
				
			||||||
	fs.Var(&options.config.Mode, "proxy-mode", "Which proxy mode to use: 'userspace' (older) or 'iptables' (faster). If blank, use the best-available proxy (currently iptables).  If the iptables proxy is selected, regardless of how, but the system's kernel or iptables versions are insufficient, this always falls back to the userspace proxy.")
 | 
						fs.Var(&options.config.Mode, "proxy-mode", "Which proxy mode to use: 'userspace' (older) or 'iptables' (faster) or 'ipvs'(experimental). If blank, use the best-available proxy (currently iptables).  If the iptables proxy is selected, regardless of how, but the system's kernel or iptables versions are insufficient, this always falls back to the userspace proxy.")
 | 
				
			||||||
	fs.Int32Var(options.config.IPTables.MasqueradeBit, "iptables-masquerade-bit", utilpointer.Int32PtrDerefOr(options.config.IPTables.MasqueradeBit, 14), "If using the pure iptables proxy, the bit of the fwmark space to mark packets requiring SNAT with.  Must be within the range [0, 31].")
 | 
						fs.Int32Var(options.config.IPTables.MasqueradeBit, "iptables-masquerade-bit", utilpointer.Int32PtrDerefOr(options.config.IPTables.MasqueradeBit, 14), "If using the pure iptables proxy, the bit of the fwmark space to mark packets requiring SNAT with.  Must be within the range [0, 31].")
 | 
				
			||||||
	fs.DurationVar(&options.config.IPTables.SyncPeriod.Duration, "iptables-sync-period", options.config.IPTables.SyncPeriod.Duration, "The maximum interval of how often iptables rules are refreshed (e.g. '5s', '1m', '2h22m').  Must be greater than 0.")
 | 
						fs.DurationVar(&options.config.IPTables.SyncPeriod.Duration, "iptables-sync-period", options.config.IPTables.SyncPeriod.Duration, "The maximum interval of how often iptables rules are refreshed (e.g. '5s', '1m', '2h22m').  Must be greater than 0.")
 | 
				
			||||||
	fs.DurationVar(&options.config.IPTables.MinSyncPeriod.Duration, "iptables-min-sync-period", options.config.IPTables.MinSyncPeriod.Duration, "The minimum interval of how often the iptables rules can be refreshed as endpoints and services change (e.g. '5s', '1m', '2h22m').")
 | 
						fs.DurationVar(&options.config.IPTables.MinSyncPeriod.Duration, "iptables-min-sync-period", options.config.IPTables.MinSyncPeriod.Duration, "The minimum interval of how often the iptables rules can be refreshed as endpoints and services change (e.g. '5s', '1m', '2h22m').")
 | 
				
			||||||
 | 
						fs.DurationVar(&options.config.IPVS.SyncPeriod.Duration, "ipvs-sync-period", options.config.IPVS.SyncPeriod.Duration, "The maximum interval of how often ipvs rules are refreshed (e.g. '5s', '1m', '2h22m').  Must be greater than 0.")
 | 
				
			||||||
 | 
						fs.DurationVar(&options.config.IPVS.MinSyncPeriod.Duration, "ipvs-min-sync-period", options.config.IPVS.MinSyncPeriod.Duration, "The minimum interval of how often the ipvs rules can be refreshed as endpoints and services change (e.g. '5s', '1m', '2h22m').")
 | 
				
			||||||
	fs.DurationVar(&options.config.ConfigSyncPeriod.Duration, "config-sync-period", options.config.ConfigSyncPeriod.Duration, "How often configuration from the apiserver is refreshed.  Must be greater than 0.")
 | 
						fs.DurationVar(&options.config.ConfigSyncPeriod.Duration, "config-sync-period", options.config.ConfigSyncPeriod.Duration, "How often configuration from the apiserver is refreshed.  Must be greater than 0.")
 | 
				
			||||||
	fs.BoolVar(&options.config.IPTables.MasqueradeAll, "masquerade-all", options.config.IPTables.MasqueradeAll, "If using the pure iptables proxy, SNAT everything (this not commonly needed)")
 | 
						fs.BoolVar(&options.config.IPTables.MasqueradeAll, "masquerade-all", options.config.IPTables.MasqueradeAll, "If using the pure iptables proxy, SNAT everything (this not commonly needed)")
 | 
				
			||||||
	fs.StringVar(&options.config.ClusterCIDR, "cluster-cidr", options.config.ClusterCIDR, "The CIDR range of pods in the cluster. It is used to bridge traffic coming from outside of the cluster. If not provided, no off-cluster bridging will be performed.")
 | 
						fs.StringVar(&options.config.ClusterCIDR, "cluster-cidr", options.config.ClusterCIDR, "The CIDR range of pods in the cluster. It is used to bridge traffic coming from outside of the cluster. If not provided, no off-cluster bridging will be performed.")
 | 
				
			||||||
@@ -161,7 +168,7 @@ func AddFlags(options *Options, fs *pflag.FlagSet) {
 | 
				
			|||||||
		options.config.Conntrack.TCPCloseWaitTimeout.Duration,
 | 
							options.config.Conntrack.TCPCloseWaitTimeout.Duration,
 | 
				
			||||||
		"NAT timeout for TCP connections in the CLOSE_WAIT state")
 | 
							"NAT timeout for TCP connections in the CLOSE_WAIT state")
 | 
				
			||||||
	fs.BoolVar(&options.config.EnableProfiling, "profiling", options.config.EnableProfiling, "If true enables profiling via web interface on /debug/pprof handler.")
 | 
						fs.BoolVar(&options.config.EnableProfiling, "profiling", options.config.EnableProfiling, "If true enables profiling via web interface on /debug/pprof handler.")
 | 
				
			||||||
 | 
						fs.StringVar(&options.config.IPVS.Scheduler, "ipvs-scheduler", options.config.IPVS.Scheduler, "The ipvs scheduler type when proxy mode is ipvs")
 | 
				
			||||||
	utilfeature.DefaultFeatureGate.AddFlag(fs)
 | 
						utilfeature.DefaultFeatureGate.AddFlag(fs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -187,7 +194,7 @@ func NewOptions() (*Options, error) {
 | 
				
			|||||||
// Complete completes all the required options.
 | 
					// Complete completes all the required options.
 | 
				
			||||||
func (o *Options) Complete() error {
 | 
					func (o *Options) Complete() error {
 | 
				
			||||||
	if len(o.ConfigFile) == 0 && len(o.WriteConfigTo) == 0 {
 | 
						if len(o.ConfigFile) == 0 && len(o.WriteConfigTo) == 0 {
 | 
				
			||||||
		glog.Warning("WARNING: all flags other than --config, --write-config-to, and --cleanup-iptables are deprecated. Please begin using a config file ASAP.")
 | 
							glog.Warning("WARNING: all flags other than --config, --write-config-to, and --cleanup are deprecated. Please begin using a config file ASAP.")
 | 
				
			||||||
		o.applyDeprecatedHealthzPortToConfig()
 | 
							o.applyDeprecatedHealthzPortToConfig()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -363,6 +370,8 @@ type ProxyServer struct {
 | 
				
			|||||||
	Client                 clientset.Interface
 | 
						Client                 clientset.Interface
 | 
				
			||||||
	EventClient            v1core.EventsGetter
 | 
						EventClient            v1core.EventsGetter
 | 
				
			||||||
	IptInterface           utiliptables.Interface
 | 
						IptInterface           utiliptables.Interface
 | 
				
			||||||
 | 
						IpvsInterface          utilipvs.Interface
 | 
				
			||||||
 | 
						execer                 exec.Interface
 | 
				
			||||||
	Proxier                proxy.ProxyProvider
 | 
						Proxier                proxy.ProxyProvider
 | 
				
			||||||
	Broadcaster            record.EventBroadcaster
 | 
						Broadcaster            record.EventBroadcaster
 | 
				
			||||||
	Recorder               record.EventRecorder
 | 
						Recorder               record.EventRecorder
 | 
				
			||||||
@@ -435,6 +444,7 @@ func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndEx
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	var netshInterface utilnetsh.Interface
 | 
						var netshInterface utilnetsh.Interface
 | 
				
			||||||
	var iptInterface utiliptables.Interface
 | 
						var iptInterface utiliptables.Interface
 | 
				
			||||||
 | 
						var ipvsInterface utilipvs.Interface
 | 
				
			||||||
	var dbus utildbus.Interface
 | 
						var dbus utildbus.Interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create a iptables utils.
 | 
						// Create a iptables utils.
 | 
				
			||||||
@@ -445,11 +455,12 @@ func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndEx
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		dbus = utildbus.New()
 | 
							dbus = utildbus.New()
 | 
				
			||||||
		iptInterface = utiliptables.New(execer, dbus, protocol)
 | 
							iptInterface = utiliptables.New(execer, dbus, protocol)
 | 
				
			||||||
 | 
							ipvsInterface = utilipvs.New(execer)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// We omit creation of pretty much everything if we run in cleanup mode
 | 
						// We omit creation of pretty much everything if we run in cleanup mode
 | 
				
			||||||
	if cleanupAndExit {
 | 
						if cleanupAndExit {
 | 
				
			||||||
		return &ProxyServer{IptInterface: iptInterface, CleanupAndExit: cleanupAndExit}, nil
 | 
							return &ProxyServer{IptInterface: iptInterface, IpvsInterface: ipvsInterface, CleanupAndExit: cleanupAndExit}, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	client, eventClient, err := createClients(config.ClientConnection, master)
 | 
						client, eventClient, err := createClients(config.ClientConnection, master)
 | 
				
			||||||
@@ -517,9 +528,40 @@ func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndEx
 | 
				
			|||||||
		serviceEventHandler = proxierIPTables
 | 
							serviceEventHandler = proxierIPTables
 | 
				
			||||||
		endpointsEventHandler = proxierIPTables
 | 
							endpointsEventHandler = proxierIPTables
 | 
				
			||||||
		// No turning back. Remove artifacts that might still exist from the userspace Proxier.
 | 
							// No turning back. Remove artifacts that might still exist from the userspace Proxier.
 | 
				
			||||||
		glog.V(0).Info("Tearing down userspace rules.")
 | 
							glog.V(0).Info("Tearing down inactive rules.")
 | 
				
			||||||
		// TODO this has side effects that should only happen when Run() is invoked.
 | 
							// TODO this has side effects that should only happen when Run() is invoked.
 | 
				
			||||||
		userspace.CleanupLeftovers(iptInterface)
 | 
							userspace.CleanupLeftovers(iptInterface)
 | 
				
			||||||
 | 
							// IPVS Proxier will generate some iptables rules,
 | 
				
			||||||
 | 
							// need to clean them before switching to other proxy mode.
 | 
				
			||||||
 | 
							ipvs.CleanupLeftovers(execer, ipvsInterface, iptInterface)
 | 
				
			||||||
 | 
						} else if proxyMode == proxyModeIPVS {
 | 
				
			||||||
 | 
							glog.V(0).Info("Using ipvs Proxier.")
 | 
				
			||||||
 | 
							proxierIPVS, err := ipvs.NewProxier(
 | 
				
			||||||
 | 
								iptInterface,
 | 
				
			||||||
 | 
								ipvsInterface,
 | 
				
			||||||
 | 
								utilsysctl.New(),
 | 
				
			||||||
 | 
								execer,
 | 
				
			||||||
 | 
								config.IPVS.SyncPeriod.Duration,
 | 
				
			||||||
 | 
								config.IPVS.MinSyncPeriod.Duration,
 | 
				
			||||||
 | 
								config.IPTables.MasqueradeAll,
 | 
				
			||||||
 | 
								int(*config.IPTables.MasqueradeBit),
 | 
				
			||||||
 | 
								config.ClusterCIDR,
 | 
				
			||||||
 | 
								hostname,
 | 
				
			||||||
 | 
								getNodeIP(client, hostname),
 | 
				
			||||||
 | 
								recorder,
 | 
				
			||||||
 | 
								healthzServer,
 | 
				
			||||||
 | 
								config.IPVS.Scheduler,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("unable to create proxier: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							proxier = proxierIPVS
 | 
				
			||||||
 | 
							serviceEventHandler = proxierIPVS
 | 
				
			||||||
 | 
							endpointsEventHandler = proxierIPVS
 | 
				
			||||||
 | 
							glog.V(0).Info("Tearing down inactive rules.")
 | 
				
			||||||
 | 
							// TODO this has side effects that should only happen when Run() is invoked.
 | 
				
			||||||
 | 
							userspace.CleanupLeftovers(iptInterface)
 | 
				
			||||||
 | 
							iptables.CleanupLeftovers(iptInterface)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		glog.V(0).Info("Using userspace Proxier.")
 | 
							glog.V(0).Info("Using userspace Proxier.")
 | 
				
			||||||
		if goruntime.GOOS == "windows" {
 | 
							if goruntime.GOOS == "windows" {
 | 
				
			||||||
@@ -566,11 +608,14 @@ func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndEx
 | 
				
			|||||||
			serviceEventHandler = proxierUserspace
 | 
								serviceEventHandler = proxierUserspace
 | 
				
			||||||
			proxier = proxierUserspace
 | 
								proxier = proxierUserspace
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Remove artifacts from the pure-iptables Proxier, if not on Windows.
 | 
							// Remove artifacts from the iptables and ipvs Proxier, if not on Windows.
 | 
				
			||||||
		if goruntime.GOOS != "windows" {
 | 
							if goruntime.GOOS != "windows" {
 | 
				
			||||||
			glog.V(0).Info("Tearing down pure-iptables proxy rules.")
 | 
								glog.V(0).Info("Tearing down inactive rules.")
 | 
				
			||||||
			// TODO this has side effects that should only happen when Run() is invoked.
 | 
								// TODO this has side effects that should only happen when Run() is invoked.
 | 
				
			||||||
			iptables.CleanupLeftovers(iptInterface)
 | 
								iptables.CleanupLeftovers(iptInterface)
 | 
				
			||||||
 | 
								// IPVS Proxier will generate some iptables rules,
 | 
				
			||||||
 | 
								// need to clean them before switching to other proxy mode.
 | 
				
			||||||
 | 
								ipvs.CleanupLeftovers(execer, ipvsInterface, iptInterface)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -583,6 +628,8 @@ func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndEx
 | 
				
			|||||||
		Client:                 client,
 | 
							Client:                 client,
 | 
				
			||||||
		EventClient:            eventClient,
 | 
							EventClient:            eventClient,
 | 
				
			||||||
		IptInterface:           iptInterface,
 | 
							IptInterface:           iptInterface,
 | 
				
			||||||
 | 
							IpvsInterface:          ipvsInterface,
 | 
				
			||||||
 | 
							execer:                 execer,
 | 
				
			||||||
		Proxier:                proxier,
 | 
							Proxier:                proxier,
 | 
				
			||||||
		Broadcaster:            eventBroadcaster,
 | 
							Broadcaster:            eventBroadcaster,
 | 
				
			||||||
		Recorder:               recorder,
 | 
							Recorder:               recorder,
 | 
				
			||||||
@@ -607,6 +654,7 @@ func (s *ProxyServer) Run() error {
 | 
				
			|||||||
	if s.CleanupAndExit {
 | 
						if s.CleanupAndExit {
 | 
				
			||||||
		encounteredError := userspace.CleanupLeftovers(s.IptInterface)
 | 
							encounteredError := userspace.CleanupLeftovers(s.IptInterface)
 | 
				
			||||||
		encounteredError = iptables.CleanupLeftovers(s.IptInterface) || encounteredError
 | 
							encounteredError = iptables.CleanupLeftovers(s.IptInterface) || encounteredError
 | 
				
			||||||
 | 
							encounteredError = ipvs.CleanupLeftovers(s.execer, s.IpvsInterface, s.IptInterface) || encounteredError
 | 
				
			||||||
		if encounteredError {
 | 
							if encounteredError {
 | 
				
			||||||
			return errors.New("encountered an error while tearing down rules.")
 | 
								return errors.New("encountered an error while tearing down rules.")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -754,10 +802,38 @@ func getProxyMode(proxyMode string, iptver iptables.IPTablesVersioner, kcompat i
 | 
				
			|||||||
		return proxyModeUserspace
 | 
							return proxyModeUserspace
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(proxyMode) > 0 && proxyMode != proxyModeIPTables {
 | 
						if len(proxyMode) > 0 && proxyMode == proxyModeIPTables {
 | 
				
			||||||
		glog.Warningf("Flag proxy-mode=%q unknown, assuming iptables proxy", proxyMode)
 | 
							return tryIPTablesProxy(iptver, kcompat)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if utilfeature.DefaultFeatureGate.Enabled(features.SupportIPVSProxyMode) {
 | 
				
			||||||
 | 
							if proxyMode == proxyModeIPVS {
 | 
				
			||||||
 | 
								return tryIPVSProxy(iptver, kcompat)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								glog.Warningf("Can't use ipvs proxier, trying iptables proxier")
 | 
				
			||||||
 | 
								return tryIPTablesProxy(iptver, kcompat)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Warningf("Flag proxy-mode=%q unknown, assuming iptables proxy", proxyMode)
 | 
				
			||||||
 | 
						return tryIPTablesProxy(iptver, kcompat)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func tryIPVSProxy(iptver iptables.IPTablesVersioner, kcompat iptables.KernelCompatTester) string {
 | 
				
			||||||
 | 
						// guaranteed false on error, error only necessary for debugging
 | 
				
			||||||
 | 
						// IPVS Proxier relies on iptables
 | 
				
			||||||
 | 
						useIPVSProxy, err := ipvs.CanUseIPVSProxier()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							utilruntime.HandleError(fmt.Errorf("can't determine whether to use ipvs proxy, using userspace proxier: %v", err))
 | 
				
			||||||
 | 
							return proxyModeUserspace
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if useIPVSProxy {
 | 
				
			||||||
 | 
							return proxyModeIPVS
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: Check ipvs version
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to fallback to iptables before falling back to userspace
 | 
				
			||||||
 | 
						glog.V(1).Infof("Can't use ipvs proxier, trying iptables proxier")
 | 
				
			||||||
	return tryIPTablesProxy(iptver, kcompat)
 | 
						return tryIPTablesProxy(iptver, kcompat)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -287,6 +287,9 @@ iptables:
 | 
				
			|||||||
  masqueradeBit: 17
 | 
					  masqueradeBit: 17
 | 
				
			||||||
  minSyncPeriod: 10s
 | 
					  minSyncPeriod: 10s
 | 
				
			||||||
  syncPeriod: 60s
 | 
					  syncPeriod: 60s
 | 
				
			||||||
 | 
					ipvs:
 | 
				
			||||||
 | 
					  minSyncPeriod: 10s
 | 
				
			||||||
 | 
					  syncPeriod: 60s
 | 
				
			||||||
kind: KubeProxyConfiguration
 | 
					kind: KubeProxyConfiguration
 | 
				
			||||||
metricsBindAddress: "%s"
 | 
					metricsBindAddress: "%s"
 | 
				
			||||||
mode: "iptables"
 | 
					mode: "iptables"
 | 
				
			||||||
@@ -347,8 +350,13 @@ udpTimeoutMilliseconds: 123ms
 | 
				
			|||||||
				MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
 | 
									MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
 | 
				
			||||||
				SyncPeriod:    metav1.Duration{Duration: 60 * time.Second},
 | 
									SyncPeriod:    metav1.Duration{Duration: 60 * time.Second},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 | 
								IPVS: componentconfig.KubeProxyIPVSConfiguration{
 | 
				
			||||||
 | 
									MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
 | 
				
			||||||
 | 
									SyncPeriod:    metav1.Duration{Duration: 60 * time.Second},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
			MetricsBindAddress: tc.metricsBindAddress,
 | 
								MetricsBindAddress: tc.metricsBindAddress,
 | 
				
			||||||
			Mode:               "iptables",
 | 
								Mode:               "iptables",
 | 
				
			||||||
 | 
								// TODO: IPVS
 | 
				
			||||||
			OOMScoreAdj:       utilpointer.Int32Ptr(17),
 | 
								OOMScoreAdj:       utilpointer.Int32Ptr(17),
 | 
				
			||||||
			PortRange:         "2-7",
 | 
								PortRange:         "2-7",
 | 
				
			||||||
			ResourceContainer: "/foo",
 | 
								ResourceContainer: "/foo",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,19 @@ type KubeProxyIPTablesConfiguration struct {
 | 
				
			|||||||
	MinSyncPeriod metav1.Duration
 | 
						MinSyncPeriod metav1.Duration
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// KubeProxyIPVSConfiguration contains ipvs-related configuration
 | 
				
			||||||
 | 
					// details for the Kubernetes proxy server.
 | 
				
			||||||
 | 
					type KubeProxyIPVSConfiguration struct {
 | 
				
			||||||
 | 
						// syncPeriod is the period that ipvs rules are refreshed (e.g. '5s', '1m',
 | 
				
			||||||
 | 
						// '2h22m').  Must be greater than 0.
 | 
				
			||||||
 | 
						SyncPeriod metav1.Duration
 | 
				
			||||||
 | 
						// minSyncPeriod is the minimum period that ipvs rules are refreshed (e.g. '5s', '1m',
 | 
				
			||||||
 | 
						// '2h22m').
 | 
				
			||||||
 | 
						MinSyncPeriod metav1.Duration
 | 
				
			||||||
 | 
						// ipvs scheduler
 | 
				
			||||||
 | 
						Scheduler string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// KubeProxyConntrackConfiguration contains conntrack settings for
 | 
					// KubeProxyConntrackConfiguration contains conntrack settings for
 | 
				
			||||||
// the Kubernetes proxy server.
 | 
					// the Kubernetes proxy server.
 | 
				
			||||||
type KubeProxyConntrackConfiguration struct {
 | 
					type KubeProxyConntrackConfiguration struct {
 | 
				
			||||||
@@ -112,6 +125,8 @@ type KubeProxyConfiguration struct {
 | 
				
			|||||||
	ClientConnection ClientConnectionConfiguration
 | 
						ClientConnection ClientConnectionConfiguration
 | 
				
			||||||
	// iptables contains iptables-related configuration options.
 | 
						// iptables contains iptables-related configuration options.
 | 
				
			||||||
	IPTables KubeProxyIPTablesConfiguration
 | 
						IPTables KubeProxyIPTablesConfiguration
 | 
				
			||||||
 | 
						// ipvs contains ipvs-related configuration options.
 | 
				
			||||||
 | 
						IPVS KubeProxyIPVSConfiguration
 | 
				
			||||||
	// oomScoreAdj is the oom-score-adj value for kube-proxy process. Values must be within
 | 
						// oomScoreAdj is the oom-score-adj value for kube-proxy process. Values must be within
 | 
				
			||||||
	// the range [-1000, 1000]
 | 
						// the range [-1000, 1000]
 | 
				
			||||||
	OOMScoreAdj *int32
 | 
						OOMScoreAdj *int32
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,19 @@ type KubeProxyIPTablesConfiguration struct {
 | 
				
			|||||||
	MinSyncPeriod metav1.Duration `json:"minSyncPeriod"`
 | 
						MinSyncPeriod metav1.Duration `json:"minSyncPeriod"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// KubeProxyIPVSConfiguration contains ipvs-related configuration
 | 
				
			||||||
 | 
					// details for the Kubernetes proxy server.
 | 
				
			||||||
 | 
					type KubeProxyIPVSConfiguration struct {
 | 
				
			||||||
 | 
						// syncPeriod is the period that ipvs rules are refreshed (e.g. '5s', '1m',
 | 
				
			||||||
 | 
						// '2h22m').  Must be greater than 0.
 | 
				
			||||||
 | 
						SyncPeriod metav1.Duration `json:"syncPeriod"`
 | 
				
			||||||
 | 
						// minSyncPeriod is the minimum period that ipvs rules are refreshed (e.g. '5s', '1m',
 | 
				
			||||||
 | 
						// '2h22m').
 | 
				
			||||||
 | 
						MinSyncPeriod metav1.Duration `json:"minSyncPeriod"`
 | 
				
			||||||
 | 
						// ipvs scheduler
 | 
				
			||||||
 | 
						Scheduler string `json:"scheduler"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// KubeProxyConntrackConfiguration contains conntrack settings for
 | 
					// KubeProxyConntrackConfiguration contains conntrack settings for
 | 
				
			||||||
// the Kubernetes proxy server.
 | 
					// the Kubernetes proxy server.
 | 
				
			||||||
type KubeProxyConntrackConfiguration struct {
 | 
					type KubeProxyConntrackConfiguration struct {
 | 
				
			||||||
@@ -112,6 +125,8 @@ type KubeProxyConfiguration struct {
 | 
				
			|||||||
	ClientConnection ClientConnectionConfiguration `json:"clientConnection"`
 | 
						ClientConnection ClientConnectionConfiguration `json:"clientConnection"`
 | 
				
			||||||
	// iptables contains iptables-related configuration options.
 | 
						// iptables contains iptables-related configuration options.
 | 
				
			||||||
	IPTables KubeProxyIPTablesConfiguration `json:"iptables"`
 | 
						IPTables KubeProxyIPTablesConfiguration `json:"iptables"`
 | 
				
			||||||
 | 
						// ipvs contains ipvs-related configuration options.
 | 
				
			||||||
 | 
						IPVS KubeProxyIPVSConfiguration `json:"ipvs"`
 | 
				
			||||||
	// oomScoreAdj is the oom-score-adj value for kube-proxy process. Values must be within
 | 
						// oomScoreAdj is the oom-score-adj value for kube-proxy process. Values must be within
 | 
				
			||||||
	// the range [-1000, 1000]
 | 
						// the range [-1000, 1000]
 | 
				
			||||||
	OOMScoreAdj *int32 `json:"oomScoreAdj"`
 | 
						OOMScoreAdj *int32 `json:"oomScoreAdj"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
 | 
				
			|||||||
		Convert_componentconfig_KubeProxyConntrackConfiguration_To_v1alpha1_KubeProxyConntrackConfiguration,
 | 
							Convert_componentconfig_KubeProxyConntrackConfiguration_To_v1alpha1_KubeProxyConntrackConfiguration,
 | 
				
			||||||
		Convert_v1alpha1_KubeProxyIPTablesConfiguration_To_componentconfig_KubeProxyIPTablesConfiguration,
 | 
							Convert_v1alpha1_KubeProxyIPTablesConfiguration_To_componentconfig_KubeProxyIPTablesConfiguration,
 | 
				
			||||||
		Convert_componentconfig_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration,
 | 
							Convert_componentconfig_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration,
 | 
				
			||||||
 | 
							Convert_v1alpha1_KubeProxyIPVSConfiguration_To_componentconfig_KubeProxyIPVSConfiguration,
 | 
				
			||||||
 | 
							Convert_componentconfig_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration,
 | 
				
			||||||
		Convert_v1alpha1_KubeSchedulerConfiguration_To_componentconfig_KubeSchedulerConfiguration,
 | 
							Convert_v1alpha1_KubeSchedulerConfiguration_To_componentconfig_KubeSchedulerConfiguration,
 | 
				
			||||||
		Convert_componentconfig_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration,
 | 
							Convert_componentconfig_KubeSchedulerConfiguration_To_v1alpha1_KubeSchedulerConfiguration,
 | 
				
			||||||
		Convert_v1alpha1_LeaderElectionConfiguration_To_componentconfig_LeaderElectionConfiguration,
 | 
							Convert_v1alpha1_LeaderElectionConfiguration_To_componentconfig_LeaderElectionConfiguration,
 | 
				
			||||||
@@ -93,6 +95,9 @@ func autoConvert_v1alpha1_KubeProxyConfiguration_To_componentconfig_KubeProxyCon
 | 
				
			|||||||
	if err := Convert_v1alpha1_KubeProxyIPTablesConfiguration_To_componentconfig_KubeProxyIPTablesConfiguration(&in.IPTables, &out.IPTables, s); err != nil {
 | 
						if err := Convert_v1alpha1_KubeProxyIPTablesConfiguration_To_componentconfig_KubeProxyIPTablesConfiguration(&in.IPTables, &out.IPTables, s); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if err := Convert_v1alpha1_KubeProxyIPVSConfiguration_To_componentconfig_KubeProxyIPVSConfiguration(&in.IPVS, &out.IPVS, s); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	out.OOMScoreAdj = (*int32)(unsafe.Pointer(in.OOMScoreAdj))
 | 
						out.OOMScoreAdj = (*int32)(unsafe.Pointer(in.OOMScoreAdj))
 | 
				
			||||||
	out.Mode = componentconfig.ProxyMode(in.Mode)
 | 
						out.Mode = componentconfig.ProxyMode(in.Mode)
 | 
				
			||||||
	out.PortRange = in.PortRange
 | 
						out.PortRange = in.PortRange
 | 
				
			||||||
@@ -124,6 +129,9 @@ func autoConvert_componentconfig_KubeProxyConfiguration_To_v1alpha1_KubeProxyCon
 | 
				
			|||||||
	if err := Convert_componentconfig_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(&in.IPTables, &out.IPTables, s); err != nil {
 | 
						if err := Convert_componentconfig_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(&in.IPTables, &out.IPTables, s); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if err := Convert_componentconfig_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(&in.IPVS, &out.IPVS, s); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	out.OOMScoreAdj = (*int32)(unsafe.Pointer(in.OOMScoreAdj))
 | 
						out.OOMScoreAdj = (*int32)(unsafe.Pointer(in.OOMScoreAdj))
 | 
				
			||||||
	out.Mode = ProxyMode(in.Mode)
 | 
						out.Mode = ProxyMode(in.Mode)
 | 
				
			||||||
	out.PortRange = in.PortRange
 | 
						out.PortRange = in.PortRange
 | 
				
			||||||
@@ -195,6 +203,30 @@ func Convert_componentconfig_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProx
 | 
				
			|||||||
	return autoConvert_componentconfig_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(in, out, s)
 | 
						return autoConvert_componentconfig_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(in, out, s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_componentconfig_KubeProxyIPVSConfiguration(in *KubeProxyIPVSConfiguration, out *componentconfig.KubeProxyIPVSConfiguration, s conversion.Scope) error {
 | 
				
			||||||
 | 
						out.SyncPeriod = in.SyncPeriod
 | 
				
			||||||
 | 
						out.MinSyncPeriod = in.MinSyncPeriod
 | 
				
			||||||
 | 
						out.Scheduler = in.Scheduler
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Convert_v1alpha1_KubeProxyIPVSConfiguration_To_componentconfig_KubeProxyIPVSConfiguration is an autogenerated conversion function.
 | 
				
			||||||
 | 
					func Convert_v1alpha1_KubeProxyIPVSConfiguration_To_componentconfig_KubeProxyIPVSConfiguration(in *KubeProxyIPVSConfiguration, out *componentconfig.KubeProxyIPVSConfiguration, s conversion.Scope) error {
 | 
				
			||||||
 | 
						return autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_componentconfig_KubeProxyIPVSConfiguration(in, out, s)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func autoConvert_componentconfig_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in *componentconfig.KubeProxyIPVSConfiguration, out *KubeProxyIPVSConfiguration, s conversion.Scope) error {
 | 
				
			||||||
 | 
						out.SyncPeriod = in.SyncPeriod
 | 
				
			||||||
 | 
						out.MinSyncPeriod = in.MinSyncPeriod
 | 
				
			||||||
 | 
						out.Scheduler = in.Scheduler
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Convert_componentconfig_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration is an autogenerated conversion function.
 | 
				
			||||||
 | 
					func Convert_componentconfig_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in *componentconfig.KubeProxyIPVSConfiguration, out *KubeProxyIPVSConfiguration, s conversion.Scope) error {
 | 
				
			||||||
 | 
						return autoConvert_componentconfig_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in, out, s)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func autoConvert_v1alpha1_KubeSchedulerConfiguration_To_componentconfig_KubeSchedulerConfiguration(in *KubeSchedulerConfiguration, out *componentconfig.KubeSchedulerConfiguration, s conversion.Scope) error {
 | 
					func autoConvert_v1alpha1_KubeSchedulerConfiguration_To_componentconfig_KubeSchedulerConfiguration(in *KubeSchedulerConfiguration, out *componentconfig.KubeSchedulerConfiguration, s conversion.Scope) error {
 | 
				
			||||||
	out.Port = int32(in.Port)
 | 
						out.Port = int32(in.Port)
 | 
				
			||||||
	out.Address = in.Address
 | 
						out.Address = in.Address
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,6 +52,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
 | 
				
			|||||||
			in.(*KubeProxyIPTablesConfiguration).DeepCopyInto(out.(*KubeProxyIPTablesConfiguration))
 | 
								in.(*KubeProxyIPTablesConfiguration).DeepCopyInto(out.(*KubeProxyIPTablesConfiguration))
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		}, InType: reflect.TypeOf(&KubeProxyIPTablesConfiguration{})},
 | 
							}, InType: reflect.TypeOf(&KubeProxyIPTablesConfiguration{})},
 | 
				
			||||||
 | 
							conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
 | 
				
			||||||
 | 
								in.(*KubeProxyIPVSConfiguration).DeepCopyInto(out.(*KubeProxyIPVSConfiguration))
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}, InType: reflect.TypeOf(&KubeProxyIPVSConfiguration{})},
 | 
				
			||||||
		conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
 | 
							conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
 | 
				
			||||||
			in.(*KubeSchedulerConfiguration).DeepCopyInto(out.(*KubeSchedulerConfiguration))
 | 
								in.(*KubeSchedulerConfiguration).DeepCopyInto(out.(*KubeSchedulerConfiguration))
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
@@ -85,6 +89,7 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
 | 
				
			|||||||
	out.TypeMeta = in.TypeMeta
 | 
						out.TypeMeta = in.TypeMeta
 | 
				
			||||||
	out.ClientConnection = in.ClientConnection
 | 
						out.ClientConnection = in.ClientConnection
 | 
				
			||||||
	in.IPTables.DeepCopyInto(&out.IPTables)
 | 
						in.IPTables.DeepCopyInto(&out.IPTables)
 | 
				
			||||||
 | 
						out.IPVS = in.IPVS
 | 
				
			||||||
	if in.OOMScoreAdj != nil {
 | 
						if in.OOMScoreAdj != nil {
 | 
				
			||||||
		in, out := &in.OOMScoreAdj, &out.OOMScoreAdj
 | 
							in, out := &in.OOMScoreAdj, &out.OOMScoreAdj
 | 
				
			||||||
		if *in == nil {
 | 
							if *in == nil {
 | 
				
			||||||
@@ -164,6 +169,24 @@ func (in *KubeProxyIPTablesConfiguration) DeepCopy() *KubeProxyIPTablesConfigura
 | 
				
			|||||||
	return out
 | 
						return out
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 | 
				
			||||||
 | 
					func (in *KubeProxyIPVSConfiguration) DeepCopyInto(out *KubeProxyIPVSConfiguration) {
 | 
				
			||||||
 | 
						*out = *in
 | 
				
			||||||
 | 
						out.SyncPeriod = in.SyncPeriod
 | 
				
			||||||
 | 
						out.MinSyncPeriod = in.MinSyncPeriod
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProxyIPVSConfiguration.
 | 
				
			||||||
 | 
					func (in *KubeProxyIPVSConfiguration) DeepCopy() *KubeProxyIPVSConfiguration {
 | 
				
			||||||
 | 
						if in == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out := new(KubeProxyIPVSConfiguration)
 | 
				
			||||||
 | 
						in.DeepCopyInto(out)
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 | 
					// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 | 
				
			||||||
func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfiguration) {
 | 
					func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfiguration) {
 | 
				
			||||||
	*out = *in
 | 
						*out = *in
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,6 +64,10 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
 | 
				
			|||||||
			in.(*KubeProxyIPTablesConfiguration).DeepCopyInto(out.(*KubeProxyIPTablesConfiguration))
 | 
								in.(*KubeProxyIPTablesConfiguration).DeepCopyInto(out.(*KubeProxyIPTablesConfiguration))
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		}, InType: reflect.TypeOf(&KubeProxyIPTablesConfiguration{})},
 | 
							}, InType: reflect.TypeOf(&KubeProxyIPTablesConfiguration{})},
 | 
				
			||||||
 | 
							conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
 | 
				
			||||||
 | 
								in.(*KubeProxyIPVSConfiguration).DeepCopyInto(out.(*KubeProxyIPVSConfiguration))
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}, InType: reflect.TypeOf(&KubeProxyIPVSConfiguration{})},
 | 
				
			||||||
		conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
 | 
							conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
 | 
				
			||||||
			in.(*KubeSchedulerConfiguration).DeepCopyInto(out.(*KubeSchedulerConfiguration))
 | 
								in.(*KubeSchedulerConfiguration).DeepCopyInto(out.(*KubeSchedulerConfiguration))
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
@@ -206,6 +210,7 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
 | 
				
			|||||||
	out.TypeMeta = in.TypeMeta
 | 
						out.TypeMeta = in.TypeMeta
 | 
				
			||||||
	out.ClientConnection = in.ClientConnection
 | 
						out.ClientConnection = in.ClientConnection
 | 
				
			||||||
	in.IPTables.DeepCopyInto(&out.IPTables)
 | 
						in.IPTables.DeepCopyInto(&out.IPTables)
 | 
				
			||||||
 | 
						out.IPVS = in.IPVS
 | 
				
			||||||
	if in.OOMScoreAdj != nil {
 | 
						if in.OOMScoreAdj != nil {
 | 
				
			||||||
		in, out := &in.OOMScoreAdj, &out.OOMScoreAdj
 | 
							in, out := &in.OOMScoreAdj, &out.OOMScoreAdj
 | 
				
			||||||
		if *in == nil {
 | 
							if *in == nil {
 | 
				
			||||||
@@ -285,6 +290,24 @@ func (in *KubeProxyIPTablesConfiguration) DeepCopy() *KubeProxyIPTablesConfigura
 | 
				
			|||||||
	return out
 | 
						return out
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 | 
				
			||||||
 | 
					func (in *KubeProxyIPVSConfiguration) DeepCopyInto(out *KubeProxyIPVSConfiguration) {
 | 
				
			||||||
 | 
						*out = *in
 | 
				
			||||||
 | 
						out.SyncPeriod = in.SyncPeriod
 | 
				
			||||||
 | 
						out.MinSyncPeriod = in.MinSyncPeriod
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProxyIPVSConfiguration.
 | 
				
			||||||
 | 
					func (in *KubeProxyIPVSConfiguration) DeepCopy() *KubeProxyIPVSConfiguration {
 | 
				
			||||||
 | 
						if in == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						out := new(KubeProxyIPVSConfiguration)
 | 
				
			||||||
 | 
						in.DeepCopyInto(out)
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 | 
					// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 | 
				
			||||||
func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfiguration) {
 | 
					func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfiguration) {
 | 
				
			||||||
	*out = *in
 | 
						*out = *in
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -127,6 +127,12 @@ const (
 | 
				
			|||||||
	// Taint nodes based on their condition status for 'NetworkUnavailable',
 | 
						// Taint nodes based on their condition status for 'NetworkUnavailable',
 | 
				
			||||||
	// 'MemoryPressure', 'OutOfDisk' and 'DiskPressure'.
 | 
						// 'MemoryPressure', 'OutOfDisk' and 'DiskPressure'.
 | 
				
			||||||
	TaintNodesByCondition utilfeature.Feature = "TaintNodesByCondition"
 | 
						TaintNodesByCondition utilfeature.Feature = "TaintNodesByCondition"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// owner: @haibinxie
 | 
				
			||||||
 | 
						// alpha: v1.8
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// Implement IPVS-based in-cluster service load balancing
 | 
				
			||||||
 | 
						SupportIPVSProxyMode utilfeature.Feature = "SupportIPVSProxyMode"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
@@ -164,4 +170,5 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
 | 
				
			|||||||
	// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
 | 
						// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
 | 
				
			||||||
	// unintentionally on either side:
 | 
						// unintentionally on either side:
 | 
				
			||||||
	apiextensionsfeatures.CustomResourceValidation: {Default: false, PreRelease: utilfeature.Alpha},
 | 
						apiextensionsfeatures.CustomResourceValidation: {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
 | 
						SupportIPVSProxyMode:                           {Default: false, PreRelease: utilfeature.Alpha},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@ filegroup(
 | 
				
			|||||||
        "//pkg/proxy/config:all-srcs",
 | 
					        "//pkg/proxy/config:all-srcs",
 | 
				
			||||||
        "//pkg/proxy/healthcheck:all-srcs",
 | 
					        "//pkg/proxy/healthcheck:all-srcs",
 | 
				
			||||||
        "//pkg/proxy/iptables:all-srcs",
 | 
					        "//pkg/proxy/iptables:all-srcs",
 | 
				
			||||||
 | 
					        "//pkg/proxy/ipvs:all-srcs",
 | 
				
			||||||
        "//pkg/proxy/userspace:all-srcs",
 | 
					        "//pkg/proxy/userspace:all-srcs",
 | 
				
			||||||
        "//pkg/proxy/util:all-srcs",
 | 
					        "//pkg/proxy/util:all-srcs",
 | 
				
			||||||
        "//pkg/proxy/winuserspace:all-srcs",
 | 
					        "//pkg/proxy/winuserspace:all-srcs",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								pkg/proxy/ipvs/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								pkg/proxy/ipvs/BUILD
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					package(default_visibility = ["//visibility:public"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					licenses(["notice"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					load(
 | 
				
			||||||
 | 
					    "@io_bazel_rules_go//go:def.bzl",
 | 
				
			||||||
 | 
					    "go_library",
 | 
				
			||||||
 | 
					    "go_test",
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go_test(
 | 
				
			||||||
 | 
					    name = "go_default_test",
 | 
				
			||||||
 | 
					    srcs = select({
 | 
				
			||||||
 | 
					        "@io_bazel_rules_go//go/platform:linux_amd64": [
 | 
				
			||||||
 | 
					            "proxier_test.go",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "//conditions:default": [],
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					    library = ":go_default_library",
 | 
				
			||||||
 | 
					    tags = ["automanaged"],
 | 
				
			||||||
 | 
					    deps = select({
 | 
				
			||||||
 | 
					        "@io_bazel_rules_go//go/platform:linux_amd64": [
 | 
				
			||||||
 | 
					            "//pkg/api:go_default_library",
 | 
				
			||||||
 | 
					            "//pkg/proxy:go_default_library",
 | 
				
			||||||
 | 
					            "//pkg/proxy/util:go_default_library",
 | 
				
			||||||
 | 
					            "//pkg/util/iptables:go_default_library",
 | 
				
			||||||
 | 
					            "//pkg/util/iptables/testing:go_default_library",
 | 
				
			||||||
 | 
					            "//pkg/util/ipvs:go_default_library",
 | 
				
			||||||
 | 
					            "//pkg/util/ipvs/testing:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/github.com/davecgh/go-spew/spew:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/k8s.io/utils/exec:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/k8s.io/utils/exec/testing:go_default_library",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "//conditions:default": [],
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go_library(
 | 
				
			||||||
 | 
					    name = "go_default_library",
 | 
				
			||||||
 | 
					    srcs = ["proxier.go"],
 | 
				
			||||||
 | 
					    tags = ["automanaged"],
 | 
				
			||||||
 | 
					    deps = [
 | 
				
			||||||
 | 
					        "//pkg/api:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/api/helper:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/api/service:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/features:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/proxy:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/proxy/healthcheck:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/proxy/util:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/util/iptables:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/util/ipvs:go_default_library",
 | 
				
			||||||
 | 
					        "//pkg/util/sysctl:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/github.com/golang/glog:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/api/core/v1:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/client-go/tools/record:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
 | 
				
			||||||
 | 
					        "//vendor/k8s.io/utils/exec:go_default_library",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					filegroup(
 | 
				
			||||||
 | 
					    name = "package-srcs",
 | 
				
			||||||
 | 
					    srcs = glob(["**"]),
 | 
				
			||||||
 | 
					    tags = ["automanaged"],
 | 
				
			||||||
 | 
					    visibility = ["//visibility:private"],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					filegroup(
 | 
				
			||||||
 | 
					    name = "all-srcs",
 | 
				
			||||||
 | 
					    srcs = [":package-srcs"],
 | 
				
			||||||
 | 
					    tags = ["automanaged"],
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										1498
									
								
								pkg/proxy/ipvs/proxier.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1498
									
								
								pkg/proxy/ipvs/proxier.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2180
									
								
								pkg/proxy/ipvs/proxier_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2180
									
								
								pkg/proxy/ipvs/proxier_test.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										19
									
								
								vendor/github.com/docker/libnetwork/ipvs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/docker/libnetwork/ipvs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,18 +4,21 @@ go_library(
 | 
				
			|||||||
    name = "go_default_library",
 | 
					    name = "go_default_library",
 | 
				
			||||||
    srcs = select({
 | 
					    srcs = select({
 | 
				
			||||||
        "@io_bazel_rules_go//go/platform:linux_amd64": [
 | 
					        "@io_bazel_rules_go//go/platform:linux_amd64": [
 | 
				
			||||||
            "addr_linux.go",
 | 
					            "constants.go",
 | 
				
			||||||
            "link_linux.go",
 | 
					            "ipvs.go",
 | 
				
			||||||
            "nl_linux.go",
 | 
					            "netlink.go",
 | 
				
			||||||
            "route_linux.go",
 | 
					 | 
				
			||||||
            "tc_linux.go",
 | 
					 | 
				
			||||||
            "xfrm_linux.go",
 | 
					 | 
				
			||||||
            "xfrm_policy_linux.go",
 | 
					 | 
				
			||||||
            "xfrm_state_linux.go",
 | 
					 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "//conditions:default": [],
 | 
					        "//conditions:default": [],
 | 
				
			||||||
    }),
 | 
					    }),
 | 
				
			||||||
    visibility = ["//visibility:public"],
 | 
					    visibility = ["//visibility:public"],
 | 
				
			||||||
 | 
					    deps = select({
 | 
				
			||||||
 | 
					        "@io_bazel_rules_go//go/platform:linux_amd64": [
 | 
				
			||||||
 | 
					            "//vendor/github.com/Sirupsen/logrus:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/github.com/vishvananda/netlink/nl:go_default_library",
 | 
				
			||||||
 | 
					            "//vendor/github.com/vishvananda/netns:go_default_library",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "//conditions:default": [],
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
filegroup(
 | 
					filegroup(
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user