diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index e5414dbb576..7b46b34f2e6 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -47,14 +47,17 @@ import ( "k8s.io/client-go/tools/record" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/componentconfig" - "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/master/ports" "k8s.io/kubernetes/pkg/proxy" - proxyconfig "k8s.io/kubernetes/pkg/proxy/config" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig/scheme" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig/v1alpha1" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig/validation" + "k8s.io/kubernetes/pkg/proxy/config" "k8s.io/kubernetes/pkg/proxy/healthcheck" "k8s.io/kubernetes/pkg/proxy/iptables" "k8s.io/kubernetes/pkg/proxy/ipvs" @@ -93,10 +96,10 @@ type Options struct { CleanupAndExit bool // config is the proxy server's configuration object. - config *componentconfig.KubeProxyConfiguration + config *proxyconfig.KubeProxyConfiguration // The fields below here are placeholders for flags that can't be directly mapped into - // componentconfig.KubeProxyConfiguration. + // proxyconfig.KubeProxyConfiguration. // // TODO remove these fields once the deprecated flags are removed. @@ -161,19 +164,16 @@ func AddFlags(options *Options, fs *pflag.FlagSet) { } func NewOptions() (*Options, error) { + scheme, codecs, err := scheme.NewSchemeAndCodecs() + if err != nil { + return nil, err + } + o := &Options{ - config: new(componentconfig.KubeProxyConfiguration), + config: new(proxyconfig.KubeProxyConfiguration), healthzPort: ports.ProxyHealthzPort, - } - - o.scheme = runtime.NewScheme() - o.codecs = serializer.NewCodecFactory(o.scheme) - - if err := componentconfig.AddToScheme(o.scheme); err != nil { - return nil, err - } - if err := v1alpha1.AddToScheme(o.scheme); err != nil { - return nil, err + scheme: scheme, + codecs: *codecs, } return o, nil @@ -195,7 +195,7 @@ func (o *Options) Validate(args []string) error { return errors.New("no arguments are supported") } - if errs := Validate(o.config); len(errs) != 0 { + if errs := validation.Validate(o.config); len(errs) != 0 { return errs.ToAggregate() } @@ -279,7 +279,7 @@ func (o *Options) applyDeprecatedHealthzPortToConfig() { // loadConfigFromFile loads the contents of file and decodes it as a // KubeProxyConfiguration object. -func (o *Options) loadConfigFromFile(file string) (*componentconfig.KubeProxyConfiguration, error) { +func (o *Options) loadConfigFromFile(file string) (*proxyconfig.KubeProxyConfiguration, error) { data, err := ioutil.ReadFile(file) if err != nil { return nil, err @@ -289,19 +289,19 @@ func (o *Options) loadConfigFromFile(file string) (*componentconfig.KubeProxyCon } // loadConfig decodes data as a KubeProxyConfiguration object. -func (o *Options) loadConfig(data []byte) (*componentconfig.KubeProxyConfiguration, error) { +func (o *Options) loadConfig(data []byte) (*proxyconfig.KubeProxyConfiguration, error) { configObj, gvk, err := o.codecs.UniversalDecoder().Decode(data, nil, nil) if err != nil { return nil, err } - config, ok := configObj.(*componentconfig.KubeProxyConfiguration) + config, ok := configObj.(*proxyconfig.KubeProxyConfiguration) if !ok { return nil, fmt.Errorf("got unexpected config type: %v", gvk) } return config, nil } -func (o *Options) ApplyDefaults(in *componentconfig.KubeProxyConfiguration) (*componentconfig.KubeProxyConfiguration, error) { +func (o *Options) ApplyDefaults(in *proxyconfig.KubeProxyConfiguration) (*proxyconfig.KubeProxyConfiguration, error) { external, err := o.scheme.ConvertToVersion(in, v1alpha1.SchemeGroupVersion) if err != nil { return nil, err @@ -309,12 +309,12 @@ func (o *Options) ApplyDefaults(in *componentconfig.KubeProxyConfiguration) (*co o.scheme.Default(external) - internal, err := o.scheme.ConvertToVersion(external, componentconfig.SchemeGroupVersion) + internal, err := o.scheme.ConvertToVersion(external, proxyconfig.SchemeGroupVersion) if err != nil { return nil, err } - out := internal.(*componentconfig.KubeProxyConfiguration) + out := internal.(*proxyconfig.KubeProxyConfiguration) return out, nil } @@ -367,7 +367,7 @@ type ProxyServer struct { Proxier proxy.ProxyProvider Broadcaster record.EventBroadcaster Recorder record.EventRecorder - ConntrackConfiguration componentconfig.KubeProxyConntrackConfiguration + ConntrackConfiguration proxyconfig.KubeProxyConntrackConfiguration Conntracker Conntracker // if nil, ignored ProxyMode string NodeRef *v1.ObjectReference @@ -377,14 +377,14 @@ type ProxyServer struct { OOMScoreAdj *int32 ResourceContainer string ConfigSyncPeriod time.Duration - ServiceEventHandler proxyconfig.ServiceHandler - EndpointsEventHandler proxyconfig.EndpointsHandler + ServiceEventHandler config.ServiceHandler + EndpointsEventHandler config.EndpointsHandler HealthzServer *healthcheck.HealthzServer } // createClients creates a kube client and an event client from the given config and masterOverride. // TODO remove masterOverride when CLI flags are removed. -func createClients(config componentconfig.ClientConnectionConfiguration, masterOverride string) (clientset.Interface, v1core.EventsGetter, error) { +func createClients(config proxyconfig.ClientConnectionConfiguration, masterOverride string) (clientset.Interface, v1core.EventsGetter, error) { var kubeConfig *rest.Config var err error @@ -532,11 +532,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 := proxyconfig.NewServiceConfig(informerFactory.Core().InternalVersion().Services(), s.ConfigSyncPeriod) + serviceConfig := config.NewServiceConfig(informerFactory.Core().InternalVersion().Services(), s.ConfigSyncPeriod) serviceConfig.RegisterEventHandler(s.ServiceEventHandler) go serviceConfig.Run(wait.NeverStop) - endpointsConfig := proxyconfig.NewEndpointsConfig(informerFactory.Core().InternalVersion().Endpoints(), s.ConfigSyncPeriod) + endpointsConfig := config.NewEndpointsConfig(informerFactory.Core().InternalVersion().Endpoints(), s.ConfigSyncPeriod) endpointsConfig.RegisterEventHandler(s.EndpointsEventHandler) go endpointsConfig.Run(wait.NeverStop) @@ -556,7 +556,7 @@ func (s *ProxyServer) birthCry() { s.Recorder.Eventf(s.NodeRef, api.EventTypeNormal, "Starting", "Starting kube-proxy.") } -func getConntrackMax(config componentconfig.KubeProxyConntrackConfiguration) (int, error) { +func getConntrackMax(config proxyconfig.KubeProxyConntrackConfiguration) (int, error) { if config.Max > 0 { if config.MaxPerCore > 0 { return -1, fmt.Errorf("invalid config: Conntrack Max and Conntrack MaxPerCore are mutually exclusive") diff --git a/cmd/kube-proxy/app/server_others.go b/cmd/kube-proxy/app/server_others.go index 879ffa7f94d..60710f8c6cc 100644 --- a/cmd/kube-proxy/app/server_others.go +++ b/cmd/kube-proxy/app/server_others.go @@ -32,9 +32,9 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/record" - "k8s.io/kubernetes/pkg/apis/componentconfig" "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/proxy" + proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" proxyconfig "k8s.io/kubernetes/pkg/proxy/config" "k8s.io/kubernetes/pkg/proxy/healthcheck" "k8s.io/kubernetes/pkg/proxy/iptables" @@ -53,12 +53,12 @@ import ( ) // NewProxyServer returns a new ProxyServer. -func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndExit bool, scheme *runtime.Scheme, master string) (*ProxyServer, error) { +func NewProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExit bool, scheme *runtime.Scheme, master string) (*ProxyServer, error) { if config == nil { return nil, errors.New("config is required") } - if c, err := configz.New("componentconfig"); err == nil { + if c, err := configz.New("proxyconfig"); err == nil { c.Set(config) } else { return nil, fmt.Errorf("unable to register configz: %s", err) diff --git a/cmd/kube-proxy/app/server_test.go b/cmd/kube-proxy/app/server_test.go index e6e0708064f..16a292a9997 100644 --- a/cmd/kube-proxy/app/server_test.go +++ b/cmd/kube-proxy/app/server_test.go @@ -31,8 +31,8 @@ import ( k8sRuntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/componentconfig" - "k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig/v1alpha1" "k8s.io/kubernetes/pkg/util/configz" "k8s.io/kubernetes/pkg/util/iptables" utilpointer "k8s.io/kubernetes/pkg/util/pointer" @@ -140,7 +140,6 @@ func Test_getProxyMode(t *testing.T) { // TestNewOptionsFailures tests failure modes for NewOptions() func TestNewOptionsFailures(t *testing.T) { - // Create a fake scheme builder that generates an error errString := fmt.Sprintf("Simulated error") genError := func(scheme *k8sRuntime.Scheme) error { @@ -150,8 +149,8 @@ func TestNewOptionsFailures(t *testing.T) { simulatedErrorTest := func(target string) { var addToScheme *func(s *k8sRuntime.Scheme) error - if target == "componentconfig" { - addToScheme = &componentconfig.AddToScheme + if target == "proxyconfig" { + addToScheme = &proxyconfig.AddToScheme } else { addToScheme = &v1alpha1.AddToScheme } @@ -166,7 +165,7 @@ func TestNewOptionsFailures(t *testing.T) { } // Simulate errors in calls to AddToScheme() - faultTargets := []string{"componentconfig", "v1alpha1"} + faultTargets := []string{"proxyconfig", "v1alpha1"} for _, target := range faultTargets { simulatedErrorTest(target) } @@ -185,7 +184,7 @@ func TestProxyServerWithCleanupAndExit(t *testing.T) { t.Fatalf("Unexpected error with address %s: %v", addr, err) } - options.config = &componentconfig.KubeProxyConfiguration{ + options.config = &proxyconfig.KubeProxyConfiguration{ BindAddress: addr, } options.CleanupAndExit = true @@ -198,7 +197,7 @@ func TestProxyServerWithCleanupAndExit(t *testing.T) { assert.True(t, proxyserver.CleanupAndExit, "false CleanupAndExit, addr: %s", addr) // Clean up config for next test case - configz.Delete("componentconfig") + configz.Delete("proxyconfig") } } @@ -242,7 +241,7 @@ func TestGetConntrackMax(t *testing.T) { } for i, tc := range testCases { - cfg := componentconfig.KubeProxyConntrackConfiguration{ + cfg := proxyconfig.KubeProxyConntrackConfiguration{ Min: tc.min, Max: tc.max, MaxPerCore: tc.maxPerCore, @@ -263,7 +262,7 @@ func TestGetConntrackMax(t *testing.T) { // TestLoadConfig tests proper operation of loadConfig() func TestLoadConfig(t *testing.T) { - yamlTemplate := `apiVersion: componentconfig/v1alpha1 + yamlTemplate := `apiVersion: proxyconfig/v1alpha1 bindAddress: %s clientConnection: acceptContentTypes: "abc" @@ -372,9 +371,9 @@ udpTimeoutMilliseconds: 123ms // Surrounding double quotes will get stripped by the yaml parser. expBindAddr = expBindAddr[1 : len(tc.bindAddress)-1] } - expected := &componentconfig.KubeProxyConfiguration{ + expected := &proxyconfig.KubeProxyConfiguration{ BindAddress: expBindAddr, - ClientConnection: componentconfig.ClientConnectionConfiguration{ + ClientConnection: proxyconfig.ClientConnectionConfiguration{ AcceptContentTypes: "abc", Burst: 100, ContentType: "content-type", @@ -383,7 +382,7 @@ udpTimeoutMilliseconds: 123ms }, ClusterCIDR: tc.clusterCIDR, ConfigSyncPeriod: metav1.Duration{Duration: 15 * time.Second}, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: 4, MaxPerCore: 2, Min: 1, @@ -393,18 +392,18 @@ udpTimeoutMilliseconds: 123ms FeatureGates: "all", HealthzBindAddress: tc.healthzBindAddress, HostnameOverride: "foo", - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, MasqueradeBit: utilpointer.Int32Ptr(17), MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second}, SyncPeriod: metav1.Duration{Duration: 60 * time.Second}, }, - IPVS: componentconfig.KubeProxyIPVSConfiguration{ + IPVS: proxyconfig.KubeProxyIPVSConfiguration{ MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second}, SyncPeriod: metav1.Duration{Duration: 60 * time.Second}, }, MetricsBindAddress: tc.metricsBindAddress, - Mode: componentconfig.ProxyMode(tc.mode), + Mode: proxyconfig.ProxyMode(tc.mode), OOMScoreAdj: utilpointer.Int32Ptr(17), PortRange: "2-7", ResourceContainer: "/foo", @@ -440,7 +439,7 @@ func TestLoadConfigFailures(t *testing.T) { { name: "Bad config type test", config: "kind: KubeSchedulerConfiguration", - expErr: "unexpected config type", + expErr: "no kind", }, { name: "Missing quotes around :: bindAddress", @@ -448,7 +447,7 @@ func TestLoadConfigFailures(t *testing.T) { expErr: "mapping values are not allowed in this context", }, } - version := "apiVersion: componentconfig/v1alpha1" + version := "apiVersion: proxyconfig/v1alpha1" for _, tc := range testCases { options, _ := NewOptions() config := fmt.Sprintf("%s\n%s", version, tc.config) diff --git a/cmd/kube-proxy/app/server_windows.go b/cmd/kube-proxy/app/server_windows.go index f4f46386a74..cc7871693f5 100644 --- a/cmd/kube-proxy/app/server_windows.go +++ b/cmd/kube-proxy/app/server_windows.go @@ -31,8 +31,8 @@ import ( "k8s.io/apimachinery/pkg/types" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/client-go/tools/record" - "k8s.io/kubernetes/pkg/apis/componentconfig" "k8s.io/kubernetes/pkg/proxy" + proxyconfigapi "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" proxyconfig "k8s.io/kubernetes/pkg/proxy/config" "k8s.io/kubernetes/pkg/proxy/healthcheck" "k8s.io/kubernetes/pkg/proxy/winkernel" @@ -46,12 +46,12 @@ import ( ) // NewProxyServer returns a new ProxyServer. -func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndExit bool, scheme *runtime.Scheme, master string) (*ProxyServer, error) { +func NewProxyServer(config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExit bool, scheme *runtime.Scheme, master string) (*ProxyServer, error) { if config == nil { return nil, errors.New("config is required") } - if c, err := configz.New("componentconfig"); err == nil { + if c, err := configz.New("proxyconfig"); err == nil { c.Set(config) } else { return nil, fmt.Errorf("unable to register configz: %s", err) diff --git a/pkg/apis/componentconfig/helpers.go b/pkg/apis/componentconfig/helpers.go index 39fc082da0d..a39ec138c81 100644 --- a/pkg/apis/componentconfig/helpers.go +++ b/pkg/apis/componentconfig/helpers.go @@ -61,22 +61,6 @@ func (v IPVar) Type() string { return "ip" } -func (m *ProxyMode) Set(s string) error { - *m = ProxyMode(s) - return nil -} - -func (m *ProxyMode) String() string { - if m != nil { - return string(*m) - } - return "" -} - -func (m *ProxyMode) Type() string { - return "ProxyMode" -} - type PortRangeVar struct { Val *string } diff --git a/pkg/apis/componentconfig/register.go b/pkg/apis/componentconfig/register.go index 53675741352..7ba52b1f68e 100644 --- a/pkg/apis/componentconfig/register.go +++ b/pkg/apis/componentconfig/register.go @@ -45,7 +45,6 @@ func Resource(resource string) schema.GroupResource { func addKnownTypes(scheme *runtime.Scheme) error { // TODO this will get cleaned up with the scheme types are fixed scheme.AddKnownTypes(SchemeGroupVersion, - &KubeProxyConfiguration{}, &KubeSchedulerConfiguration{}, ) return nil diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go index ca321ac9b61..e9d1b33a423 100644 --- a/pkg/apis/componentconfig/types.go +++ b/pkg/apis/componentconfig/types.go @@ -20,189 +20,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// ClientConnectionConfiguration contains details for constructing a client. -type ClientConnectionConfiguration struct { - // kubeConfigFile is the path to a kubeconfig file. - KubeConfigFile string - // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the - // default value of 'application/json'. This field will control all connections to the server used by a particular - // client. - AcceptContentTypes string - // contentType is the content type used when sending data to the server from this client. - ContentType string - // qps controls the number of queries per second allowed for this connection. - QPS float32 - // burst allows extra queries to accumulate when a client is exceeding its rate. - Burst int -} - -// KubeProxyIPTablesConfiguration contains iptables-related configuration -// details for the Kubernetes proxy server. -type KubeProxyIPTablesConfiguration struct { - // masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using - // the pure iptables proxy mode. Values must be within the range [0, 31]. - MasqueradeBit *int32 - // masqueradeAll tells kube-proxy to SNAT everything if using the pure iptables proxy mode. - MasqueradeAll bool - // syncPeriod is the period that iptables rules are refreshed (e.g. '5s', '1m', - // '2h22m'). Must be greater than 0. - SyncPeriod metav1.Duration - // minSyncPeriod is the minimum period that iptables rules are refreshed (e.g. '5s', '1m', - // '2h22m'). - 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 -// the Kubernetes proxy server. -type KubeProxyConntrackConfiguration struct { - // max is the maximum number of NAT connections to track (0 to - // leave as-is). This takes precedence over conntrackMaxPerCore and conntrackMin. - Max int32 - // maxPerCore is the maximum number of NAT connections to track - // per CPU core (0 to leave the limit as-is and ignore conntrackMin). - MaxPerCore int32 - // min is the minimum value of connect-tracking records to allocate, - // regardless of conntrackMaxPerCore (set conntrackMaxPerCore=0 to leave the limit as-is). - Min int32 - // tcpEstablishedTimeout is how long an idle TCP connection will be kept open - // (e.g. '2s'). Must be greater than 0. - TCPEstablishedTimeout metav1.Duration - // tcpCloseWaitTimeout is how long an idle conntrack entry - // in CLOSE_WAIT state will remain in the conntrack - // table. (e.g. '60s'). Must be greater than 0 to set. - TCPCloseWaitTimeout metav1.Duration -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// KubeProxyConfiguration contains everything necessary to configure the -// Kubernetes proxy server. -type KubeProxyConfiguration struct { - metav1.TypeMeta - - // featureGates is a comma-separated list of key=value pairs that control - // which alpha/beta features are enabled. - // - // TODO this really should be a map but that requires refactoring all - // components to use config files because local-up-cluster.sh only supports - // the --feature-gates flag right now, which is comma-separated key=value - // pairs. - FeatureGates string - - // bindAddress is the IP address for the proxy server to serve on (set to 0.0.0.0 - // for all interfaces) - BindAddress string - // healthzBindAddress is the IP address and port for the health check server to serve on, - // defaulting to 0.0.0.0:10256 - HealthzBindAddress string - // metricsBindAddress is the IP address and port for the metrics server to serve on, - // defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces) - MetricsBindAddress string - // enableProfiling enables profiling via web interface on /debug/pprof handler. - // Profiling handlers will be handled by metrics server. - EnableProfiling bool - // clusterCIDR is the CIDR range of the 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. - ClusterCIDR string - // hostnameOverride, if non-empty, will be used as the identity instead of the actual hostname. - HostnameOverride string - // clientConnection specifies the kubeconfig file and client connection settings for the proxy - // server to use when communicating with the apiserver. - ClientConnection ClientConnectionConfiguration - // iptables contains iptables-related configuration options. - 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 - // the range [-1000, 1000] - OOMScoreAdj *int32 - // mode specifies which proxy mode to use. - Mode ProxyMode - // portRange is the 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. - PortRange string - // resourceContainer is the absolute name of the resource-only container to create and run - // the Kube-proxy in (Default: /kube-proxy). - ResourceContainer string - // udpIdleTimeout is how long an idle UDP connection will be kept open (e.g. '250ms', '2s'). - // Must be greater than 0. Only applicable for proxyMode=userspace. - UDPIdleTimeout metav1.Duration - // conntrack contains conntrack-related configuration options. - Conntrack KubeProxyConntrackConfiguration - // configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater - // than 0. - ConfigSyncPeriod metav1.Duration -} - -// Currently two modes of proxying are available: 'userspace' (older, stable) or 'iptables' -// (newer, faster). If blank, use the best-available proxy (currently iptables, but may -// change in future versions). 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. -type ProxyMode string - -const ( - ProxyModeUserspace ProxyMode = "userspace" - ProxyModeIPTables ProxyMode = "iptables" - ProxyModeIPVS ProxyMode = "ipvs" -) - -// IPVSSchedulerMethod is the algorithm for allocating TCP connections and -// UDP datagrams to real servers. Scheduling algorithms are imple- -//wanted as kernel modules. Ten are shipped with the Linux Virtual Server. -type IPVSSchedulerMethod string - -const ( - // Robin Robin distributes jobs equally amongst the available real servers. - RoundRobin IPVSSchedulerMethod = "rr" - // Weighted Round Robin assigns jobs to real servers proportionally to there real servers' weight. - // Servers with higher weights receive new jobs first and get more jobs than servers with lower weights. - // Servers with equal weights get an equal distribution of new jobs. - WeightedRoundRobin IPVSSchedulerMethod = "wrr" - // Least Connection assigns more jobs to real servers with fewer active jobs. - LeastConnection IPVSSchedulerMethod = "lc" - // Weighted Least Connection assigns more jobs to servers with fewer jobs and - // relative to the real servers’weight(Ci/Wi). - WeightedLeastConnection IPVSSchedulerMethod = "wlc" - // Locality Based Least Connection assigns jobs destined for the same IP address to the same server if - // the server is not overloaded and available; otherwise assign jobs to servers with fewer jobs, - // and keep it for future assignment. - LocalityBasedLeastConnection IPVSSchedulerMethod = "lblc" - // Locality Based Least Connection with Replication assigns jobs destined for the same IP address to the - // least-connection node in the server set for the IP address. If all the node in the server set are over loaded, - // it picks up a node with fewer jobs in the cluster and adds it in the sever set for the target. - // If the server set has not been modified for the specified time, the most loaded node is removed from the server set, - // in order to avoid high degree of replication. - LocalityBasedLeastConnectionWithReplication IPVSSchedulerMethod = "lblcr" - // Source Hashing assigns jobs to servers through looking up a statically assigned hash table - // by their source IP addresses. - SourceHashing IPVSSchedulerMethod = "sh" - // Destination Hashing assigns jobs to servers through looking up a statically assigned hash table - // by their destination IP addresses. - DestinationHashing IPVSSchedulerMethod = "dh" - // Shortest Expected Delay assigns an incoming job to the server with the shortest expected delay. - // The expected delay that the job will experience is (Ci + 1) / Ui if sent to the ith server, in which - // Ci is the number of jobs on the the ith server and Ui is the fixed service rate (weight) of the ith server. - ShortestExpectedDelay IPVSSchedulerMethod = "sed" - // Never Queue assigns an incoming job to an idle server if there is, instead of waiting for a fast one; - // if all the servers are busy, it adopts the Shortest Expected Delay policy to assign the job. - NeverQueue IPVSSchedulerMethod = "nq" -) - // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type KubeSchedulerConfiguration struct { diff --git a/pkg/apis/componentconfig/v1alpha1/defaults.go b/pkg/apis/componentconfig/v1alpha1/defaults.go index f5bc328e617..59cadbe100a 100644 --- a/pkg/apis/componentconfig/v1alpha1/defaults.go +++ b/pkg/apis/componentconfig/v1alpha1/defaults.go @@ -17,15 +17,12 @@ limitations under the License. package v1alpha1 import ( - "fmt" - "strings" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/kubernetes/pkg/api" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" - "k8s.io/kubernetes/pkg/kubelet/qos" "k8s.io/kubernetes/pkg/master/ports" ) @@ -33,92 +30,6 @@ func addDefaultingFuncs(scheme *kruntime.Scheme) error { return RegisterDefaults(scheme) } -func SetDefaults_KubeProxyConfiguration(obj *KubeProxyConfiguration) { - if len(obj.BindAddress) == 0 { - obj.BindAddress = "0.0.0.0" - } - if obj.HealthzBindAddress == "" { - obj.HealthzBindAddress = fmt.Sprintf("0.0.0.0:%v", ports.ProxyHealthzPort) - } else if !strings.Contains(obj.HealthzBindAddress, ":") { - obj.HealthzBindAddress += fmt.Sprintf(":%v", ports.ProxyHealthzPort) - } - if obj.MetricsBindAddress == "" { - obj.MetricsBindAddress = fmt.Sprintf("127.0.0.1:%v", ports.ProxyStatusPort) - } else if !strings.Contains(obj.MetricsBindAddress, ":") { - obj.MetricsBindAddress += fmt.Sprintf(":%v", ports.ProxyStatusPort) - } - if obj.OOMScoreAdj == nil { - temp := int32(qos.KubeProxyOOMScoreAdj) - obj.OOMScoreAdj = &temp - } - if obj.ResourceContainer == "" { - obj.ResourceContainer = "/kube-proxy" - } - if obj.IPTables.SyncPeriod.Duration == 0 { - obj.IPTables.SyncPeriod = metav1.Duration{Duration: 30 * time.Second} - } - if obj.IPVS.SyncPeriod.Duration == 0 { - obj.IPVS.SyncPeriod = metav1.Duration{Duration: 30 * time.Second} - } - zero := metav1.Duration{} - if obj.UDPIdleTimeout == zero { - obj.UDPIdleTimeout = metav1.Duration{Duration: 250 * time.Millisecond} - } - // If ConntrackMax is set, respect it. - if obj.Conntrack.Max == 0 { - // If ConntrackMax is *not* set, use per-core scaling. - if obj.Conntrack.MaxPerCore == 0 { - obj.Conntrack.MaxPerCore = 32 * 1024 - } - if obj.Conntrack.Min == 0 { - obj.Conntrack.Min = 128 * 1024 - } - } - if obj.IPTables.MasqueradeBit == nil { - temp := int32(14) - obj.IPTables.MasqueradeBit = &temp - } - if obj.Conntrack.TCPEstablishedTimeout == zero { - obj.Conntrack.TCPEstablishedTimeout = metav1.Duration{Duration: 24 * time.Hour} // 1 day (1/5 default) - } - if obj.Conntrack.TCPCloseWaitTimeout == zero { - // See https://github.com/kubernetes/kubernetes/issues/32551. - // - // CLOSE_WAIT conntrack state occurs when the Linux kernel - // sees a FIN from the remote server. Note: this is a half-close - // condition that persists as long as the local side keeps the - // socket open. The condition is rare as it is typical in most - // protocols for both sides to issue a close; this typically - // occurs when the local socket is lazily garbage collected. - // - // If the CLOSE_WAIT conntrack entry expires, then FINs from the - // local socket will not be properly SNAT'd and will not reach the - // remote server (if the connection was subject to SNAT). If the - // remote timeouts for FIN_WAIT* states exceed the CLOSE_WAIT - // timeout, then there will be an inconsistency in the state of - // the connection and a new connection reusing the SNAT (src, - // port) pair may be rejected by the remote side with RST. This - // can cause new calls to connect(2) to return with ECONNREFUSED. - // - // We set CLOSE_WAIT to one hour by default to better match - // typical server timeouts. - obj.Conntrack.TCPCloseWaitTimeout = metav1.Duration{Duration: 1 * time.Hour} - } - if obj.ConfigSyncPeriod.Duration == 0 { - obj.ConfigSyncPeriod.Duration = 15 * time.Minute - } - - if len(obj.ClientConnection.ContentType) == 0 { - obj.ClientConnection.ContentType = "application/vnd.kubernetes.protobuf" - } - if obj.ClientConnection.QPS == 0.0 { - obj.ClientConnection.QPS = 5.0 - } - if obj.ClientConnection.Burst == 0 { - obj.ClientConnection.Burst = 10 - } -} - func SetDefaults_KubeSchedulerConfiguration(obj *KubeSchedulerConfiguration) { if obj.Port == 0 { obj.Port = ports.SchedulerPort @@ -174,7 +85,3 @@ func SetDefaults_LeaderElectionConfiguration(obj *LeaderElectionConfiguration) { obj.ResourceLock = "endpoints" } } - -func boolVar(b bool) *bool { - return &b -} diff --git a/pkg/apis/componentconfig/v1alpha1/register.go b/pkg/apis/componentconfig/v1alpha1/register.go index a75096f20fb..693ff3a3511 100644 --- a/pkg/apis/componentconfig/v1alpha1/register.go +++ b/pkg/apis/componentconfig/v1alpha1/register.go @@ -44,7 +44,6 @@ func init() { func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &KubeProxyConfiguration{}, &KubeSchedulerConfiguration{}, ) return nil diff --git a/pkg/apis/componentconfig/v1alpha1/types.go b/pkg/apis/componentconfig/v1alpha1/types.go index 70654ca8c9e..9e559d41293 100644 --- a/pkg/apis/componentconfig/v1alpha1/types.go +++ b/pkg/apis/componentconfig/v1alpha1/types.go @@ -20,146 +20,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// ClientConnectionConfiguration contains details for constructing a client. -type ClientConnectionConfiguration struct { - // kubeConfigFile is the path to a kubeconfig file. - KubeConfigFile string `json:"kubeconfig"` - // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the - // default value of 'application/json'. This field will control all connections to the server used by a particular - // client. - AcceptContentTypes string `json:"acceptContentTypes"` - // contentType is the content type used when sending data to the server from this client. - ContentType string `json:"contentType"` - // cps controls the number of queries per second allowed for this connection. - QPS float32 `json:"qps"` - // burst allows extra queries to accumulate when a client is exceeding its rate. - Burst int `json:"burst"` -} - -// KubeProxyIPTablesConfiguration contains iptables-related configuration -// details for the Kubernetes proxy server. -type KubeProxyIPTablesConfiguration struct { - // masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using - // the pure iptables proxy mode. Values must be within the range [0, 31]. - MasqueradeBit *int32 `json:"masqueradeBit"` - // masqueradeAll tells kube-proxy to SNAT everything if using the pure iptables proxy mode. - MasqueradeAll bool `json:"masqueradeAll"` - // syncPeriod is the period that iptables rules are refreshed (e.g. '5s', '1m', - // '2h22m'). Must be greater than 0. - SyncPeriod metav1.Duration `json:"syncPeriod"` - // minSyncPeriod is the minimum period that iptables rules are refreshed (e.g. '5s', '1m', - // '2h22m'). - 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 -// the Kubernetes proxy server. -type KubeProxyConntrackConfiguration struct { - // max is the maximum number of NAT connections to track (0 to - // leave as-is). This takes precedence over conntrackMaxPerCore and conntrackMin. - Max int32 `json:"max"` - // maxPerCore is the maximum number of NAT connections to track - // per CPU core (0 to leave the limit as-is and ignore conntrackMin). - MaxPerCore int32 `json:"maxPerCore"` - // min is the minimum value of connect-tracking records to allocate, - // regardless of conntrackMaxPerCore (set conntrackMaxPerCore=0 to leave the limit as-is). - Min int32 `json:"min"` - // tcpEstablishedTimeout is how long an idle TCP connection will be kept open - // (e.g. '2s'). Must be greater than 0. - TCPEstablishedTimeout metav1.Duration `json:"tcpEstablishedTimeout"` - // tcpCloseWaitTimeout is how long an idle conntrack entry - // in CLOSE_WAIT state will remain in the conntrack - // table. (e.g. '60s'). Must be greater than 0 to set. - TCPCloseWaitTimeout metav1.Duration `json:"tcpCloseWaitTimeout"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// KubeProxyConfiguration contains everything necessary to configure the -// Kubernetes proxy server. -type KubeProxyConfiguration struct { - metav1.TypeMeta `json:",inline"` - - // featureGates is a comma-separated list of key=value pairs that control - // which alpha/beta features are enabled. - // - // TODO this really should be a map but that requires refactoring all - // components to use config files because local-up-cluster.sh only supports - // the --feature-gates flag right now, which is comma-separated key=value - // pairs. - FeatureGates string `json:"featureGates"` - - // bindAddress is the IP address for the proxy server to serve on (set to 0.0.0.0 - // for all interfaces) - BindAddress string `json:"bindAddress"` - // healthzBindAddress is the IP address and port for the health check server to serve on, - // defaulting to 0.0.0.0:10256 - HealthzBindAddress string `json:"healthzBindAddress"` - // metricsBindAddress is the IP address and port for the metrics server to serve on, - // defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces) - MetricsBindAddress string `json:"metricsBindAddress"` - // enableProfiling enables profiling via web interface on /debug/pprof handler. - // Profiling handlers will be handled by metrics server. - EnableProfiling bool `json:"enableProfiling"` - // clusterCIDR is the CIDR range of the 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. - ClusterCIDR string `json:"clusterCIDR"` - // hostnameOverride, if non-empty, will be used as the identity instead of the actual hostname. - HostnameOverride string `json:"hostnameOverride"` - // clientConnection specifies the kubeconfig file and client connection settings for the proxy - // server to use when communicating with the apiserver. - ClientConnection ClientConnectionConfiguration `json:"clientConnection"` - // iptables contains iptables-related configuration options. - 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 - // the range [-1000, 1000] - OOMScoreAdj *int32 `json:"oomScoreAdj"` - // mode specifies which proxy mode to use. - Mode ProxyMode `json:"mode"` - // portRange is the 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. - PortRange string `json:"portRange"` - // resourceContainer is the bsolute name of the resource-only container to create and run - // the Kube-proxy in (Default: /kube-proxy). - ResourceContainer string `json:"resourceContainer"` - // udpIdleTimeout is how long an idle UDP connection will be kept open (e.g. '250ms', '2s'). - // Must be greater than 0. Only applicable for proxyMode=userspace. - UDPIdleTimeout metav1.Duration `json:"udpTimeoutMilliseconds"` - // conntrack contains conntrack-related configuration options. - Conntrack KubeProxyConntrackConfiguration `json:"conntrack"` - // configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater - // than 0. - ConfigSyncPeriod metav1.Duration `json:"configSyncPeriod"` -} - -// Currently two modes of proxying are available: 'userspace' (older, stable) or 'iptables' -// (newer, faster). If blank, use the best-available proxy (currently iptables, but may -// change in future versions). 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. -type ProxyMode string - -const ( - ProxyModeUserspace ProxyMode = "userspace" - ProxyModeIPTables ProxyMode = "iptables" -) - // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type KubeSchedulerConfiguration struct { diff --git a/pkg/proxy/apis/proxyconfig/OWNERS b/pkg/proxy/apis/proxyconfig/OWNERS new file mode 100644 index 00000000000..34823356d22 --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/OWNERS @@ -0,0 +1,4 @@ +approvers: +- thockin +reviewers: +- sig-network-reviewers diff --git a/pkg/proxy/apis/proxyconfig/doc.go b/pkg/proxy/apis/proxyconfig/doc.go new file mode 100644 index 00000000000..efbe2a12a19 --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package,register + +package proxyconfig // import "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" diff --git a/pkg/proxy/apis/proxyconfig/register.go b/pkg/proxy/apis/proxyconfig/register.go new file mode 100644 index 00000000000..23bf4a7ac7d --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/register.go @@ -0,0 +1,51 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package proxyconfig + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// GroupName is the group name use in this package +const GroupName = "proxyconfig" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +func addKnownTypes(scheme *runtime.Scheme) error { + // TODO this will get cleaned up with the scheme types are fixed + scheme.AddKnownTypes(SchemeGroupVersion, + &KubeProxyConfiguration{}, + ) + return nil +} diff --git a/pkg/proxy/apis/proxyconfig/scheme/scheme.go b/pkg/proxy/apis/proxyconfig/scheme/scheme.go new file mode 100644 index 00000000000..e6d2ae89e78 --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/scheme/scheme.go @@ -0,0 +1,40 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package scheme + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig/v1alpha1" +) + +// Utility functions for the Kube-proxy's proxyconfig API group + +// NewSchemeAndCodecs is a utility funciton that returns a Scheme and CodecFactory +// that understand the types in the proxyconfig API group. +func NewSchemeAndCodecs() (*runtime.Scheme, *serializer.CodecFactory, error) { + scheme := runtime.NewScheme() + if err := proxyconfig.AddToScheme(scheme); err != nil { + return nil, nil, err + } + if err := v1alpha1.AddToScheme(scheme); err != nil { + return nil, nil, err + } + codecs := serializer.NewCodecFactory(scheme) + return scheme, &codecs, nil +} diff --git a/pkg/proxy/apis/proxyconfig/types.go b/pkg/proxy/apis/proxyconfig/types.go new file mode 100644 index 00000000000..03420c7857c --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/types.go @@ -0,0 +1,254 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package proxyconfig + +import ( + "fmt" + "sort" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ClientConnectionConfiguration contains details for constructing a client. +type ClientConnectionConfiguration struct { + // kubeConfigFile is the path to a kubeconfig file. + KubeConfigFile string + // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the + // default value of 'application/json'. This field will control all connections to the server used by a particular + // client. + AcceptContentTypes string + // contentType is the content type used when sending data to the server from this client. + ContentType string + // qps controls the number of queries per second allowed for this connection. + QPS float32 + // burst allows extra queries to accumulate when a client is exceeding its rate. + Burst int +} + +// KubeProxyIPTablesConfiguration contains iptables-related configuration +// details for the Kubernetes proxy server. +type KubeProxyIPTablesConfiguration struct { + // masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using + // the pure iptables proxy mode. Values must be within the range [0, 31]. + MasqueradeBit *int32 + // masqueradeAll tells kube-proxy to SNAT everything if using the pure iptables proxy mode. + MasqueradeAll bool + // syncPeriod is the period that iptables rules are refreshed (e.g. '5s', '1m', + // '2h22m'). Must be greater than 0. + SyncPeriod metav1.Duration + // minSyncPeriod is the minimum period that iptables rules are refreshed (e.g. '5s', '1m', + // '2h22m'). + 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 +// the Kubernetes proxy server. +type KubeProxyConntrackConfiguration struct { + // max is the maximum number of NAT connections to track (0 to + // leave as-is). This takes precedence over conntrackMaxPerCore and conntrackMin. + Max int32 + // maxPerCore is the maximum number of NAT connections to track + // per CPU core (0 to leave the limit as-is and ignore conntrackMin). + MaxPerCore int32 + // min is the minimum value of connect-tracking records to allocate, + // regardless of conntrackMaxPerCore (set conntrackMaxPerCore=0 to leave the limit as-is). + Min int32 + // tcpEstablishedTimeout is how long an idle TCP connection will be kept open + // (e.g. '2s'). Must be greater than 0. + TCPEstablishedTimeout metav1.Duration + // tcpCloseWaitTimeout is how long an idle conntrack entry + // in CLOSE_WAIT state will remain in the conntrack + // table. (e.g. '60s'). Must be greater than 0 to set. + TCPCloseWaitTimeout metav1.Duration +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// KubeProxyConfiguration contains everything necessary to configure the +// Kubernetes proxy server. +type KubeProxyConfiguration struct { + metav1.TypeMeta + + // featureGates is a comma-separated list of key=value pairs that control + // which alpha/beta features are enabled. + // + // TODO this really should be a map but that requires refactoring all + // components to use config files because local-up-cluster.sh only supports + // the --feature-gates flag right now, which is comma-separated key=value + // pairs. + FeatureGates string + + // bindAddress is the IP address for the proxy server to serve on (set to 0.0.0.0 + // for all interfaces) + BindAddress string + // healthzBindAddress is the IP address and port for the health check server to serve on, + // defaulting to 0.0.0.0:10256 + HealthzBindAddress string + // metricsBindAddress is the IP address and port for the metrics server to serve on, + // defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces) + MetricsBindAddress string + // enableProfiling enables profiling via web interface on /debug/pprof handler. + // Profiling handlers will be handled by metrics server. + EnableProfiling bool + // clusterCIDR is the CIDR range of the 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. + ClusterCIDR string + // hostnameOverride, if non-empty, will be used as the identity instead of the actual hostname. + HostnameOverride string + // clientConnection specifies the kubeconfig file and client connection settings for the proxy + // server to use when communicating with the apiserver. + ClientConnection ClientConnectionConfiguration + // iptables contains iptables-related configuration options. + 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 + // the range [-1000, 1000] + OOMScoreAdj *int32 + // mode specifies which proxy mode to use. + Mode ProxyMode + // portRange is the 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. + PortRange string + // resourceContainer is the absolute name of the resource-only container to create and run + // the Kube-proxy in (Default: /kube-proxy). + ResourceContainer string + // udpIdleTimeout is how long an idle UDP connection will be kept open (e.g. '250ms', '2s'). + // Must be greater than 0. Only applicable for proxyMode=userspace. + UDPIdleTimeout metav1.Duration + // conntrack contains conntrack-related configuration options. + Conntrack KubeProxyConntrackConfiguration + // configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater + // than 0. + ConfigSyncPeriod metav1.Duration +} + +// Currently two modes of proxying are available: 'userspace' (older, stable) or 'iptables' +// (newer, faster). If blank, use the best-available proxy (currently iptables, but may +// change in future versions). 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. +type ProxyMode string + +const ( + ProxyModeUserspace ProxyMode = "userspace" + ProxyModeIPTables ProxyMode = "iptables" + ProxyModeIPVS ProxyMode = "ipvs" +) + +// IPVSSchedulerMethod is the algorithm for allocating TCP connections and +// UDP datagrams to real servers. Scheduling algorithms are imple- +//wanted as kernel modules. Ten are shipped with the Linux Virtual Server. +type IPVSSchedulerMethod string + +const ( + // Robin Robin distributes jobs equally amongst the available real servers. + RoundRobin IPVSSchedulerMethod = "rr" + // Weighted Round Robin assigns jobs to real servers proportionally to there real servers' weight. + // Servers with higher weights receive new jobs first and get more jobs than servers with lower weights. + // Servers with equal weights get an equal distribution of new jobs. + WeightedRoundRobin IPVSSchedulerMethod = "wrr" + // Least Connection assigns more jobs to real servers with fewer active jobs. + LeastConnection IPVSSchedulerMethod = "lc" + // Weighted Least Connection assigns more jobs to servers with fewer jobs and + // relative to the real servers’weight(Ci/Wi). + WeightedLeastConnection IPVSSchedulerMethod = "wlc" + // Locality Based Least Connection assigns jobs destined for the same IP address to the same server if + // the server is not overloaded and available; otherwise assign jobs to servers with fewer jobs, + // and keep it for future assignment. + LocalityBasedLeastConnection IPVSSchedulerMethod = "lblc" + // Locality Based Least Connection with Replication assigns jobs destined for the same IP address to the + // least-connection node in the server set for the IP address. If all the node in the server set are over loaded, + // it picks up a node with fewer jobs in the cluster and adds it in the sever set for the target. + // If the server set has not been modified for the specified time, the most loaded node is removed from the server set, + // in order to avoid high degree of replication. + LocalityBasedLeastConnectionWithReplication IPVSSchedulerMethod = "lblcr" + // Source Hashing assigns jobs to servers through looking up a statically assigned hash table + // by their source IP addresses. + SourceHashing IPVSSchedulerMethod = "sh" + // Destination Hashing assigns jobs to servers through looking up a statically assigned hash table + // by their destination IP addresses. + DestinationHashing IPVSSchedulerMethod = "dh" + // Shortest Expected Delay assigns an incoming job to the server with the shortest expected delay. + // The expected delay that the job will experience is (Ci + 1) / Ui if sent to the ith server, in which + // Ci is the number of jobs on the the ith server and Ui is the fixed service rate (weight) of the ith server. + ShortestExpectedDelay IPVSSchedulerMethod = "sed" + // Never Queue assigns an incoming job to an idle server if there is, instead of waiting for a fast one; + // if all the servers are busy, it adopts the Shortest Expected Delay policy to assign the job. + NeverQueue IPVSSchedulerMethod = "nq" +) + +func (m *ProxyMode) Set(s string) error { + *m = ProxyMode(s) + return nil +} + +func (m *ProxyMode) String() string { + if m != nil { + return string(*m) + } + return "" +} + +func (m *ProxyMode) Type() string { + return "ProxyMode" +} + +type ConfigurationMap map[string]string + +func (m *ConfigurationMap) String() string { + pairs := []string{} + for k, v := range *m { + pairs = append(pairs, fmt.Sprintf("%s=%s", k, v)) + } + sort.Strings(pairs) + return strings.Join(pairs, ",") +} + +func (m *ConfigurationMap) Set(value string) error { + for _, s := range strings.Split(value, ",") { + if len(s) == 0 { + continue + } + arr := strings.SplitN(s, "=", 2) + if len(arr) == 2 { + (*m)[strings.TrimSpace(arr[0])] = strings.TrimSpace(arr[1]) + } else { + (*m)[strings.TrimSpace(arr[0])] = "" + } + } + return nil +} + +func (*ConfigurationMap) Type() string { + return "mapStringString" +} diff --git a/pkg/proxy/apis/proxyconfig/v1alpha1/defaults.go b/pkg/proxy/apis/proxyconfig/v1alpha1/defaults.go new file mode 100644 index 00000000000..1378b7bfc8b --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/v1alpha1/defaults.go @@ -0,0 +1,118 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "fmt" + "strings" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/kubernetes/pkg/kubelet/qos" + "k8s.io/kubernetes/pkg/master/ports" +) + +func addDefaultingFuncs(scheme *kruntime.Scheme) error { + return RegisterDefaults(scheme) +} + +func SetDefaults_KubeProxyConfiguration(obj *KubeProxyConfiguration) { + if len(obj.BindAddress) == 0 { + obj.BindAddress = "0.0.0.0" + } + if obj.HealthzBindAddress == "" { + obj.HealthzBindAddress = fmt.Sprintf("0.0.0.0:%v", ports.ProxyHealthzPort) + } else if !strings.Contains(obj.HealthzBindAddress, ":") { + obj.HealthzBindAddress += fmt.Sprintf(":%v", ports.ProxyHealthzPort) + } + if obj.MetricsBindAddress == "" { + obj.MetricsBindAddress = fmt.Sprintf("127.0.0.1:%v", ports.ProxyStatusPort) + } else if !strings.Contains(obj.MetricsBindAddress, ":") { + obj.MetricsBindAddress += fmt.Sprintf(":%v", ports.ProxyStatusPort) + } + if obj.OOMScoreAdj == nil { + temp := int32(qos.KubeProxyOOMScoreAdj) + obj.OOMScoreAdj = &temp + } + if obj.ResourceContainer == "" { + obj.ResourceContainer = "/kube-proxy" + } + if obj.IPTables.SyncPeriod.Duration == 0 { + obj.IPTables.SyncPeriod = metav1.Duration{Duration: 30 * time.Second} + } + if obj.IPVS.SyncPeriod.Duration == 0 { + obj.IPVS.SyncPeriod = metav1.Duration{Duration: 30 * time.Second} + } + zero := metav1.Duration{} + if obj.UDPIdleTimeout == zero { + obj.UDPIdleTimeout = metav1.Duration{Duration: 250 * time.Millisecond} + } + // If ConntrackMax is set, respect it. + if obj.Conntrack.Max == 0 { + // If ConntrackMax is *not* set, use per-core scaling. + if obj.Conntrack.MaxPerCore == 0 { + obj.Conntrack.MaxPerCore = 32 * 1024 + } + if obj.Conntrack.Min == 0 { + obj.Conntrack.Min = 128 * 1024 + } + } + if obj.IPTables.MasqueradeBit == nil { + temp := int32(14) + obj.IPTables.MasqueradeBit = &temp + } + if obj.Conntrack.TCPEstablishedTimeout == zero { + obj.Conntrack.TCPEstablishedTimeout = metav1.Duration{Duration: 24 * time.Hour} // 1 day (1/5 default) + } + if obj.Conntrack.TCPCloseWaitTimeout == zero { + // See https://github.com/kubernetes/kubernetes/issues/32551. + // + // CLOSE_WAIT conntrack state occurs when the Linux kernel + // sees a FIN from the remote server. Note: this is a half-close + // condition that persists as long as the local side keeps the + // socket open. The condition is rare as it is typical in most + // protocols for both sides to issue a close; this typically + // occurs when the local socket is lazily garbage collected. + // + // If the CLOSE_WAIT conntrack entry expires, then FINs from the + // local socket will not be properly SNAT'd and will not reach the + // remote server (if the connection was subject to SNAT). If the + // remote timeouts for FIN_WAIT* states exceed the CLOSE_WAIT + // timeout, then there will be an inconsistency in the state of + // the connection and a new connection reusing the SNAT (src, + // port) pair may be rejected by the remote side with RST. This + // can cause new calls to connect(2) to return with ECONNREFUSED. + // + // We set CLOSE_WAIT to one hour by default to better match + // typical server timeouts. + obj.Conntrack.TCPCloseWaitTimeout = metav1.Duration{Duration: 1 * time.Hour} + } + if obj.ConfigSyncPeriod.Duration == 0 { + obj.ConfigSyncPeriod.Duration = 15 * time.Minute + } + + if len(obj.ClientConnection.ContentType) == 0 { + obj.ClientConnection.ContentType = "application/vnd.kubernetes.protobuf" + } + if obj.ClientConnection.QPS == 0.0 { + obj.ClientConnection.QPS = 5.0 + } + if obj.ClientConnection.Burst == 0 { + obj.ClientConnection.Burst = 10 + } +} diff --git a/pkg/proxy/apis/proxyconfig/v1alpha1/doc.go b/pkg/proxy/apis/proxyconfig/v1alpha1/doc.go new file mode 100644 index 00000000000..4e48f370605 --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/v1alpha1/doc.go @@ -0,0 +1,22 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=k8s.io/kubernetes/pkg/proxy/apis/proxyconfig +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta + +package v1alpha1 // import "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig/v1alpha1" diff --git a/pkg/proxy/apis/proxyconfig/v1alpha1/register.go b/pkg/proxy/apis/proxyconfig/v1alpha1/register.go new file mode 100644 index 00000000000..813f2cc6066 --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/v1alpha1/register.go @@ -0,0 +1,50 @@ +/* +Copyright 2015 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "proxyconfig" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +var ( + // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. + // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs) +} + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &KubeProxyConfiguration{}, + ) + return nil +} diff --git a/pkg/proxy/apis/proxyconfig/v1alpha1/types.go b/pkg/proxy/apis/proxyconfig/v1alpha1/types.go new file mode 100644 index 00000000000..d8ee5d0f930 --- /dev/null +++ b/pkg/proxy/apis/proxyconfig/v1alpha1/types.go @@ -0,0 +1,161 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ClientConnectionConfiguration contains details for constructing a client. +type ClientConnectionConfiguration struct { + // kubeConfigFile is the path to a kubeconfig file. + KubeConfigFile string `json:"kubeconfig"` + // acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the + // default value of 'application/json'. This field will control all connections to the server used by a particular + // client. + AcceptContentTypes string `json:"acceptContentTypes"` + // contentType is the content type used when sending data to the server from this client. + ContentType string `json:"contentType"` + // cps controls the number of queries per second allowed for this connection. + QPS float32 `json:"qps"` + // burst allows extra queries to accumulate when a client is exceeding its rate. + Burst int `json:"burst"` +} + +// KubeProxyIPTablesConfiguration contains iptables-related configuration +// details for the Kubernetes proxy server. +type KubeProxyIPTablesConfiguration struct { + // masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using + // the pure iptables proxy mode. Values must be within the range [0, 31]. + MasqueradeBit *int32 `json:"masqueradeBit"` + // masqueradeAll tells kube-proxy to SNAT everything if using the pure iptables proxy mode. + MasqueradeAll bool `json:"masqueradeAll"` + // syncPeriod is the period that iptables rules are refreshed (e.g. '5s', '1m', + // '2h22m'). Must be greater than 0. + SyncPeriod metav1.Duration `json:"syncPeriod"` + // minSyncPeriod is the minimum period that iptables rules are refreshed (e.g. '5s', '1m', + // '2h22m'). + 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 +// the Kubernetes proxy server. +type KubeProxyConntrackConfiguration struct { + // max is the maximum number of NAT connections to track (0 to + // leave as-is). This takes precedence over conntrackMaxPerCore and conntrackMin. + Max int32 `json:"max"` + // maxPerCore is the maximum number of NAT connections to track + // per CPU core (0 to leave the limit as-is and ignore conntrackMin). + MaxPerCore int32 `json:"maxPerCore"` + // min is the minimum value of connect-tracking records to allocate, + // regardless of conntrackMaxPerCore (set conntrackMaxPerCore=0 to leave the limit as-is). + Min int32 `json:"min"` + // tcpEstablishedTimeout is how long an idle TCP connection will be kept open + // (e.g. '2s'). Must be greater than 0. + TCPEstablishedTimeout metav1.Duration `json:"tcpEstablishedTimeout"` + // tcpCloseWaitTimeout is how long an idle conntrack entry + // in CLOSE_WAIT state will remain in the conntrack + // table. (e.g. '60s'). Must be greater than 0 to set. + TCPCloseWaitTimeout metav1.Duration `json:"tcpCloseWaitTimeout"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// KubeProxyConfiguration contains everything necessary to configure the +// Kubernetes proxy server. +type KubeProxyConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // featureGates is a comma-separated list of key=value pairs that control + // which alpha/beta features are enabled. + // + // TODO this really should be a map but that requires refactoring all + // components to use config files because local-up-cluster.sh only supports + // the --feature-gates flag right now, which is comma-separated key=value + // pairs. + FeatureGates string `json:"featureGates"` + + // bindAddress is the IP address for the proxy server to serve on (set to 0.0.0.0 + // for all interfaces) + BindAddress string `json:"bindAddress"` + // healthzBindAddress is the IP address and port for the health check server to serve on, + // defaulting to 0.0.0.0:10256 + HealthzBindAddress string `json:"healthzBindAddress"` + // metricsBindAddress is the IP address and port for the metrics server to serve on, + // defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces) + MetricsBindAddress string `json:"metricsBindAddress"` + // enableProfiling enables profiling via web interface on /debug/pprof handler. + // Profiling handlers will be handled by metrics server. + EnableProfiling bool `json:"enableProfiling"` + // clusterCIDR is the CIDR range of the 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. + ClusterCIDR string `json:"clusterCIDR"` + // hostnameOverride, if non-empty, will be used as the identity instead of the actual hostname. + HostnameOverride string `json:"hostnameOverride"` + // clientConnection specifies the kubeconfig file and client connection settings for the proxy + // server to use when communicating with the apiserver. + ClientConnection ClientConnectionConfiguration `json:"clientConnection"` + // iptables contains iptables-related configuration options. + 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 + // the range [-1000, 1000] + OOMScoreAdj *int32 `json:"oomScoreAdj"` + // mode specifies which proxy mode to use. + Mode ProxyMode `json:"mode"` + // portRange is the 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. + PortRange string `json:"portRange"` + // resourceContainer is the bsolute name of the resource-only container to create and run + // the Kube-proxy in (Default: /kube-proxy). + ResourceContainer string `json:"resourceContainer"` + // udpIdleTimeout is how long an idle UDP connection will be kept open (e.g. '250ms', '2s'). + // Must be greater than 0. Only applicable for proxyMode=userspace. + UDPIdleTimeout metav1.Duration `json:"udpTimeoutMilliseconds"` + // conntrack contains conntrack-related configuration options. + Conntrack KubeProxyConntrackConfiguration `json:"conntrack"` + // configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater + // than 0. + ConfigSyncPeriod metav1.Duration `json:"configSyncPeriod"` +} + +// Currently two modes of proxying are available: 'userspace' (older, stable) or 'iptables' +// (newer, faster). If blank, use the best-available proxy (currently iptables, but may +// change in future versions). 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. +type ProxyMode string + +const ( + ProxyModeUserspace ProxyMode = "userspace" + ProxyModeIPTables ProxyMode = "iptables" +) diff --git a/cmd/kube-proxy/app/validation.go b/pkg/proxy/apis/proxyconfig/validation/validation.go similarity index 78% rename from cmd/kube-proxy/app/validation.go rename to pkg/proxy/apis/proxyconfig/validation/validation.go index 79dc7011940..97128eeb81b 100644 --- a/cmd/kube-proxy/app/validation.go +++ b/pkg/proxy/apis/proxyconfig/validation/validation.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package app +package validation import ( "fmt" @@ -25,11 +25,11 @@ import ( utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/validation/field" apivalidation "k8s.io/kubernetes/pkg/api/validation" - "k8s.io/kubernetes/pkg/apis/componentconfig" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" ) // Validate validates the configuration of kube-proxy -func Validate(config *componentconfig.KubeProxyConfiguration) field.ErrorList { +func Validate(config *proxyconfig.KubeProxyConfiguration) field.ErrorList { allErrs := field.ErrorList{} newPath := field.NewPath("KubeProxyConfiguration") @@ -38,7 +38,7 @@ func Validate(config *componentconfig.KubeProxyConfiguration) field.ErrorList { allErrs = append(allErrs, validateKubeProxyConntrackConfiguration(config.Conntrack, newPath.Child("KubeProxyConntrackConfiguration"))...) allErrs = append(allErrs, validateProxyMode(config.Mode, newPath.Child("Mode"))...) allErrs = append(allErrs, validateClientConnectionConfiguration(config.ClientConnection, newPath.Child("ClientConnection"))...) - allErrs = append(allErrs, validateIPVSSchedulerMethod(componentconfig.IPVSSchedulerMethod(config.IPVS.Scheduler), newPath.Child("KubeProxyIPVSConfiguration").Child("Scheduler"))...) + allErrs = append(allErrs, validateIPVSSchedulerMethod(proxyconfig.IPVSSchedulerMethod(config.IPVS.Scheduler), newPath.Child("KubeProxyIPVSConfiguration").Child("Scheduler"))...) if config.OOMScoreAdj != nil && (*config.OOMScoreAdj < -1000 || *config.OOMScoreAdj > 1000) { allErrs = append(allErrs, field.Invalid(newPath.Child("OOMScoreAdj"), *config.OOMScoreAdj, "must be within the range [-1000, 1000]")) @@ -72,7 +72,7 @@ func Validate(config *componentconfig.KubeProxyConfiguration) field.ErrorList { return allErrs } -func validateKubeProxyIPTablesConfiguration(config componentconfig.KubeProxyIPTablesConfiguration, fldPath *field.Path) field.ErrorList { +func validateKubeProxyIPTablesConfiguration(config proxyconfig.KubeProxyIPTablesConfiguration, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if config.MasqueradeBit != nil && (*config.MasqueradeBit < 0 || *config.MasqueradeBit > 31) { @@ -90,7 +90,7 @@ func validateKubeProxyIPTablesConfiguration(config componentconfig.KubeProxyIPTa return allErrs } -func validateKubeProxyConntrackConfiguration(config componentconfig.KubeProxyConntrackConfiguration, fldPath *field.Path) field.ErrorList { +func validateKubeProxyConntrackConfiguration(config proxyconfig.KubeProxyConntrackConfiguration, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if config.Max < 0 { @@ -116,22 +116,22 @@ func validateKubeProxyConntrackConfiguration(config componentconfig.KubeProxyCon return allErrs } -func validateProxyMode(mode componentconfig.ProxyMode, fldPath *field.Path) field.ErrorList { +func validateProxyMode(mode proxyconfig.ProxyMode, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} switch mode { - case componentconfig.ProxyModeUserspace: - case componentconfig.ProxyModeIPTables: - case componentconfig.ProxyModeIPVS: + case proxyconfig.ProxyModeUserspace: + case proxyconfig.ProxyModeIPTables: + case proxyconfig.ProxyModeIPVS: case "": default: - modes := []string{string(componentconfig.ProxyModeUserspace), string(componentconfig.ProxyModeIPTables), string(componentconfig.ProxyModeIPVS)} + modes := []string{string(proxyconfig.ProxyModeUserspace), string(proxyconfig.ProxyModeIPTables), string(proxyconfig.ProxyModeIPVS)} errMsg := fmt.Sprintf("must be %s or blank (blank means the best-available proxy (currently iptables)", strings.Join(modes, ",")) allErrs = append(allErrs, field.Invalid(fldPath.Child("ProxyMode"), string(mode), errMsg)) } return allErrs } -func validateClientConnectionConfiguration(config componentconfig.ClientConnectionConfiguration, fldPath *field.Path) field.ErrorList { +func validateClientConnectionConfiguration(config proxyconfig.ClientConnectionConfiguration, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(config.Burst), fldPath.Child("Burst"))...) return allErrs @@ -159,18 +159,18 @@ func validateHostPort(input string, fldPath *field.Path) field.ErrorList { return allErrs } -func validateIPVSSchedulerMethod(scheduler componentconfig.IPVSSchedulerMethod, fldPath *field.Path) field.ErrorList { - supportedMethod := []componentconfig.IPVSSchedulerMethod{ - componentconfig.RoundRobin, - componentconfig.WeightedRoundRobin, - componentconfig.LeastConnection, - componentconfig.WeightedLeastConnection, - componentconfig.LocalityBasedLeastConnection, - componentconfig.LocalityBasedLeastConnectionWithReplication, - componentconfig.SourceHashing, - componentconfig.DestinationHashing, - componentconfig.ShortestExpectedDelay, - componentconfig.NeverQueue, +func validateIPVSSchedulerMethod(scheduler proxyconfig.IPVSSchedulerMethod, fldPath *field.Path) field.ErrorList { + supportedMethod := []proxyconfig.IPVSSchedulerMethod{ + proxyconfig.RoundRobin, + proxyconfig.WeightedRoundRobin, + proxyconfig.LeastConnection, + proxyconfig.WeightedLeastConnection, + proxyconfig.LocalityBasedLeastConnection, + proxyconfig.LocalityBasedLeastConnectionWithReplication, + proxyconfig.SourceHashing, + proxyconfig.DestinationHashing, + proxyconfig.ShortestExpectedDelay, + proxyconfig.NeverQueue, "", } allErrs := field.ErrorList{} diff --git a/cmd/kube-proxy/app/validation_test.go b/pkg/proxy/apis/proxyconfig/validation/validation_test.go similarity index 82% rename from cmd/kube-proxy/app/validation_test.go rename to pkg/proxy/apis/proxyconfig/validation/validation_test.go index 51d22b3299b..9dbd6bdbdae 100644 --- a/cmd/kube-proxy/app/validation_test.go +++ b/pkg/proxy/apis/proxyconfig/validation/validation_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package app +package validation import ( "strings" @@ -23,11 +23,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/kubernetes/pkg/apis/componentconfig" + "k8s.io/kubernetes/pkg/proxy/apis/proxyconfig" ) func TestValidateKubeProxyConfiguration(t *testing.T) { - successCases := []componentconfig.KubeProxyConfiguration{ + successCases := []proxyconfig.KubeProxyConfiguration{ { BindAddress: "192.168.59.103", HealthzBindAddress: "0.0.0.0:10256", @@ -35,12 +35,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { ClusterCIDR: "192.168.59.0/24", UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, }, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(1), @@ -57,11 +57,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { } errorCases := []struct { - config componentconfig.KubeProxyConfiguration + config proxyconfig.KubeProxyConfiguration msg string }{ { - config: componentconfig.KubeProxyConfiguration{ + config: proxyconfig.KubeProxyConfiguration{ // only BindAddress is invalid BindAddress: "10.10.12.11:2000", HealthzBindAddress: "0.0.0.0:10256", @@ -69,12 +69,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { ClusterCIDR: "192.168.59.0/24", UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, }, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(1), @@ -85,7 +85,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { msg: "not a valid textual representation of an IP address", }, { - config: componentconfig.KubeProxyConfiguration{ + config: proxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", // only HealthzBindAddress is invalid HealthzBindAddress: "0.0.0.0", @@ -93,12 +93,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { ClusterCIDR: "192.168.59.0/24", UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, }, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(1), @@ -109,7 +109,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { msg: "must be IP:port", }, { - config: componentconfig.KubeProxyConfiguration{ + config: proxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", HealthzBindAddress: "0.0.0.0:12345", // only MetricsBindAddress is invalid @@ -117,12 +117,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { ClusterCIDR: "192.168.59.0/24", UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, }, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(1), @@ -133,7 +133,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { msg: "must be IP:port", }, { - config: componentconfig.KubeProxyConfiguration{ + config: proxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", HealthzBindAddress: "0.0.0.0:12345", MetricsBindAddress: "127.0.0.1:10249", @@ -141,12 +141,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { ClusterCIDR: "192.168.59.0", UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, }, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(1), @@ -157,7 +157,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { msg: "must be a valid CIDR block (e.g. 10.100.0.0/16)", }, { - config: componentconfig.KubeProxyConfiguration{ + config: proxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", HealthzBindAddress: "0.0.0.0:12345", MetricsBindAddress: "127.0.0.1:10249", @@ -165,12 +165,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { // only UDPIdleTimeout is invalid UDPIdleTimeout: metav1.Duration{Duration: -1 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, }, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(1), @@ -181,7 +181,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { msg: "must be greater than 0", }, { - config: componentconfig.KubeProxyConfiguration{ + config: proxyconfig.KubeProxyConfiguration{ BindAddress: "10.10.12.11", HealthzBindAddress: "0.0.0.0:12345", MetricsBindAddress: "127.0.0.1:10249", @@ -189,12 +189,12 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { UDPIdleTimeout: metav1.Duration{Duration: 1 * time.Second}, // only ConfigSyncPeriod is invalid ConfigSyncPeriod: metav1.Duration{Duration: -1 * time.Second}, - IPTables: componentconfig.KubeProxyIPTablesConfiguration{ + IPTables: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, }, - Conntrack: componentconfig.KubeProxyConntrackConfiguration{ + Conntrack: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(1), @@ -217,7 +217,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) { func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) { valid := int32(5) - successCases := []componentconfig.KubeProxyIPTablesConfiguration{ + successCases := []proxyconfig.KubeProxyIPTablesConfiguration{ { MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, @@ -239,11 +239,11 @@ func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) { invalid := int32(-10) errorCases := []struct { - config componentconfig.KubeProxyIPTablesConfiguration + config proxyconfig.KubeProxyIPTablesConfiguration msg string }{ { - config: componentconfig.KubeProxyIPTablesConfiguration{ + config: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: -5 * time.Second}, MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second}, @@ -251,7 +251,7 @@ func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) { msg: "must be greater than 0", }, { - config: componentconfig.KubeProxyIPTablesConfiguration{ + config: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeBit: &valid, MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, @@ -260,7 +260,7 @@ func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) { msg: "must be greater than or equal to 0", }, { - config: componentconfig.KubeProxyIPTablesConfiguration{ + config: proxyconfig.KubeProxyIPTablesConfiguration{ MasqueradeBit: &invalid, MasqueradeAll: true, SyncPeriod: metav1.Duration{Duration: 5 * time.Second}, @@ -280,7 +280,7 @@ func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) { } func TestValidateKubeProxyConntrackConfiguration(t *testing.T) { - successCases := []componentconfig.KubeProxyConntrackConfiguration{ + successCases := []proxyconfig.KubeProxyConntrackConfiguration{ { Max: int32(2), MaxPerCore: int32(1), @@ -304,11 +304,11 @@ func TestValidateKubeProxyConntrackConfiguration(t *testing.T) { } errorCases := []struct { - config componentconfig.KubeProxyConntrackConfiguration + config proxyconfig.KubeProxyConntrackConfiguration msg string }{ { - config: componentconfig.KubeProxyConntrackConfiguration{ + config: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(-1), MaxPerCore: int32(1), Min: int32(1), @@ -318,7 +318,7 @@ func TestValidateKubeProxyConntrackConfiguration(t *testing.T) { msg: "must be greater than or equal to 0", }, { - config: componentconfig.KubeProxyConntrackConfiguration{ + config: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(-1), Min: int32(1), @@ -328,7 +328,7 @@ func TestValidateKubeProxyConntrackConfiguration(t *testing.T) { msg: "must be greater than or equal to 0", }, { - config: componentconfig.KubeProxyConntrackConfiguration{ + config: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(2), MaxPerCore: int32(1), Min: int32(-1), @@ -338,7 +338,7 @@ func TestValidateKubeProxyConntrackConfiguration(t *testing.T) { msg: "must be greater than or equal to 0", }, { - config: componentconfig.KubeProxyConntrackConfiguration{ + config: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(4), MaxPerCore: int32(1), Min: int32(3), @@ -348,7 +348,7 @@ func TestValidateKubeProxyConntrackConfiguration(t *testing.T) { msg: "must be greater than 0", }, { - config: componentconfig.KubeProxyConntrackConfiguration{ + config: proxyconfig.KubeProxyConntrackConfiguration{ Max: int32(4), MaxPerCore: int32(1), Min: int32(3), @@ -371,11 +371,11 @@ func TestValidateKubeProxyConntrackConfiguration(t *testing.T) { func TestValidateProxyMode(t *testing.T) { newPath := field.NewPath("KubeProxyConfiguration") - successCases := []componentconfig.ProxyMode{ - componentconfig.ProxyModeUserspace, - componentconfig.ProxyModeIPTables, - componentconfig.ProxyModeIPVS, - componentconfig.ProxyMode(""), + successCases := []proxyconfig.ProxyMode{ + proxyconfig.ProxyModeUserspace, + proxyconfig.ProxyModeIPTables, + proxyconfig.ProxyModeIPVS, + proxyconfig.ProxyMode(""), } for _, successCase := range successCases { @@ -385,11 +385,11 @@ func TestValidateProxyMode(t *testing.T) { } errorCases := []struct { - mode componentconfig.ProxyMode + mode proxyconfig.ProxyMode msg string }{ { - mode: componentconfig.ProxyMode("non-existing"), + mode: proxyconfig.ProxyMode("non-existing"), msg: "or blank (blank means the best-available proxy (currently iptables)", }, } @@ -406,7 +406,7 @@ func TestValidateProxyMode(t *testing.T) { func TestValidateClientConnectionConfiguration(t *testing.T) { newPath := field.NewPath("KubeProxyConfiguration") - successCases := []componentconfig.ClientConnectionConfiguration{ + successCases := []proxyconfig.ClientConnectionConfiguration{ { Burst: 0, }, @@ -422,11 +422,11 @@ func TestValidateClientConnectionConfiguration(t *testing.T) { } errorCases := []struct { - ccc componentconfig.ClientConnectionConfiguration + ccc proxyconfig.ClientConnectionConfiguration msg string }{ { - ccc: componentconfig.ClientConnectionConfiguration{Burst: -5}, + ccc: proxyconfig.ClientConnectionConfiguration{Burst: -5}, msg: "must be greater than or equal to 0", }, } @@ -493,17 +493,17 @@ func TestValidateHostPort(t *testing.T) { func TestValidateIPVSSchedulerMethod(t *testing.T) { newPath := field.NewPath("KubeProxyConfiguration") - successCases := []componentconfig.IPVSSchedulerMethod{ - componentconfig.RoundRobin, - componentconfig.WeightedRoundRobin, - componentconfig.LeastConnection, - componentconfig.WeightedLeastConnection, - componentconfig.LocalityBasedLeastConnection, - componentconfig.LocalityBasedLeastConnectionWithReplication, - componentconfig.SourceHashing, - componentconfig.DestinationHashing, - componentconfig.ShortestExpectedDelay, - componentconfig.NeverQueue, + successCases := []proxyconfig.IPVSSchedulerMethod{ + proxyconfig.RoundRobin, + proxyconfig.WeightedRoundRobin, + proxyconfig.LeastConnection, + proxyconfig.WeightedLeastConnection, + proxyconfig.LocalityBasedLeastConnection, + proxyconfig.LocalityBasedLeastConnectionWithReplication, + proxyconfig.SourceHashing, + proxyconfig.DestinationHashing, + proxyconfig.ShortestExpectedDelay, + proxyconfig.NeverQueue, "", } @@ -514,11 +514,11 @@ func TestValidateIPVSSchedulerMethod(t *testing.T) { } errorCases := []struct { - mode componentconfig.IPVSSchedulerMethod + mode proxyconfig.IPVSSchedulerMethod msg string }{ { - mode: componentconfig.IPVSSchedulerMethod("non-existing"), + mode: proxyconfig.IPVSSchedulerMethod("non-existing"), msg: "blank means the default algorithm method (currently rr)", }, } diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index d9b1976ac59..6ff9dfa4b63 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -459,7 +459,6 @@ var ephemeralWhiteList = createEphemeralWhiteList( // k8s.io/kubernetes/pkg/apis/componentconfig/v1alpha1 gvr("componentconfig", "v1alpha1", "kubeschedulerconfigurations"), // not stored in etcd - gvr("componentconfig", "v1alpha1", "kubeproxyconfigurations"), // not stored in etcd // -- // k8s.io/kubernetes/pkg/apis/extensions/v1beta1