mirror of https://github.com/k3s-io/k3s
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
commit
d28fccfabe
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
],
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue