Merge pull request #55261 from ncdc/kube-proxy-config-fix-conntrack-zero-values

Automatic merge from submit-queue (batch tested with PRs 55247, 55324, 55261, 55147, 54052). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Restore kube-proxy's support for 0 values for conntrack settings

**What this PR does / why we need it**: re-allow 0 values for kube-proxy conntrack min, max, max per core, tcp close wait timeout, tcp established timeout.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #50787

**Special notes for your reviewer**:
- I adjusted validation to allow for 0 values for some of the conntrack settings, as otherwise the "leave the limit as-is" logic wouldn't be allowed.
- I moved the loading of the config file from the cobra command's Validate method to Complete. This way, the config is fully resolved before validation happens. Otherwise, it just validates the default config values first, and _then_ the config is loaded.
- I think I got all the default values & nil checking correct, but please review carefully!

**Release note**:

```release-note
Restored kube-proxy's support for 0 values for conntrack min, max, max per core, tcp close wait timeout, and tcp established timeout.
```
pull/6/head
Kubernetes Submit Queue 2017-11-09 00:59:23 -08:00 committed by GitHub
commit d28fccfabe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 252 additions and 154 deletions

View File

@ -146,12 +146,15 @@ func AddFlags(options *Options, fs *pflag.FlagSet) {
fs.Float32Var(&options.config.ClientConnection.QPS, "kube-api-qps", options.config.ClientConnection.QPS, "QPS to use while talking with kubernetes apiserver")
fs.IntVar(&options.config.ClientConnection.Burst, "kube-api-burst", options.config.ClientConnection.Burst, "Burst to use while talking with kubernetes apiserver")
fs.DurationVar(&options.config.UDPIdleTimeout.Duration, "udp-timeout", options.config.UDPIdleTimeout.Duration, "How long an idle UDP connection will be kept open (e.g. '250ms', '2s'). Must be greater than 0. Only applicable for proxy-mode=userspace")
fs.Int32Var(&options.config.Conntrack.Max, "conntrack-max", options.config.Conntrack.Max,
if options.config.Conntrack.Max == nil {
options.config.Conntrack.Max = utilpointer.Int32Ptr(0)
}
fs.Int32Var(options.config.Conntrack.Max, "conntrack-max", *options.config.Conntrack.Max,
"Maximum number of NAT connections to track (0 to leave as-is). This overrides conntrack-max-per-core and conntrack-min.")
fs.MarkDeprecated("conntrack-max", "This feature will be removed in a later release.")
fs.Int32Var(&options.config.Conntrack.MaxPerCore, "conntrack-max-per-core", options.config.Conntrack.MaxPerCore,
fs.Int32Var(options.config.Conntrack.MaxPerCore, "conntrack-max-per-core", *options.config.Conntrack.MaxPerCore,
"Maximum number of NAT connections to track per CPU core (0 to leave the limit as-is and ignore conntrack-min).")
fs.Int32Var(&options.config.Conntrack.Min, "conntrack-min", options.config.Conntrack.Min,
fs.Int32Var(options.config.Conntrack.Min, "conntrack-min", *options.config.Conntrack.Min,
"Minimum number of conntrack entries to allocate, regardless of conntrack-max-per-core (set conntrack-max-per-core=0 to leave the limit as-is).")
fs.DurationVar(&options.config.Conntrack.TCPEstablishedTimeout.Duration, "conntrack-tcp-timeout-established", options.config.Conntrack.TCPEstablishedTimeout.Duration, "Idle timeout for established TCP connections (0 to leave as-is)")
fs.DurationVar(
@ -179,6 +182,17 @@ func (o *Options) Complete() error {
o.applyDeprecatedHealthzPortToConfig()
}
// Load the config file here in Complete, so that Validate validates the fully-resolved config.
if len(o.ConfigFile) > 0 {
if c, err := o.loadConfigFromFile(o.ConfigFile); err != nil {
return err
} else {
o.config = c
// Make sure we apply the feature gate settings in the config file.
utilfeature.DefaultFeatureGate.Set(o.config.FeatureGates)
}
}
return nil
}
@ -196,23 +210,11 @@ func (o *Options) Validate(args []string) error {
}
func (o *Options) Run() error {
config := o.config
if len(o.WriteConfigTo) > 0 {
return o.writeConfigFile()
}
if len(o.ConfigFile) > 0 {
if c, err := o.loadConfigFromFile(o.ConfigFile); err != nil {
return err
} else {
config = c
// Make sure we apply the feature gate settings in the config file.
utilfeature.DefaultFeatureGate.Set(config.FeatureGates)
}
}
proxyServer, err := NewProxyServer(config, o.CleanupAndExit, o.scheme, o.master)
proxyServer, err := NewProxyServer(o.config, o.CleanupAndExit, o.scheme, o.master)
if err != nil {
return err
}
@ -502,14 +504,14 @@ func (s *ProxyServer) Run() error {
}
}
if s.ConntrackConfiguration.TCPEstablishedTimeout.Duration > 0 {
if s.ConntrackConfiguration.TCPEstablishedTimeout != nil && s.ConntrackConfiguration.TCPEstablishedTimeout.Duration > 0 {
timeout := int(s.ConntrackConfiguration.TCPEstablishedTimeout.Duration / time.Second)
if err := s.Conntracker.SetTCPEstablishedTimeout(timeout); err != nil {
return err
}
}
if s.ConntrackConfiguration.TCPCloseWaitTimeout.Duration > 0 {
if s.ConntrackConfiguration.TCPCloseWaitTimeout != nil && s.ConntrackConfiguration.TCPCloseWaitTimeout.Duration > 0 {
timeout := int(s.ConntrackConfiguration.TCPCloseWaitTimeout.Duration / time.Second)
if err := s.Conntracker.SetTCPCloseWaitTimeout(timeout); err != nil {
return err
@ -548,16 +550,19 @@ func (s *ProxyServer) birthCry() {
}
func getConntrackMax(config kubeproxyconfig.KubeProxyConntrackConfiguration) (int, error) {
if config.Max > 0 {
if config.MaxPerCore > 0 {
if config.Max != nil && *config.Max > 0 {
if config.MaxPerCore != nil && *config.MaxPerCore > 0 {
return -1, fmt.Errorf("invalid config: Conntrack Max and Conntrack MaxPerCore are mutually exclusive")
}
glog.V(3).Infof("getConntrackMax: using absolute conntrack-max (deprecated)")
return int(config.Max), nil
return int(*config.Max), nil
}
if config.MaxPerCore > 0 {
floor := int(config.Min)
scaled := int(config.MaxPerCore) * goruntime.NumCPU()
if config.MaxPerCore != nil && *config.MaxPerCore > 0 {
floor := 0
if config.Min != nil {
floor = int(*config.Min)
}
scaled := int(*config.MaxPerCore) * goruntime.NumCPU()
if scaled > floor {
glog.V(3).Infof("getConntrackMax: using scaled conntrack-max-per-core")
return scaled, nil

View File

@ -203,9 +203,9 @@ func TestGetConntrackMax(t *testing.T) {
for i, tc := range testCases {
cfg := kubeproxyconfig.KubeProxyConntrackConfiguration{
Min: tc.min,
Max: tc.max,
MaxPerCore: tc.maxPerCore,
Min: utilpointer.Int32Ptr(tc.min),
Max: utilpointer.Int32Ptr(tc.max),
MaxPerCore: utilpointer.Int32Ptr(tc.maxPerCore),
}
x, e := getConntrackMax(cfg)
if e != nil {
@ -344,11 +344,11 @@ udpTimeoutMilliseconds: 123ms
ClusterCIDR: tc.clusterCIDR,
ConfigSyncPeriod: metav1.Duration{Duration: 15 * time.Second},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: 4,
MaxPerCore: 2,
Min: 1,
TCPCloseWaitTimeout: metav1.Duration{Duration: 10 * time.Second},
TCPEstablishedTimeout: metav1.Duration{Duration: 20 * time.Second},
Max: utilpointer.Int32Ptr(4),
MaxPerCore: utilpointer.Int32Ptr(2),
Min: utilpointer.Int32Ptr(1),
TCPCloseWaitTimeout: &metav1.Duration{Duration: 10 * time.Second},
TCPEstablishedTimeout: &metav1.Duration{Duration: 20 * time.Second},
},
FeatureGates: "all",
HealthzBindAddress: tc.healthzBindAddress,

View File

@ -73,21 +73,21 @@ type KubeProxyIPVSConfiguration struct {
// 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
// leave as-is). This takes precedence over maxPerCore and min.
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
// per CPU core (0 to leave the limit as-is and ignore min).
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
// regardless of maxPerCore (set maxPerCore=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
// (e.g. '2s'). Must be greater than 0 to set.
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
TCPCloseWaitTimeout *metav1.Duration
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@ -21,6 +21,7 @@ go_library(
"//pkg/kubelet/qos:go_default_library",
"//pkg/master/ports:go_default_library",
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
"//pkg/util/pointer:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",

View File

@ -25,6 +25,7 @@ import (
kruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/kubelet/qos"
"k8s.io/kubernetes/pkg/master/ports"
"k8s.io/kubernetes/pkg/util/pointer"
)
func addDefaultingFuncs(scheme *kruntime.Scheme) error {
@ -63,23 +64,23 @@ func SetDefaults_KubeProxyConfiguration(obj *KubeProxyConfiguration) {
obj.UDPIdleTimeout = metav1.Duration{Duration: 250 * time.Millisecond}
}
// If ConntrackMax is set, respect it.
if obj.Conntrack.Max == 0 {
if obj.Conntrack.Max == nil {
// If ConntrackMax is *not* set, use per-core scaling.
if obj.Conntrack.MaxPerCore == 0 {
obj.Conntrack.MaxPerCore = 32 * 1024
if obj.Conntrack.MaxPerCore == nil {
obj.Conntrack.MaxPerCore = pointer.Int32Ptr(32 * 1024)
}
if obj.Conntrack.Min == 0 {
obj.Conntrack.Min = 128 * 1024
if obj.Conntrack.Min == nil {
obj.Conntrack.Min = pointer.Int32Ptr(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.TCPEstablishedTimeout == nil {
obj.Conntrack.TCPEstablishedTimeout = &metav1.Duration{Duration: 24 * time.Hour} // 1 day (1/5 default)
}
if obj.Conntrack.TCPCloseWaitTimeout == zero {
if obj.Conntrack.TCPCloseWaitTimeout == nil {
// See https://github.com/kubernetes/kubernetes/issues/32551.
//
// CLOSE_WAIT conntrack state occurs when the Linux kernel
@ -100,7 +101,7 @@ func SetDefaults_KubeProxyConfiguration(obj *KubeProxyConfiguration) {
//
// We set CLOSE_WAIT to one hour by default to better match
// typical server timeouts.
obj.Conntrack.TCPCloseWaitTimeout = metav1.Duration{Duration: 1 * time.Hour}
obj.Conntrack.TCPCloseWaitTimeout = &metav1.Duration{Duration: 1 * time.Hour}
}
if obj.ConfigSyncPeriod.Duration == 0 {
obj.ConfigSyncPeriod.Duration = 15 * time.Minute

View File

@ -69,21 +69,21 @@ type KubeProxyIPVSConfiguration struct {
// 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"`
// leave as-is). This takes precedence over maxPerCore and min.
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"`
// per CPU core (0 to leave the limit as-is and ignore min).
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"`
// regardless of conntrackMaxPerCore (set maxPerCore=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"`
// (e.g. '2s'). Must be greater than 0 to set.
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"`
TCPCloseWaitTimeout *metav1.Duration `json:"tcpCloseWaitTimeout"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

View File

@ -21,6 +21,7 @@ limitations under the License.
package v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
@ -145,11 +146,11 @@ func Convert_kubeproxyconfig_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfigu
}
func autoConvert_v1alpha1_KubeProxyConntrackConfiguration_To_kubeproxyconfig_KubeProxyConntrackConfiguration(in *KubeProxyConntrackConfiguration, out *kubeproxyconfig.KubeProxyConntrackConfiguration, s conversion.Scope) error {
out.Max = in.Max
out.MaxPerCore = in.MaxPerCore
out.Min = in.Min
out.TCPEstablishedTimeout = in.TCPEstablishedTimeout
out.TCPCloseWaitTimeout = in.TCPCloseWaitTimeout
out.Max = (*int32)(unsafe.Pointer(in.Max))
out.MaxPerCore = (*int32)(unsafe.Pointer(in.MaxPerCore))
out.Min = (*int32)(unsafe.Pointer(in.Min))
out.TCPEstablishedTimeout = (*v1.Duration)(unsafe.Pointer(in.TCPEstablishedTimeout))
out.TCPCloseWaitTimeout = (*v1.Duration)(unsafe.Pointer(in.TCPCloseWaitTimeout))
return nil
}
@ -159,11 +160,11 @@ func Convert_v1alpha1_KubeProxyConntrackConfiguration_To_kubeproxyconfig_KubePro
}
func autoConvert_kubeproxyconfig_KubeProxyConntrackConfiguration_To_v1alpha1_KubeProxyConntrackConfiguration(in *kubeproxyconfig.KubeProxyConntrackConfiguration, out *KubeProxyConntrackConfiguration, s conversion.Scope) error {
out.Max = in.Max
out.MaxPerCore = in.MaxPerCore
out.Min = in.Min
out.TCPEstablishedTimeout = in.TCPEstablishedTimeout
out.TCPCloseWaitTimeout = in.TCPCloseWaitTimeout
out.Max = (*int32)(unsafe.Pointer(in.Max))
out.MaxPerCore = (*int32)(unsafe.Pointer(in.MaxPerCore))
out.Min = (*int32)(unsafe.Pointer(in.Min))
out.TCPEstablishedTimeout = (*v1.Duration)(unsafe.Pointer(in.TCPEstablishedTimeout))
out.TCPCloseWaitTimeout = (*v1.Duration)(unsafe.Pointer(in.TCPCloseWaitTimeout))
return nil
}

View File

@ -21,6 +21,7 @@ limitations under the License.
package v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
reflect "reflect"
@ -92,7 +93,7 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
}
}
out.UDPIdleTimeout = in.UDPIdleTimeout
out.Conntrack = in.Conntrack
in.Conntrack.DeepCopyInto(&out.Conntrack)
out.ConfigSyncPeriod = in.ConfigSyncPeriod
return
}
@ -119,8 +120,51 @@ func (in *KubeProxyConfiguration) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyConntrackConfiguration) DeepCopyInto(out *KubeProxyConntrackConfiguration) {
*out = *in
out.TCPEstablishedTimeout = in.TCPEstablishedTimeout
out.TCPCloseWaitTimeout = in.TCPCloseWaitTimeout
if in.Max != nil {
in, out := &in.Max, &out.Max
if *in == nil {
*out = nil
} else {
*out = new(int32)
**out = **in
}
}
if in.MaxPerCore != nil {
in, out := &in.MaxPerCore, &out.MaxPerCore
if *in == nil {
*out = nil
} else {
*out = new(int32)
**out = **in
}
}
if in.Min != nil {
in, out := &in.Min, &out.Min
if *in == nil {
*out = nil
} else {
*out = new(int32)
**out = **in
}
}
if in.TCPEstablishedTimeout != nil {
in, out := &in.TCPEstablishedTimeout, &out.TCPEstablishedTimeout
if *in == nil {
*out = nil
} else {
*out = new(v1.Duration)
**out = **in
}
}
if in.TCPCloseWaitTimeout != nil {
in, out := &in.TCPCloseWaitTimeout, &out.TCPCloseWaitTimeout
if *in == nil {
*out = nil
} else {
*out = new(v1.Duration)
**out = **in
}
}
return
}

View File

@ -38,6 +38,7 @@ go_test(
library = ":go_default_library",
deps = [
"//pkg/proxy/apis/kubeproxyconfig:go_default_library",
"//pkg/util/pointer:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
],

View File

@ -93,24 +93,24 @@ func validateKubeProxyIPTablesConfiguration(config kubeproxyconfig.KubeProxyIPTa
func validateKubeProxyConntrackConfiguration(config kubeproxyconfig.KubeProxyConntrackConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if config.Max < 0 {
if config.Max != nil && *config.Max < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("Max"), config.Max, "must be greater than or equal to 0"))
}
if config.MaxPerCore < 0 {
if config.MaxPerCore != nil && *config.MaxPerCore < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MaxPerCore"), config.MaxPerCore, "must be greater than or equal to 0"))
}
if config.Min < 0 {
if config.Min != nil && *config.Min < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("Min"), config.Min, "must be greater than or equal to 0"))
}
if config.TCPEstablishedTimeout.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("TCPEstablishedTimeout"), config.TCPEstablishedTimeout, "must be greater than 0"))
if config.TCPEstablishedTimeout.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("TCPEstablishedTimeout"), config.TCPEstablishedTimeout, "must be greater than or equal to 0"))
}
if config.TCPCloseWaitTimeout.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("TCPCloseWaitTimeout"), config.TCPCloseWaitTimeout, "must be greater than 0"))
if config.TCPCloseWaitTimeout.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("TCPCloseWaitTimeout"), config.TCPCloseWaitTimeout, "must be greater than or equal to 0"))
}
return allErrs

View File

@ -24,6 +24,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/proxy/apis/kubeproxyconfig"
"k8s.io/kubernetes/pkg/util/pointer"
)
func TestValidateKubeProxyConfiguration(t *testing.T) {
@ -41,11 +42,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
}
@ -75,11 +76,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
msg: "not a valid textual representation of an IP address",
@ -99,11 +100,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
msg: "must be IP:port",
@ -123,11 +124,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
msg: "must be IP:port",
@ -147,11 +148,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
msg: "must be a valid CIDR block (e.g. 10.100.0.0/16)",
@ -171,11 +172,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
msg: "must be greater than 0",
@ -195,11 +196,11 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
},
msg: "must be greater than 0",
@ -282,18 +283,18 @@ func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) {
func TestValidateKubeProxyConntrackConfiguration(t *testing.T) {
successCases := []kubeproxyconfig.KubeProxyConntrackConfiguration{
{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
{
Max: 0,
MaxPerCore: 0,
Min: 0,
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 60 * time.Second},
Max: pointer.Int32Ptr(0),
MaxPerCore: pointer.Int32Ptr(0),
Min: pointer.Int32Ptr(0),
TCPEstablishedTimeout: &metav1.Duration{Duration: 0 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 0 * time.Second},
},
}
newPath := field.NewPath("KubeProxyConfiguration")
@ -309,53 +310,53 @@ func TestValidateKubeProxyConntrackConfiguration(t *testing.T) {
}{
{
config: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(-1),
MaxPerCore: int32(1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(-1),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
msg: "must be greater than or equal to 0",
},
{
config: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(-1),
Min: int32(1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(-1),
Min: pointer.Int32Ptr(1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
msg: "must be greater than or equal to 0",
},
{
config: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(2),
MaxPerCore: int32(1),
Min: int32(-1),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(2),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(-1),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
msg: "must be greater than or equal to 0",
},
{
config: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(4),
MaxPerCore: int32(1),
Min: int32(3),
TCPEstablishedTimeout: metav1.Duration{Duration: -5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: 5 * time.Second},
Max: pointer.Int32Ptr(4),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(3),
TCPEstablishedTimeout: &metav1.Duration{Duration: -5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
msg: "must be greater than 0",
msg: "must be greater than or equal to 0",
},
{
config: kubeproxyconfig.KubeProxyConntrackConfiguration{
Max: int32(4),
MaxPerCore: int32(1),
Min: int32(3),
TCPEstablishedTimeout: metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: metav1.Duration{Duration: -5 * time.Second},
Max: pointer.Int32Ptr(4),
MaxPerCore: pointer.Int32Ptr(1),
Min: pointer.Int32Ptr(3),
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: -5 * time.Second},
},
msg: "must be greater than 0",
msg: "must be greater than or equal to 0",
},
}

View File

@ -21,6 +21,7 @@ limitations under the License.
package kubeproxyconfig
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
reflect "reflect"
@ -92,7 +93,7 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
}
}
out.UDPIdleTimeout = in.UDPIdleTimeout
out.Conntrack = in.Conntrack
in.Conntrack.DeepCopyInto(&out.Conntrack)
out.ConfigSyncPeriod = in.ConfigSyncPeriod
return
}
@ -119,8 +120,51 @@ func (in *KubeProxyConfiguration) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyConntrackConfiguration) DeepCopyInto(out *KubeProxyConntrackConfiguration) {
*out = *in
out.TCPEstablishedTimeout = in.TCPEstablishedTimeout
out.TCPCloseWaitTimeout = in.TCPCloseWaitTimeout
if in.Max != nil {
in, out := &in.Max, &out.Max
if *in == nil {
*out = nil
} else {
*out = new(int32)
**out = **in
}
}
if in.MaxPerCore != nil {
in, out := &in.MaxPerCore, &out.MaxPerCore
if *in == nil {
*out = nil
} else {
*out = new(int32)
**out = **in
}
}
if in.Min != nil {
in, out := &in.Min, &out.Min
if *in == nil {
*out = nil
} else {
*out = new(int32)
**out = **in
}
}
if in.TCPEstablishedTimeout != nil {
in, out := &in.TCPEstablishedTimeout, &out.TCPEstablishedTimeout
if *in == nil {
*out = nil
} else {
*out = new(v1.Duration)
**out = **in
}
}
if in.TCPCloseWaitTimeout != nil {
in, out := &in.TCPCloseWaitTimeout, &out.TCPCloseWaitTimeout
if *in == nil {
*out = nil
} else {
*out = new(v1.Duration)
**out = **in
}
}
return
}