diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 3503f585fe0..b9048aa3aed 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -205,10 +205,22 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&o.config.DetectLocal.InterfaceNamePrefix, "pod-interface-name-prefix", o.config.DetectLocal.InterfaceNamePrefix, "An interface prefix in the cluster. Kube-proxy considers traffic as local if originating from interfaces that match the given prefix. This argument should be set if DetectLocalMode is set to InterfaceNamePrefix.") } +// newKubeProxyConfiguration returns a KubeProxyConfiguration with default values +func newKubeProxyConfiguration() *kubeproxyconfig.KubeProxyConfiguration { + versionedConfig := &v1alpha1.KubeProxyConfiguration{} + proxyconfigscheme.Scheme.Default(versionedConfig) + internalConfig, err := proxyconfigscheme.Scheme.ConvertToVersion(versionedConfig, kubeproxyconfig.SchemeGroupVersion) + if err != nil { + panic(fmt.Sprintf("Unable to create default config: %v", err)) + } + + return internalConfig.(*kubeproxyconfig.KubeProxyConfiguration) +} + // NewOptions returns initialized Options func NewOptions() *Options { return &Options{ - config: new(kubeproxyconfig.KubeProxyConfiguration), + config: newKubeProxyConfiguration(), healthzPort: ports.ProxyHealthzPort, metricsPort: ports.ProxyStatusPort, errCh: make(chan error), @@ -236,6 +248,8 @@ func (o *Options) Complete() error { } } + o.platformApplyDefaults(o.config) + if err := o.processHostnameOverrideFlag(); err != nil { return err } @@ -436,25 +450,6 @@ func (o *Options) loadConfig(data []byte) (*kubeproxyconfig.KubeProxyConfigurati return proxyConfig, nil } -// ApplyDefaults applies the default values to Options. -func (o *Options) ApplyDefaults(in *kubeproxyconfig.KubeProxyConfiguration) (*kubeproxyconfig.KubeProxyConfiguration, error) { - external, err := proxyconfigscheme.Scheme.ConvertToVersion(in, v1alpha1.SchemeGroupVersion) - if err != nil { - return nil, err - } - - proxyconfigscheme.Scheme.Default(external) - - internal, err := proxyconfigscheme.Scheme.ConvertToVersion(external, kubeproxyconfig.SchemeGroupVersion) - if err != nil { - return nil, err - } - - out := internal.(*kubeproxyconfig.KubeProxyConfiguration) - - return out, nil -} - // NewProxyCommand creates a *cobra.Command object with default parameters func NewProxyCommand() *cobra.Command { opts := NewOptions() @@ -502,14 +497,6 @@ with the apiserver API to configure the proxy.`, }, } - var err error - opts.config, err = opts.ApplyDefaults(opts.config) - if err != nil { - klog.ErrorS(err, "Unable to create flag defaults") - // ACTION REQUIRED: Exit code changed from 255 to 1 - os.Exit(1) - } - fs := cmd.Flags() opts.AddFlags(fs) fs.AddGoFlagSet(goflag.CommandLine) // for --boot-id-file and --machine-id-file @@ -522,21 +509,16 @@ with the apiserver API to configure the proxy.`, // ProxyServer represents all the parameters required to start the Kubernetes proxy server. All // fields are required. type ProxyServer struct { - Client clientset.Interface - Proxier proxy.Provider - Broadcaster events.EventBroadcaster - Recorder events.EventRecorder - ConntrackConfiguration kubeproxyconfig.KubeProxyConntrackConfiguration - Conntracker Conntracker // if nil, ignored - ProxyMode kubeproxyconfig.ProxyMode - NodeRef *v1.ObjectReference - MetricsBindAddress string - BindAddressHardFail bool - EnableProfiling bool - OOMScoreAdj *int32 - ConfigSyncPeriod time.Duration - HealthzServer healthcheck.ProxierHealthUpdater - localDetectorMode kubeproxyconfig.LocalMode + Config *kubeproxyconfig.KubeProxyConfiguration + + Client clientset.Interface + Broadcaster events.EventBroadcaster + Recorder events.EventRecorder + Conntracker Conntracker // if nil, ignored + NodeRef *v1.ObjectReference + HealthzServer healthcheck.ProxierHealthUpdater + + Proxier proxy.Provider } // createClient creates a kube client from the given config and masterOverride. @@ -645,9 +627,9 @@ func (s *ProxyServer) Run() error { // TODO(vmarmol): Use container config for this. var oomAdjuster *oom.OOMAdjuster - if s.OOMScoreAdj != nil { + if s.Config.OOMScoreAdj != nil { oomAdjuster = oom.NewOOMAdjuster() - if err := oomAdjuster.ApplyOOMScoreAdj(0, int(*s.OOMScoreAdj)); err != nil { + if err := oomAdjuster.ApplyOOMScoreAdj(0, int(*s.Config.OOMScoreAdj)); err != nil { klog.V(2).InfoS("Failed to apply OOMScore", "err", err) } } @@ -660,7 +642,7 @@ func (s *ProxyServer) Run() error { // TODO(thockin): make it possible for healthz and metrics to be on the same port. var errCh chan error - if s.BindAddressHardFail { + if s.Config.BindAddressHardFail { errCh = make(chan error) } @@ -668,12 +650,12 @@ func (s *ProxyServer) Run() error { serveHealthz(s.HealthzServer, errCh) // Start up a metrics server if requested - serveMetrics(s.MetricsBindAddress, s.ProxyMode, s.EnableProfiling, errCh) + serveMetrics(s.Config.MetricsBindAddress, s.Config.Mode, s.Config.EnableProfiling, errCh) // Tune conntrack, if requested // Conntracker is always nil for windows if s.Conntracker != nil { - max, err := getConntrackMax(s.ConntrackConfiguration) + max, err := getConntrackMax(s.Config.Conntrack) if err != nil { return err } @@ -696,15 +678,15 @@ func (s *ProxyServer) Run() error { } } - if s.ConntrackConfiguration.TCPEstablishedTimeout != nil && s.ConntrackConfiguration.TCPEstablishedTimeout.Duration > 0 { - timeout := int(s.ConntrackConfiguration.TCPEstablishedTimeout.Duration / time.Second) + if s.Config.Conntrack.TCPEstablishedTimeout != nil && s.Config.Conntrack.TCPEstablishedTimeout.Duration > 0 { + timeout := int(s.Config.Conntrack.TCPEstablishedTimeout.Duration / time.Second) if err := s.Conntracker.SetTCPEstablishedTimeout(timeout); err != nil { return err } } - if s.ConntrackConfiguration.TCPCloseWaitTimeout != nil && s.ConntrackConfiguration.TCPCloseWaitTimeout.Duration > 0 { - timeout := int(s.ConntrackConfiguration.TCPCloseWaitTimeout.Duration / time.Second) + if s.Config.Conntrack.TCPCloseWaitTimeout != nil && s.Config.Conntrack.TCPCloseWaitTimeout.Duration > 0 { + timeout := int(s.Config.Conntrack.TCPCloseWaitTimeout.Duration / time.Second) if err := s.Conntracker.SetTCPCloseWaitTimeout(timeout); err != nil { return err } @@ -725,7 +707,7 @@ func (s *ProxyServer) Run() error { labelSelector = labelSelector.Add(*noProxyName, *noHeadlessEndpoints) // Make informers that filter out objects that want a non-default service proxy. - informerFactory := informers.NewSharedInformerFactoryWithOptions(s.Client, s.ConfigSyncPeriod, + informerFactory := informers.NewSharedInformerFactoryWithOptions(s.Client, s.Config.ConfigSyncPeriod.Duration, informers.WithTweakListOptions(func(options *metav1.ListOptions) { options.LabelSelector = labelSelector.String() })) @@ -734,11 +716,11 @@ func (s *ProxyServer) Run() error { // Note: RegisterHandler() calls need to happen before creation of Sources because sources // only notify on changes, and the initial update (on process start) may be lost if no handlers // are registered yet. - serviceConfig := config.NewServiceConfig(informerFactory.Core().V1().Services(), s.ConfigSyncPeriod) + serviceConfig := config.NewServiceConfig(informerFactory.Core().V1().Services(), s.Config.ConfigSyncPeriod.Duration) serviceConfig.RegisterEventHandler(s.Proxier) go serviceConfig.Run(wait.NeverStop) - endpointSliceConfig := config.NewEndpointSliceConfig(informerFactory.Discovery().V1().EndpointSlices(), s.ConfigSyncPeriod) + endpointSliceConfig := config.NewEndpointSliceConfig(informerFactory.Discovery().V1().EndpointSlices(), s.Config.ConfigSyncPeriod.Duration) endpointSliceConfig.RegisterEventHandler(s.Proxier) go endpointSliceConfig.Run(wait.NeverStop) @@ -747,13 +729,13 @@ func (s *ProxyServer) Run() error { informerFactory.Start(wait.NeverStop) // Make an informer that selects for our nodename. - currentNodeInformerFactory := informers.NewSharedInformerFactoryWithOptions(s.Client, s.ConfigSyncPeriod, + currentNodeInformerFactory := informers.NewSharedInformerFactoryWithOptions(s.Client, s.Config.ConfigSyncPeriod.Duration, informers.WithTweakListOptions(func(options *metav1.ListOptions) { options.FieldSelector = fields.OneTermEqualSelector("metadata.name", s.NodeRef.Name).String() })) - nodeConfig := config.NewNodeConfig(currentNodeInformerFactory.Core().V1().Nodes(), s.ConfigSyncPeriod) + nodeConfig := config.NewNodeConfig(currentNodeInformerFactory.Core().V1().Nodes(), s.Config.ConfigSyncPeriod.Duration) // https://issues.k8s.io/111321 - if s.localDetectorMode == kubeproxyconfig.LocalModeNodeCIDR { + if s.Config.DetectLocalMode == kubeproxyconfig.LocalModeNodeCIDR { nodeConfig.RegisterEventHandler(&proxy.NodePodCIDRHandler{}) } nodeConfig.RegisterEventHandler(s.Proxier) diff --git a/cmd/kube-proxy/app/server_others.go b/cmd/kube-proxy/app/server_others.go index c4121feb989..f78ab70792b 100644 --- a/cmd/kube-proxy/app/server_others.go +++ b/cmd/kube-proxy/app/server_others.go @@ -70,6 +70,19 @@ import ( // node after it is registered. var timeoutForNodePodCIDR = 5 * time.Minute +func (o *Options) platformApplyDefaults(config *proxyconfigapi.KubeProxyConfiguration) { + if config.Mode == "" { + klog.InfoS("Using iptables proxy") + config.Mode = proxyconfigapi.ProxyModeIPTables + } + + if config.DetectLocalMode == "" { + klog.V(4).InfoS("Defaulting detect-local-mode", "localModeClusterCIDR", string(proxyconfigapi.LocalModeClusterCIDR)) + config.DetectLocalMode = proxyconfigapi.LocalModeClusterCIDR + } + klog.V(2).InfoS("DetectLocalMode", "localMode", string(config.DetectLocalMode)) +} + // NewProxyServer returns a new ProxyServer. func NewProxyServer(o *Options) (*ProxyServer, error) { return newProxyServer(o.config, o.master) @@ -79,10 +92,6 @@ func newProxyServer( config *proxyconfigapi.KubeProxyConfiguration, master string) (*ProxyServer, error) { - if config == nil { - return nil, errors.New("config is required") - } - if c, err := configz.New(proxyconfigapi.GroupName); err == nil { c.Set(config) } else { @@ -126,16 +135,9 @@ func newProxyServer( } var proxier proxy.Provider - var detectLocalMode proxyconfigapi.LocalMode - - proxyMode := getProxyMode(config.Mode) - detectLocalMode, err = getDetectLocalMode(config) - if err != nil { - return nil, fmt.Errorf("cannot determine detect-local-mode: %v", err) - } var nodeInfo *v1.Node - if detectLocalMode == proxyconfigapi.LocalModeNodeCIDR { + if config.DetectLocalMode == proxyconfigapi.LocalModeNodeCIDR { klog.InfoS("Watching for node, awaiting podCIDR allocation", "hostname", hostname) nodeInfo, err = waitForPodCIDR(client, hostname) if err != nil { @@ -144,8 +146,6 @@ func newProxyServer( klog.InfoS("NodeInfo", "podCIDR", nodeInfo.Spec.PodCIDR, "podCIDRs", nodeInfo.Spec.PodCIDRs) } - klog.V(2).InfoS("DetectLocalMode", "localMode", string(detectLocalMode)) - primaryFamily := v1.IPv4Protocol primaryProtocol := utiliptables.ProtocolIPv4 if netutils.IsIPv6(nodeIP) { @@ -186,19 +186,15 @@ func newProxyServer( } } - if proxyMode == proxyconfigapi.ProxyModeIPTables { + if config.Mode == proxyconfigapi.ProxyModeIPTables { klog.InfoS("Using iptables Proxier") - if config.IPTables.MasqueradeBit == nil { - // MasqueradeBit must be specified or defaulted. - return nil, fmt.Errorf("unable to read IPTables MasqueradeBit from config") - } if dualStack { klog.InfoS("kube-proxy running in dual-stack mode", "ipFamily", iptInterface.Protocol()) klog.InfoS("Creating dualStackProxier for iptables") // Always ordered to match []ipt var localDetectors [2]proxyutiliptables.LocalTrafficDetector - localDetectors, err = getDualStackLocalDetectorTuple(detectLocalMode, config, ipt, nodeInfo) + localDetectors, err = getDualStackLocalDetectorTuple(config.DetectLocalMode, config, ipt, nodeInfo) if err != nil { return nil, fmt.Errorf("unable to create proxier: %v", err) } @@ -223,7 +219,7 @@ func newProxyServer( } else { // Create a single-stack proxier if and only if the node does not support dual-stack (i.e, no iptables support). var localDetector proxyutiliptables.LocalTrafficDetector - localDetector, err = getLocalDetector(detectLocalMode, config, iptInterface, nodeInfo) + localDetector, err = getLocalDetector(config.DetectLocalMode, config, iptInterface, nodeInfo) if err != nil { return nil, fmt.Errorf("unable to create proxier: %v", err) } @@ -252,7 +248,7 @@ func newProxyServer( return nil, fmt.Errorf("unable to create proxier: %v", err) } proxymetrics.RegisterMetrics() - } else if proxyMode == proxyconfigapi.ProxyModeIPVS { + } else if config.Mode == proxyconfigapi.ProxyModeIPVS { kernelHandler := ipvs.NewLinuxKernelHandler() ipsetInterface = utilipset.New(execer) ipvsInterface = utilipvs.New() @@ -268,7 +264,7 @@ func newProxyServer( // Always ordered to match []ipt var localDetectors [2]proxyutiliptables.LocalTrafficDetector - localDetectors, err = getDualStackLocalDetectorTuple(detectLocalMode, config, ipt, nodeInfo) + localDetectors, err = getDualStackLocalDetectorTuple(config.DetectLocalMode, config, ipt, nodeInfo) if err != nil { return nil, fmt.Errorf("unable to create proxier: %v", err) } @@ -299,7 +295,7 @@ func newProxyServer( ) } else { var localDetector proxyutiliptables.LocalTrafficDetector - localDetector, err = getLocalDetector(detectLocalMode, config, iptInterface, nodeInfo) + localDetector, err = getLocalDetector(config.DetectLocalMode, config, iptInterface, nodeInfo) if err != nil { return nil, fmt.Errorf("unable to create proxier: %v", err) } @@ -337,21 +333,14 @@ func newProxyServer( } return &ProxyServer{ - Client: client, - Proxier: proxier, - Broadcaster: eventBroadcaster, - Recorder: recorder, - ConntrackConfiguration: config.Conntrack, - Conntracker: &realConntracker{}, - ProxyMode: proxyMode, - NodeRef: nodeRef, - MetricsBindAddress: config.MetricsBindAddress, - BindAddressHardFail: config.BindAddressHardFail, - EnableProfiling: config.EnableProfiling, - OOMScoreAdj: config.OOMScoreAdj, - ConfigSyncPeriod: config.ConfigSyncPeriod.Duration, - HealthzServer: healthzServer, - localDetectorMode: detectLocalMode, + Config: config, + Client: client, + Proxier: proxier, + Broadcaster: eventBroadcaster, + Recorder: recorder, + Conntracker: &realConntracker{}, + NodeRef: nodeRef, + HealthzServer: healthzServer, }, nil } @@ -408,23 +397,11 @@ func detectNumCPU() int { return numCPU } -func getDetectLocalMode(config *proxyconfigapi.KubeProxyConfiguration) (proxyconfigapi.LocalMode, error) { - mode := config.DetectLocalMode - switch mode { - case proxyconfigapi.LocalModeClusterCIDR, proxyconfigapi.LocalModeNodeCIDR, proxyconfigapi.LocalModeBridgeInterface, proxyconfigapi.LocalModeInterfaceNamePrefix: - return mode, nil - default: - if strings.TrimSpace(mode.String()) != "" { - return mode, fmt.Errorf("unknown detect-local-mode: %v", mode) - } - klog.V(4).InfoS("Defaulting detect-local-mode", "localModeClusterCIDR", string(proxyconfigapi.LocalModeClusterCIDR)) - return proxyconfigapi.LocalModeClusterCIDR, nil - } -} - func getLocalDetector(mode proxyconfigapi.LocalMode, config *proxyconfigapi.KubeProxyConfiguration, ipt utiliptables.Interface, nodeInfo *v1.Node) (proxyutiliptables.LocalTrafficDetector, error) { switch mode { case proxyconfigapi.LocalModeClusterCIDR: + // LocalModeClusterCIDR is the default if --detect-local-mode wasn't passed, + // but --cluster-cidr is optional. if len(strings.TrimSpace(config.ClusterCIDR)) == 0 { klog.InfoS("Detect-local-mode set to ClusterCIDR, but no cluster CIDR defined") break @@ -437,14 +414,8 @@ func getLocalDetector(mode proxyconfigapi.LocalMode, config *proxyconfigapi.Kube } return proxyutiliptables.NewDetectLocalByCIDR(nodeInfo.Spec.PodCIDR, ipt) case proxyconfigapi.LocalModeBridgeInterface: - if len(strings.TrimSpace(config.DetectLocal.BridgeInterface)) == 0 { - return nil, fmt.Errorf("Detect-local-mode set to BridgeInterface, but no bridge-interface-name %s is defined", config.DetectLocal.BridgeInterface) - } return proxyutiliptables.NewDetectLocalByBridgeInterface(config.DetectLocal.BridgeInterface) case proxyconfigapi.LocalModeInterfaceNamePrefix: - if len(strings.TrimSpace(config.DetectLocal.InterfaceNamePrefix)) == 0 { - return nil, fmt.Errorf("Detect-local-mode set to InterfaceNamePrefix, but no interface-prefix %s is defined", config.DetectLocal.InterfaceNamePrefix) - } return proxyutiliptables.NewDetectLocalByInterfaceNamePrefix(config.DetectLocal.InterfaceNamePrefix) } klog.InfoS("Defaulting to no-op detect-local", "detectLocalMode", string(mode)) @@ -456,6 +427,8 @@ func getDualStackLocalDetectorTuple(mode proxyconfigapi.LocalMode, config *proxy localDetectors := [2]proxyutiliptables.LocalTrafficDetector{proxyutiliptables.NewNoOpLocalDetector(), proxyutiliptables.NewNoOpLocalDetector()} switch mode { case proxyconfigapi.LocalModeClusterCIDR: + // LocalModeClusterCIDR is the default if --detect-local-mode wasn't passed, + // but --cluster-cidr is optional. if len(strings.TrimSpace(config.ClusterCIDR)) == 0 { klog.InfoS("Detect-local-mode set to ClusterCIDR, but no cluster CIDR defined") break @@ -479,7 +452,7 @@ func getDualStackLocalDetectorTuple(mode proxyconfigapi.LocalMode, config *proxy } return localDetectors, err case proxyconfigapi.LocalModeNodeCIDR: - if nodeInfo == nil || len(strings.TrimSpace(nodeInfo.Spec.PodCIDR)) == 0 { + if len(strings.TrimSpace(nodeInfo.Spec.PodCIDR)) == 0 { klog.InfoS("No node info available to configure detect-local-mode NodeCIDR") break } @@ -541,15 +514,6 @@ func cidrTuple(cidrList string) [2]string { return cidrs } -func getProxyMode(proxyMode proxyconfigapi.ProxyMode) proxyconfigapi.ProxyMode { - if proxyMode == "" { - klog.InfoS("Using iptables proxy") - return proxyconfigapi.ProxyModeIPTables - } else { - return proxyMode - } -} - // cleanupAndExit remove iptables rules and ipset/ipvs rules func cleanupAndExit() error { execer := exec.New() diff --git a/cmd/kube-proxy/app/server_others_test.go b/cmd/kube-proxy/app/server_others_test.go index a1f3f691180..e6836138c2f 100644 --- a/cmd/kube-proxy/app/server_others_test.go +++ b/cmd/kube-proxy/app/server_others_test.go @@ -44,54 +44,66 @@ import ( utiliptablestest "k8s.io/kubernetes/pkg/util/iptables/testing" ) -func Test_getDetectLocalMode(t *testing.T) { - cases := []struct { - detectLocal string - expected proxyconfigapi.LocalMode - errExpected bool +func Test_platformApplyDefaults(t *testing.T) { + testCases := []struct { + name string + mode proxyconfigapi.ProxyMode + expectedMode proxyconfigapi.ProxyMode + detectLocal proxyconfigapi.LocalMode + expectedDetectLocal proxyconfigapi.LocalMode }{ { - detectLocal: "", - expected: proxyconfigapi.LocalModeClusterCIDR, - errExpected: false, + name: "defaults", + mode: "", + expectedMode: proxyconfigapi.ProxyModeIPTables, + detectLocal: "", + expectedDetectLocal: proxyconfigapi.LocalModeClusterCIDR, }, { - detectLocal: string(proxyconfigapi.LocalModeClusterCIDR), - expected: proxyconfigapi.LocalModeClusterCIDR, - errExpected: false, + name: "explicit", + mode: proxyconfigapi.ProxyModeIPTables, + expectedMode: proxyconfigapi.ProxyModeIPTables, + detectLocal: proxyconfigapi.LocalModeClusterCIDR, + expectedDetectLocal: proxyconfigapi.LocalModeClusterCIDR, }, { - detectLocal: string(proxyconfigapi.LocalModeInterfaceNamePrefix), - expected: proxyconfigapi.LocalModeInterfaceNamePrefix, - errExpected: false, + name: "override mode", + mode: "ipvs", + expectedMode: proxyconfigapi.ProxyModeIPVS, + detectLocal: "", + expectedDetectLocal: proxyconfigapi.LocalModeClusterCIDR, }, { - detectLocal: string(proxyconfigapi.LocalModeBridgeInterface), - expected: proxyconfigapi.LocalModeBridgeInterface, - errExpected: false, + name: "override detect-local", + mode: "", + expectedMode: proxyconfigapi.ProxyModeIPTables, + detectLocal: "NodeCIDR", + expectedDetectLocal: proxyconfigapi.LocalModeNodeCIDR, }, { - detectLocal: "abcd", - expected: proxyconfigapi.LocalMode("abcd"), - errExpected: true, + name: "override both", + mode: "ipvs", + expectedMode: proxyconfigapi.ProxyModeIPVS, + detectLocal: "NodeCIDR", + expectedDetectLocal: proxyconfigapi.LocalModeNodeCIDR, }, } - for i, c := range cases { - proxyConfig := &proxyconfigapi.KubeProxyConfiguration{DetectLocalMode: proxyconfigapi.LocalMode(c.detectLocal)} - r, err := getDetectLocalMode(proxyConfig) - if c.errExpected { - if err == nil { - t.Errorf("Expected error, but did not fail for mode %v", c.detectLocal) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + options := NewOptions() + config := &proxyconfigapi.KubeProxyConfiguration{ + Mode: tc.mode, + DetectLocalMode: tc.detectLocal, } - continue - } - if err != nil { - t.Errorf("Got error parsing mode: %v", err) - continue - } - if r != c.expected { - t.Errorf("Case[%d] Expected %q got %q", i, c.expected, r) - } + + options.platformApplyDefaults(config) + if config.Mode != tc.expectedMode { + t.Fatalf("expected mode: %s, but got: %s", tc.expectedMode, config.Mode) + } + if config.DetectLocalMode != tc.expectedDetectLocal { + t.Fatalf("expected detect-local: %s, but got: %s", tc.expectedDetectLocal, config.DetectLocalMode) + } + }) } } @@ -224,20 +236,6 @@ func Test_getLocalDetector(t *testing.T) { expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByCIDR("2002::1234:abcd:ffff:c0a8:101/64", utiliptablestest.NewIPv6Fake())), errExpected: false, }, - { - mode: proxyconfigapi.LocalModeClusterCIDR, - config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0"}, - ipt: utiliptablestest.NewFake(), - expected: nil, - errExpected: true, - }, - { - mode: proxyconfigapi.LocalModeClusterCIDR, - config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002::1234:abcd:ffff:c0a8:101"}, - ipt: utiliptablestest.NewIPv6Fake(), - expected: nil, - errExpected: true, - }, { mode: proxyconfigapi.LocalModeClusterCIDR, config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"}, @@ -276,22 +274,6 @@ func Test_getLocalDetector(t *testing.T) { nodeInfo: makeNodeWithPodCIDRs("2002::1234:abcd:ffff:c0a8:101/96"), errExpected: false, }, - { - mode: proxyconfigapi.LocalModeNodeCIDR, - config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0"}, - ipt: utiliptablestest.NewFake(), - expected: nil, - nodeInfo: makeNodeWithPodCIDRs("10.0.0.0"), - errExpected: true, - }, - { - mode: proxyconfigapi.LocalModeNodeCIDR, - config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "2002::1234:abcd:ffff:c0a8:101"}, - ipt: utiliptablestest.NewIPv6Fake(), - expected: nil, - nodeInfo: makeNodeWithPodCIDRs("2002::1234:abcd:ffff:c0a8:101"), - errExpected: true, - }, { mode: proxyconfigapi.LocalModeNodeCIDR, config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: "10.0.0.0/14"}, @@ -333,13 +315,6 @@ func Test_getLocalDetector(t *testing.T) { expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByBridgeInterface("eth")), errExpected: false, }, - { - mode: proxyconfigapi.LocalModeBridgeInterface, - config: &proxyconfigapi.KubeProxyConfiguration{ - DetectLocal: proxyconfigapi.DetectLocalConfiguration{BridgeInterface: ""}, - }, - errExpected: true, - }, { mode: proxyconfigapi.LocalModeBridgeInterface, config: &proxyconfigapi.KubeProxyConfiguration{ @@ -357,13 +332,6 @@ func Test_getLocalDetector(t *testing.T) { expected: resolveLocalDetector(t)(proxyutiliptables.NewDetectLocalByInterfaceNamePrefix("eth")), errExpected: false, }, - { - mode: proxyconfigapi.LocalModeInterfaceNamePrefix, - config: &proxyconfigapi.KubeProxyConfiguration{ - DetectLocal: proxyconfigapi.DetectLocalConfiguration{InterfaceNamePrefix: ""}, - }, - errExpected: true, - }, { mode: proxyconfigapi.LocalModeInterfaceNamePrefix, config: &proxyconfigapi.KubeProxyConfiguration{ @@ -493,22 +461,6 @@ func Test_getDualStackLocalDetectorTuple(t *testing.T) { nodeInfo: makeNodeWithPodCIDRs(), errExpected: false, }, - { - mode: proxyconfigapi.LocalModeNodeCIDR, - config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""}, - ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIPv6Fake()}, - expected: [2]proxyutiliptables.LocalTrafficDetector{proxyutiliptables.NewNoOpLocalDetector(), proxyutiliptables.NewNoOpLocalDetector()}, - nodeInfo: nil, - errExpected: false, - }, - // unknown mode, nodeInfo would be nil for these cases - { - mode: proxyconfigapi.LocalMode("abcd"), - config: &proxyconfigapi.KubeProxyConfiguration{ClusterCIDR: ""}, - ipt: [2]utiliptables.Interface{utiliptablestest.NewFake(), utiliptablestest.NewIPv6Fake()}, - expected: [2]proxyutiliptables.LocalTrafficDetector{proxyutiliptables.NewNoOpLocalDetector(), proxyutiliptables.NewNoOpLocalDetector()}, - errExpected: false, - }, // LocalModeBridgeInterface, nodeInfo and ipt are not needed for these cases { mode: proxyconfigapi.LocalModeBridgeInterface, @@ -520,13 +472,6 @@ func Test_getDualStackLocalDetectorTuple(t *testing.T) { proxyutiliptables.NewDetectLocalByBridgeInterface("eth")), errExpected: false, }, - { - mode: proxyconfigapi.LocalModeBridgeInterface, - config: &proxyconfigapi.KubeProxyConfiguration{ - DetectLocal: proxyconfigapi.DetectLocalConfiguration{BridgeInterface: ""}, - }, - errExpected: true, - }, // LocalModeInterfaceNamePrefix, nodeInfo and ipt are not needed for these cases { mode: proxyconfigapi.LocalModeInterfaceNamePrefix, @@ -538,13 +483,6 @@ func Test_getDualStackLocalDetectorTuple(t *testing.T) { proxyutiliptables.NewDetectLocalByInterfaceNamePrefix("veth")), errExpected: false, }, - { - mode: proxyconfigapi.LocalModeInterfaceNamePrefix, - config: &proxyconfigapi.KubeProxyConfiguration{ - DetectLocal: proxyconfigapi.DetectLocalConfiguration{InterfaceNamePrefix: ""}, - }, - errExpected: true, - }, } for i, c := range cases { r, err := getDualStackLocalDetectorTuple(c.mode, c.config, c.ipt, c.nodeInfo) diff --git a/cmd/kube-proxy/app/server_windows.go b/cmd/kube-proxy/app/server_windows.go index a6ba3eff5ce..43ae62600e9 100644 --- a/cmd/kube-proxy/app/server_windows.go +++ b/cmd/kube-proxy/app/server_windows.go @@ -45,16 +45,18 @@ import ( "k8s.io/kubernetes/pkg/proxy/winkernel" ) +func (o *Options) platformApplyDefaults(config *proxyconfigapi.KubeProxyConfiguration) { + if config.Mode == "" { + config.Mode = proxyconfigapi.ProxyModeKernelspace + } +} + // NewProxyServer returns a new ProxyServer. func NewProxyServer(o *Options) (*ProxyServer, error) { return newProxyServer(o.config, o.master) } func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, master string) (*ProxyServer, error) { - if config == nil { - return nil, errors.New("config is required") - } - if c, err := configz.New(proxyconfigapi.GroupName); err == nil { c.Set(config) } else { @@ -103,7 +105,6 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, master string } var proxier proxy.Provider - proxyMode := proxyconfigapi.ProxyModeKernelspace dualStackMode := getDualStackMode(config.Winkernel.NetworkName, winkernel.DualStackCompatTester{}) if dualStackMode { klog.InfoS("Creating dualStackProxier for Windows kernel.") @@ -138,18 +139,13 @@ func newProxyServer(config *proxyconfigapi.KubeProxyConfiguration, master string winkernel.RegisterMetrics() return &ProxyServer{ - Client: client, - Proxier: proxier, - Broadcaster: eventBroadcaster, - Recorder: recorder, - ProxyMode: proxyMode, - NodeRef: nodeRef, - MetricsBindAddress: config.MetricsBindAddress, - BindAddressHardFail: config.BindAddressHardFail, - EnableProfiling: config.EnableProfiling, - OOMScoreAdj: config.OOMScoreAdj, - ConfigSyncPeriod: config.ConfigSyncPeriod.Duration, - HealthzServer: healthzServer, + Config: config, + Client: client, + Proxier: proxier, + Broadcaster: eventBroadcaster, + Recorder: recorder, + NodeRef: nodeRef, + HealthzServer: healthzServer, }, nil } diff --git a/pkg/proxy/apis/config/validation/validation.go b/pkg/proxy/apis/config/validation/validation.go index 607a5928aaa..e487e826037 100644 --- a/pkg/proxy/apis/config/validation/validation.go +++ b/pkg/proxy/apis/config/validation/validation.go @@ -95,6 +95,8 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList { allErrs = append(allErrs, validateKubeProxyNodePortAddress(config.NodePortAddresses, newPath.Child("NodePortAddresses"))...) allErrs = append(allErrs, validateShowHiddenMetricsVersion(config.ShowHiddenMetricsForVersion, newPath.Child("ShowHiddenMetricsForVersion"))...) + + allErrs = append(allErrs, validateDetectLocalMode(config.DetectLocalMode, newPath.Child("DetectLocalMode"))...) if config.DetectLocalMode == kubeproxyconfig.LocalModeBridgeInterface { allErrs = append(allErrs, validateInterface(config.DetectLocal.BridgeInterface, newPath.Child("InterfaceName"))...) } @@ -205,6 +207,22 @@ func validateProxyModeWindows(mode kubeproxyconfig.ProxyMode, fldPath *field.Pat return field.ErrorList{field.Invalid(fldPath.Child("ProxyMode"), string(mode), errMsg)} } +func validateDetectLocalMode(mode kubeproxyconfig.LocalMode, fldPath *field.Path) field.ErrorList { + validModes := []string{ + string(kubeproxyconfig.LocalModeClusterCIDR), + string(kubeproxyconfig.LocalModeNodeCIDR), + string(kubeproxyconfig.LocalModeBridgeInterface), + string(kubeproxyconfig.LocalModeInterfaceNamePrefix), + "", + } + + if sets.New(validModes...).Has(string(mode)) { + return nil + } + + return field.ErrorList{field.NotSupported(fldPath, string(mode), validModes)} +} + func validateClientConnectionConfiguration(config componentbaseconfig.ClientConnectionConfiguration, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(config.Burst), fldPath.Child("Burst"))...) diff --git a/pkg/proxy/apis/config/validation/validation_test.go b/pkg/proxy/apis/config/validation/validation_test.go index 8810bc4f1ce..ea040622378 100644 --- a/pkg/proxy/apis/config/validation/validation_test.go +++ b/pkg/proxy/apis/config/validation/validation_test.go @@ -414,6 +414,28 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { }, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("InterfaceName"), "", "must not be empty")}, }, + "invalid DetectLocalMode": { + config: kubeproxyconfig.KubeProxyConfiguration{ + BindAddress: "10.10.12.11", + HealthzBindAddress: "0.0.0.0:12345", + MetricsBindAddress: "127.0.0.1:10249", + ClusterCIDR: "192.168.59.0/24", + ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, + IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ + MasqueradeAll: true, + SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, + MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, + }, + Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ + MaxPerCore: pointer.Int32(1), + Min: pointer.Int32(1), + TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, + TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, + }, + DetectLocalMode: "Guess", + }, + expectedErrs: field.ErrorList{field.NotSupported(newPath.Child("DetectLocalMode"), "Guess", []string{"ClusterCIDR", "NodeCIDR", "BridgeInterface", "InterfaceNamePrefix", ""})}, + }, } for name, testCase := range testCases { diff --git a/pkg/proxy/kubemark/hollow_proxy.go b/pkg/proxy/kubemark/hollow_proxy.go index e87d165b84b..1462c30a84f 100644 --- a/pkg/proxy/kubemark/hollow_proxy.go +++ b/pkg/proxy/kubemark/hollow_proxy.go @@ -22,6 +22,7 @@ import ( v1 "k8s.io/api/core/v1" discoveryv1 "k8s.io/api/discovery/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" clientset "k8s.io/client-go/kubernetes" v1core "k8s.io/client-go/kubernetes/typed/core/v1" @@ -29,6 +30,7 @@ import ( utilsysctl "k8s.io/component-helpers/node/util/sysctl" proxyapp "k8s.io/kubernetes/cmd/kube-proxy/app" "k8s.io/kubernetes/pkg/proxy" + proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/config" proxyconfig "k8s.io/kubernetes/pkg/proxy/config" "k8s.io/kubernetes/pkg/proxy/iptables" proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables" @@ -124,14 +126,17 @@ func NewHollowProxyOrDie( } return &HollowProxy{ ProxyServer: &proxyapp.ProxyServer{ - Client: client, - Proxier: proxier, - Broadcaster: broadcaster, - Recorder: recorder, - ProxyMode: "fake", - NodeRef: nodeRef, - OOMScoreAdj: utilpointer.Int32Ptr(0), - ConfigSyncPeriod: 30 * time.Second, + Config: &proxyconfigapi.KubeProxyConfiguration{ + Mode: proxyconfigapi.ProxyMode("fake"), + ConfigSyncPeriod: metav1.Duration{Duration: 30 * time.Second}, + OOMScoreAdj: utilpointer.Int32Ptr(0), + }, + + Client: client, + Proxier: proxier, + Broadcaster: broadcaster, + Recorder: recorder, + NodeRef: nodeRef, }, }, nil }