Merge pull request #117747 from danwinship/proxy-startup-config

proxy startup-time config handling cleanup (take 2)
This commit is contained in:
Kubernetes Prow Robot 2023-05-04 14:37:24 -07:00 committed by GitHub
commit ff244415ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 186 additions and 261 deletions

View File

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

View File

@ -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()

View File

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

View File

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

View File

@ -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"))...)

View File

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

View File

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