kube-proxy: internal config: consolidate SyncPeriod and MinSyncPeriod

Consolidate SyncPeriod and MinSyncPeriod for internal configuration
of kube-proxy adhering to the v1alpha2 version specifications as
detailed in https://kep.k8s.io/784.

Signed-off-by: Daman Arora <aroradaman@gmail.com>
This commit is contained in:
Daman Arora 2024-07-17 22:20:15 +05:30
parent 1854839ff0
commit 380adb93cc
15 changed files with 224 additions and 298 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"time"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
"github.com/spf13/pflag" "github.com/spf13/pflag"
@ -79,6 +80,13 @@ type Options struct {
hostnameOverride string hostnameOverride string
logger klog.Logger logger klog.Logger
// The fields below here are placeholders for flags that can't be directly mapped into
// config.KubeProxyConfiguration.
iptablesSyncPeriod time.Duration
iptablesMinSyncPeriod time.Duration
ipvsSyncPeriod time.Duration
ipvsMinSyncPeriod time.Duration
} }
// AddFlags adds flags to fs and binds them to options. // AddFlags adds flags to fs and binds them to options.
@ -120,11 +128,11 @@ func (o *Options) AddFlags(fs *pflag.FlagSet) {
fs.Int32Var(o.config.IPTables.MasqueradeBit, "iptables-masquerade-bit", ptr.Deref(o.config.IPTables.MasqueradeBit, 14), "If using the iptables or ipvs proxy mode, the bit of the fwmark space to mark packets requiring SNAT with. Must be within the range [0, 31].") fs.Int32Var(o.config.IPTables.MasqueradeBit, "iptables-masquerade-bit", ptr.Deref(o.config.IPTables.MasqueradeBit, 14), "If using the iptables or ipvs proxy mode, the bit of the fwmark space to mark packets requiring SNAT with. Must be within the range [0, 31].")
fs.BoolVar(&o.config.Linux.MasqueradeAll, "masquerade-all", o.config.Linux.MasqueradeAll, "SNAT all traffic sent via Service cluster IPs. This may be required with some CNI plugins. Only supported on Linux.") fs.BoolVar(&o.config.Linux.MasqueradeAll, "masquerade-all", o.config.Linux.MasqueradeAll, "SNAT all traffic sent via Service cluster IPs. This may be required with some CNI plugins. Only supported on Linux.")
fs.BoolVar(o.config.IPTables.LocalhostNodePorts, "iptables-localhost-nodeports", ptr.Deref(o.config.IPTables.LocalhostNodePorts, true), "If false, kube-proxy will disable the legacy behavior of allowing NodePort services to be accessed via localhost. (Applies only to iptables mode and IPv4; localhost NodePorts are never allowed with other proxy modes or with IPv6.)") fs.BoolVar(o.config.IPTables.LocalhostNodePorts, "iptables-localhost-nodeports", ptr.Deref(o.config.IPTables.LocalhostNodePorts, true), "If false, kube-proxy will disable the legacy behavior of allowing NodePort services to be accessed via localhost. (Applies only to iptables mode and IPv4; localhost NodePorts are never allowed with other proxy modes or with IPv6.)")
fs.DurationVar(&o.config.IPTables.SyncPeriod.Duration, "iptables-sync-period", o.config.IPTables.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.") fs.DurationVar(&o.iptablesSyncPeriod, "iptables-sync-period", o.config.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.")
fs.DurationVar(&o.config.IPTables.MinSyncPeriod.Duration, "iptables-min-sync-period", o.config.IPTables.MinSyncPeriod.Duration, "The minimum period between iptables rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate iptables resync.") fs.DurationVar(&o.iptablesMinSyncPeriod, "iptables-min-sync-period", o.config.MinSyncPeriod.Duration, "The minimum period between iptables rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate iptables resync.")
fs.DurationVar(&o.config.IPVS.SyncPeriod.Duration, "ipvs-sync-period", o.config.IPVS.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.") fs.DurationVar(&o.ipvsSyncPeriod, "ipvs-sync-period", o.config.SyncPeriod.Duration, "An interval (e.g. '5s', '1m', '2h22m') indicating how frequently various re-synchronizing and cleanup operations are performed. Must be greater than 0.")
fs.DurationVar(&o.config.IPVS.MinSyncPeriod.Duration, "ipvs-min-sync-period", o.config.IPVS.MinSyncPeriod.Duration, "The minimum period between IPVS rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate IPVS resync.") fs.DurationVar(&o.ipvsMinSyncPeriod, "ipvs-min-sync-period", o.config.MinSyncPeriod.Duration, "The minimum period between IPVS rule resyncs (e.g. '5s', '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will result in an immediate IPVS resync.")
fs.StringVar(&o.config.IPVS.Scheduler, "ipvs-scheduler", o.config.IPVS.Scheduler, "The ipvs scheduler type when proxy mode is ipvs") fs.StringVar(&o.config.IPVS.Scheduler, "ipvs-scheduler", o.config.IPVS.Scheduler, "The ipvs scheduler type when proxy mode is ipvs")
fs.StringSliceVar(&o.config.IPVS.ExcludeCIDRs, "ipvs-exclude-cidrs", o.config.IPVS.ExcludeCIDRs, "A comma-separated list of CIDRs which the ipvs proxier should not touch when cleaning up IPVS rules.") fs.StringSliceVar(&o.config.IPVS.ExcludeCIDRs, "ipvs-exclude-cidrs", o.config.IPVS.ExcludeCIDRs, "A comma-separated list of CIDRs which the ipvs proxier should not touch when cleaning up IPVS rules.")
fs.BoolVar(&o.config.IPVS.StrictARP, "ipvs-strict-arp", o.config.IPVS.StrictARP, "Enable strict ARP by setting arp_ignore to 1 and arp_announce to 2") fs.BoolVar(&o.config.IPVS.StrictARP, "ipvs-strict-arp", o.config.IPVS.StrictARP, "Enable strict ARP by setting arp_ignore to 1 and arp_announce to 2")
@ -216,6 +224,8 @@ func (o *Options) Complete(fs *pflag.FlagSet) error {
if err := o.initWatcher(); err != nil { if err := o.initWatcher(); err != nil {
return err return err
} }
} else {
o.processV1Alpha1Flags(fs)
} }
o.platformApplyDefaults(o.config) o.platformApplyDefaults(o.config)
@ -302,6 +312,22 @@ func (o *Options) processHostnameOverrideFlag() error {
return nil return nil
} }
// processV1Alpha1Flags processes v1alpha1 flags which can't be directly mapped to internal config.
func (o *Options) processV1Alpha1Flags(fs *pflag.FlagSet) {
if fs.Changed("iptables-sync-period") && o.config.Mode != kubeproxyconfig.ProxyModeIPVS {
o.config.SyncPeriod.Duration = o.iptablesSyncPeriod
}
if fs.Changed("iptables-min-sync-period") && o.config.Mode != kubeproxyconfig.ProxyModeIPVS {
o.config.MinSyncPeriod.Duration = o.iptablesMinSyncPeriod
}
if fs.Changed("ipvs-sync-period") && o.config.Mode == kubeproxyconfig.ProxyModeIPVS {
o.config.SyncPeriod.Duration = o.ipvsSyncPeriod
}
if fs.Changed("ipvs-min-sync-period") && o.config.Mode == kubeproxyconfig.ProxyModeIPVS {
o.config.MinSyncPeriod.Duration = o.ipvsMinSyncPeriod
}
}
// Validate validates all the required options. // Validate validates all the required options.
func (o *Options) Validate() error { func (o *Options) Validate() error {
if errs := validation.Validate(o.config); len(errs) != 0 { if errs := validation.Validate(o.config); len(errs) != 0 {

View File

@ -195,6 +195,8 @@ nodePortAddresses:
QPS: 7, QPS: 7,
}, },
ClusterCIDR: tc.clusterCIDR, ClusterCIDR: tc.clusterCIDR,
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 15 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 15 * time.Second},
Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{ Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
@ -212,18 +214,12 @@ nodePortAddresses:
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](17), MasqueradeBit: ptr.To[int32](17),
LocalhostNodePorts: ptr.To(true), LocalhostNodePorts: ptr.To(true),
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
}, },
IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{ IPVS: kubeproxyconfig.KubeProxyIPVSConfiguration{
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second}, ExcludeCIDRs: []string{"10.20.30.40/16", "fd00:1::0/64"},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
ExcludeCIDRs: []string{"10.20.30.40/16", "fd00:1::0/64"},
}, },
NFTables: kubeproxyconfig.KubeProxyNFTablesConfiguration{ NFTables: kubeproxyconfig.KubeProxyNFTablesConfiguration{
MasqueradeBit: ptr.To[int32](18), MasqueradeBit: ptr.To[int32](18),
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
}, },
MetricsBindAddress: tc.metricsBindAddress, MetricsBindAddress: tc.metricsBindAddress,
Mode: kubeproxyconfig.ProxyMode(tc.mode), Mode: kubeproxyconfig.ProxyMode(tc.mode),
@ -377,6 +373,90 @@ func TestProcessHostnameOverrideFlag(t *testing.T) {
} }
} }
// TestProcessV1Alpha1Flags tests processing v1alpha1 flags.
func TestProcessV1Alpha1Flags(t *testing.T) {
testCases := []struct {
name string
flags []string
validate func(*kubeproxyconfig.KubeProxyConfiguration) bool
}{
{
name: "iptables configuration",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--proxy-mode=iptables",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 36 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 3 * time.Second}
},
},
{
name: "iptables + ipvs configuration with iptables mode",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--ipvs-sync-period=16s",
"--ipvs-min-sync-period=7s",
"--proxy-mode=iptables",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 36 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 3 * time.Second}
},
},
{
name: "winkernel configuration",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--proxy-mode=kernelspace",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 36 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 3 * time.Second}
},
},
{
name: "ipvs + iptables configuration with ipvs mode",
flags: []string{
"--iptables-sync-period=36s",
"--iptables-min-sync-period=3s",
"--ipvs-sync-period=16s",
"--ipvs-min-sync-period=7s",
"--proxy-mode=ipvs",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 16 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 7 * time.Second}
},
},
{
name: "ipvs configuration",
flags: []string{
"--ipvs-sync-period=16s",
"--ipvs-min-sync-period=7s",
"--proxy-mode=ipvs",
},
validate: func(config *kubeproxyconfig.KubeProxyConfiguration) bool {
return config.SyncPeriod == metav1.Duration{Duration: 16 * time.Second} &&
config.MinSyncPeriod == metav1.Duration{Duration: 7 * time.Second}
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
options := NewOptions()
fs := new(pflag.FlagSet)
options.AddFlags(fs)
require.NoError(t, fs.Parse(tc.flags))
options.processV1Alpha1Flags(fs)
require.True(t, tc.validate(options.config))
})
}
}
// TestOptionsComplete checks that command line flags are combined with a // TestOptionsComplete checks that command line flags are combined with a
// config properly. // config properly.
func TestOptionsComplete(t *testing.T) { func TestOptionsComplete(t *testing.T) {

View File

@ -222,7 +222,7 @@ func newProxyServer(ctx context.Context, config *kubeproxyconfig.KubeProxyConfig
} }
if len(config.HealthzBindAddress) > 0 { if len(config.HealthzBindAddress) > 0 {
s.HealthzServer = healthcheck.NewProxierHealthServer(config.HealthzBindAddress, 2*config.IPTables.SyncPeriod.Duration) s.HealthzServer = healthcheck.NewProxierHealthServer(config.HealthzBindAddress, 2*config.SyncPeriod.Duration)
} }
err = s.platformSetup(ctx) err = s.platformSetup(ctx)

View File

@ -178,8 +178,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
ipt, ipt,
utilsysctl.New(), utilsysctl.New(),
exec.New(), exec.New(),
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
*config.IPTables.LocalhostNodePorts, *config.IPTables.LocalhostNodePorts,
int(*config.IPTables.MasqueradeBit), int(*config.IPTables.MasqueradeBit),
@ -202,8 +202,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
iptInterface, iptInterface,
utilsysctl.New(), utilsysctl.New(),
exec.New(), exec.New(),
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
*config.IPTables.LocalhostNodePorts, *config.IPTables.LocalhostNodePorts,
int(*config.IPTables.MasqueradeBit), int(*config.IPTables.MasqueradeBit),
@ -238,8 +238,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
ipsetInterface, ipsetInterface,
utilsysctl.New(), utilsysctl.New(),
execer, execer,
config.IPVS.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPVS.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.IPVS.ExcludeCIDRs, config.IPVS.ExcludeCIDRs,
config.IPVS.StrictARP, config.IPVS.StrictARP,
config.IPVS.TCPTimeout.Duration, config.IPVS.TCPTimeout.Duration,
@ -266,8 +266,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
ipsetInterface, ipsetInterface,
utilsysctl.New(), utilsysctl.New(),
execer, execer,
config.IPVS.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPVS.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.IPVS.ExcludeCIDRs, config.IPVS.ExcludeCIDRs,
config.IPVS.StrictARP, config.IPVS.StrictARP,
config.IPVS.TCPTimeout.Duration, config.IPVS.TCPTimeout.Duration,
@ -295,8 +295,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
// TODO this has side effects that should only happen when Run() is invoked. // TODO this has side effects that should only happen when Run() is invoked.
proxier, err = nftables.NewDualStackProxier( proxier, err = nftables.NewDualStackProxier(
ctx, ctx,
config.NFTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.NFTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
int(*config.NFTables.MasqueradeBit), int(*config.NFTables.MasqueradeBit),
localDetectors, localDetectors,
@ -313,8 +313,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
proxier, err = nftables.NewProxier( proxier, err = nftables.NewProxier(
ctx, ctx,
s.PrimaryIPFamily, s.PrimaryIPFamily,
config.NFTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.NFTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
config.Linux.MasqueradeAll, config.Linux.MasqueradeAll,
int(*config.NFTables.MasqueradeBit), int(*config.NFTables.MasqueradeBit),
localDetectors[s.PrimaryIPFamily], localDetectors[s.PrimaryIPFamily],

View File

@ -91,8 +91,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
if dualStackMode { if dualStackMode {
proxier, err = winkernel.NewDualStackProxier( proxier, err = winkernel.NewDualStackProxier(
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
s.Hostname, s.Hostname,
s.NodeIPs, s.NodeIPs,
s.Recorder, s.Recorder,
@ -103,8 +103,8 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
} else { } else {
proxier, err = winkernel.NewProxier( proxier, err = winkernel.NewProxier(
s.PrimaryIPFamily, s.PrimaryIPFamily,
config.IPTables.SyncPeriod.Duration, config.SyncPeriod.Duration,
config.IPTables.MinSyncPeriod.Duration, config.MinSyncPeriod.Duration,
s.Hostname, s.Hostname,
s.NodeIPs[s.PrimaryIPFamily], s.NodeIPs[s.PrimaryIPFamily],
s.Recorder, s.Recorder,

View File

@ -35,7 +35,7 @@ ipvs:
minSyncPeriod: 0s minSyncPeriod: 0s
scheduler: "" scheduler: ""
strictARP: false strictARP: false
syncPeriod: 30s syncPeriod: 0s
tcpFinTimeout: 0s tcpFinTimeout: 0s
tcpTimeout: 0s tcpTimeout: 0s
udpTimeout: 0s udpTimeout: 0s
@ -54,8 +54,8 @@ mode: ""
nftables: nftables:
masqueradeAll: false masqueradeAll: false
masqueradeBit: 14 masqueradeBit: 14
minSyncPeriod: 1s minSyncPeriod: 0s
syncPeriod: 30s syncPeriod: 0s
nodePortAddresses: null nodePortAddresses: null
oomScoreAdj: -999 oomScoreAdj: -999
portRange: "" portRange: ""

View File

@ -35,7 +35,7 @@ ipvs:
minSyncPeriod: 0s minSyncPeriod: 0s
scheduler: "" scheduler: ""
strictARP: false strictARP: false
syncPeriod: 30s syncPeriod: 0s
tcpFinTimeout: 0s tcpFinTimeout: 0s
tcpTimeout: 0s tcpTimeout: 0s
udpTimeout: 0s udpTimeout: 0s
@ -54,8 +54,8 @@ mode: ""
nftables: nftables:
masqueradeAll: false masqueradeAll: false
masqueradeBit: 14 masqueradeBit: 14
minSyncPeriod: 1s minSyncPeriod: 0s
syncPeriod: 30s syncPeriod: 0s
nodePortAddresses: null nodePortAddresses: null
oomScoreAdj: -999 oomScoreAdj: -999
portRange: "" portRange: ""

View File

@ -53,27 +53,11 @@ type KubeProxyIPTablesConfiguration struct {
// iptables mode and IPv4; localhost NodePorts are never allowed with other proxy // iptables mode and IPv4; localhost NodePorts are never allowed with other proxy
// modes or with IPv6.) // modes or with IPv6.)
LocalhostNodePorts *bool LocalhostNodePorts *bool
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between iptables rule resyncs (e.g. '5s',
// '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will
// result in an immediate iptables resync.
MinSyncPeriod metav1.Duration
} }
// KubeProxyIPVSConfiguration contains ipvs-related configuration // KubeProxyIPVSConfiguration contains ipvs-related configuration
// details for the Kubernetes proxy server. // details for the Kubernetes proxy server.
type KubeProxyIPVSConfiguration struct { type KubeProxyIPVSConfiguration struct {
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between IPVS rule resyncs (e.g. '5s', '1m',
// '2h22m'). A value of 0 means every Service or EndpointSlice change will result
// in an immediate IPVS resync.
MinSyncPeriod metav1.Duration
// scheduler is the IPVS scheduler to use // scheduler is the IPVS scheduler to use
Scheduler string Scheduler string
// excludeCIDRs is a list of CIDRs which the ipvs proxier should not touch // excludeCIDRs is a list of CIDRs which the ipvs proxier should not touch
@ -99,14 +83,6 @@ type KubeProxyNFTablesConfiguration struct {
// masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using // masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using
// the nftables proxy mode. Values must be within the range [0, 31]. // the nftables proxy mode. Values must be within the range [0, 31].
MasqueradeBit *int32 MasqueradeBit *int32
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between iptables rule resyncs (e.g. '5s',
// '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will
// result in an immediate iptables resync.
MinSyncPeriod metav1.Duration
} }
// KubeProxyConntrackConfiguration contains conntrack settings for // KubeProxyConntrackConfiguration contains conntrack settings for
@ -251,6 +227,14 @@ type KubeProxyConfiguration struct {
// object. If unset, NodePort connections will be accepted on all local IPs. // object. If unset, NodePort connections will be accepted on all local IPs.
NodePortAddresses []string NodePortAddresses []string
// syncPeriod is an interval (e.g. '5s', '1m', '2h22m') indicating how frequently
// various re-synchronizing and cleanup operations are performed. Must be greater
// than 0.
SyncPeriod metav1.Duration
// minSyncPeriod is the minimum period between proxier rule resyncs (e.g. '5s',
// '1m', '2h22m'). A value of 0 means every Service or EndpointSlice change will
// result in an immediate proxier resync.
MinSyncPeriod metav1.Duration
// configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater // configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater
// than 0. // than 0.
ConfigSyncPeriod metav1.Duration ConfigSyncPeriod metav1.Duration

View File

@ -36,6 +36,18 @@ func Convert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguration(in
default: default:
out.IPTables.MasqueradeAll = in.Linux.MasqueradeAll out.IPTables.MasqueradeAll = in.Linux.MasqueradeAll
} }
switch in.Mode {
case config.ProxyModeIPVS:
out.IPVS.SyncPeriod = in.SyncPeriod
out.IPVS.MinSyncPeriod = in.MinSyncPeriod
case config.ProxyModeNFTables:
out.NFTables.SyncPeriod = in.SyncPeriod
out.NFTables.MinSyncPeriod = in.MinSyncPeriod
default:
out.IPTables.SyncPeriod = in.SyncPeriod
out.IPTables.MinSyncPeriod = in.MinSyncPeriod
}
return nil return nil
} }
@ -53,6 +65,18 @@ func Convert_v1alpha1_KubeProxyConfiguration_To_config_KubeProxyConfiguration(in
default: default:
out.Linux.MasqueradeAll = in.IPTables.MasqueradeAll out.Linux.MasqueradeAll = in.IPTables.MasqueradeAll
} }
switch config.ProxyMode(in.Mode) {
case config.ProxyModeIPVS:
out.SyncPeriod = in.IPVS.SyncPeriod
out.MinSyncPeriod = in.IPVS.MinSyncPeriod
case config.ProxyModeNFTables:
out.SyncPeriod = in.NFTables.SyncPeriod
out.MinSyncPeriod = in.NFTables.MinSyncPeriod
default:
out.SyncPeriod = in.IPTables.SyncPeriod
out.MinSyncPeriod = in.IPTables.MinSyncPeriod
}
return nil return nil
} }
@ -61,6 +85,11 @@ func Convert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTables
return autoConvert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTablesConfiguration(in, out, scope) return autoConvert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTablesConfiguration(in, out, scope)
} }
// Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration is defined here, because public conversion is not auto-generated due to existing warnings.
func Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, scope conversion.Scope) error {
return autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in, out, scope)
}
// Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration is defined here, because public conversion is not auto-generated due to existing warnings. // Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration is defined here, because public conversion is not auto-generated due to existing warnings.
func Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, scope conversion.Scope) error { func Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, scope conversion.Scope) error {
return autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in, out, scope) return autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in, out, scope)

View File

@ -64,11 +64,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddGeneratedConversionFunc((*v1alpha1.KubeProxyIPVSConfiguration)(nil), (*config.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(a.(*v1alpha1.KubeProxyIPVSConfiguration), b.(*config.KubeProxyIPVSConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*config.KubeProxyIPVSConfiguration)(nil), (*v1alpha1.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddGeneratedConversionFunc((*config.KubeProxyIPVSConfiguration)(nil), (*v1alpha1.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(a.(*config.KubeProxyIPVSConfiguration), b.(*v1alpha1.KubeProxyIPVSConfiguration), scope) return Convert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(a.(*config.KubeProxyIPVSConfiguration), b.(*v1alpha1.KubeProxyIPVSConfiguration), scope)
}); err != nil { }); err != nil {
@ -104,6 +99,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil { }); err != nil {
return err return err
} }
if err := s.AddConversionFunc((*v1alpha1.KubeProxyIPVSConfiguration)(nil), (*config.KubeProxyIPVSConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(a.(*v1alpha1.KubeProxyIPVSConfiguration), b.(*config.KubeProxyIPVSConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*v1alpha1.KubeProxyNFTablesConfiguration)(nil), (*config.KubeProxyNFTablesConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { if err := s.AddConversionFunc((*v1alpha1.KubeProxyNFTablesConfiguration)(nil), (*config.KubeProxyNFTablesConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(a.(*v1alpha1.KubeProxyNFTablesConfiguration), b.(*config.KubeProxyNFTablesConfiguration), scope) return Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(a.(*v1alpha1.KubeProxyNFTablesConfiguration), b.(*config.KubeProxyNFTablesConfiguration), scope)
}); err != nil { }); err != nil {
@ -208,6 +208,8 @@ func autoConvert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguratio
} }
out.ClusterCIDR = in.ClusterCIDR out.ClusterCIDR = in.ClusterCIDR
out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses)) out.NodePortAddresses = *(*[]string)(unsafe.Pointer(&in.NodePortAddresses))
// WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
// WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
out.ConfigSyncPeriod = in.ConfigSyncPeriod out.ConfigSyncPeriod = in.ConfigSyncPeriod
out.PortRange = in.PortRange out.PortRange = in.PortRange
return nil return nil
@ -249,16 +251,14 @@ func autoConvert_v1alpha1_KubeProxyIPTablesConfiguration_To_config_KubeProxyIPTa
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
// WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type // WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type
out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts)) out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts))
out.SyncPeriod = in.SyncPeriod // WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
out.MinSyncPeriod = in.MinSyncPeriod // WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
return nil return nil
} }
func autoConvert_config_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(in *config.KubeProxyIPTablesConfiguration, out *v1alpha1.KubeProxyIPTablesConfiguration, s conversion.Scope) error { func autoConvert_config_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTablesConfiguration(in *config.KubeProxyIPTablesConfiguration, out *v1alpha1.KubeProxyIPTablesConfiguration, s conversion.Scope) error {
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts)) out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts))
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return nil return nil
} }
@ -268,8 +268,8 @@ func Convert_config_KubeProxyIPTablesConfiguration_To_v1alpha1_KubeProxyIPTables
} }
func autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, s conversion.Scope) error { func autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, s conversion.Scope) error {
out.SyncPeriod = in.SyncPeriod // WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
out.MinSyncPeriod = in.MinSyncPeriod // WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
out.Scheduler = in.Scheduler out.Scheduler = in.Scheduler
out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs)) out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs))
out.StrictARP = in.StrictARP out.StrictARP = in.StrictARP
@ -279,14 +279,7 @@ func autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConf
return nil return nil
} }
// Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration is an autogenerated conversion function.
func Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in *v1alpha1.KubeProxyIPVSConfiguration, out *config.KubeProxyIPVSConfiguration, s conversion.Scope) error {
return autoConvert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(in, out, s)
}
func autoConvert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in *config.KubeProxyIPVSConfiguration, out *v1alpha1.KubeProxyIPVSConfiguration, s conversion.Scope) error { func autoConvert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in *config.KubeProxyIPVSConfiguration, out *v1alpha1.KubeProxyIPVSConfiguration, s conversion.Scope) error {
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
out.Scheduler = in.Scheduler out.Scheduler = in.Scheduler
out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs)) out.ExcludeCIDRs = *(*[]string)(unsafe.Pointer(&in.ExcludeCIDRs))
out.StrictARP = in.StrictARP out.StrictARP = in.StrictARP
@ -304,15 +297,13 @@ func Convert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfigur
func autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, s conversion.Scope) error { func autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, s conversion.Scope) error {
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
// WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type // WARNING: in.MasqueradeAll requires manual conversion: does not exist in peer-type
out.SyncPeriod = in.SyncPeriod // WARNING: in.SyncPeriod requires manual conversion: does not exist in peer-type
out.MinSyncPeriod = in.MinSyncPeriod // WARNING: in.MinSyncPeriod requires manual conversion: does not exist in peer-type
return nil return nil
} }
func autoConvert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(in *config.KubeProxyNFTablesConfiguration, out *v1alpha1.KubeProxyNFTablesConfiguration, s conversion.Scope) error { func autoConvert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(in *config.KubeProxyNFTablesConfiguration, out *v1alpha1.KubeProxyNFTablesConfiguration, s conversion.Scope) error {
out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit)) out.MasqueradeBit = (*int32)(unsafe.Pointer(in.MasqueradeBit))
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return nil return nil
} }

View File

@ -61,6 +61,15 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList {
if config.ConfigSyncPeriod.Duration <= 0 { if config.ConfigSyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(newPath.Child("ConfigSyncPeriod"), config.ConfigSyncPeriod, "must be greater than 0")) allErrs = append(allErrs, field.Invalid(newPath.Child("ConfigSyncPeriod"), config.ConfigSyncPeriod, "must be greater than 0"))
} }
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(newPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(newPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(newPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", newPath.Child("MinSyncPeriod").String())))
}
if netutils.ParseIPSloppy(config.BindAddress) == nil { if netutils.ParseIPSloppy(config.BindAddress) == nil {
allErrs = append(allErrs, field.Invalid(newPath.Child("BindAddress"), config.BindAddress, "not a valid textual representation of an IP address")) allErrs = append(allErrs, field.Invalid(newPath.Child("BindAddress"), config.BindAddress, "not a valid textual representation of an IP address"))
@ -115,37 +124,12 @@ func validateKubeProxyIPTablesConfiguration(config kubeproxyconfig.KubeProxyIPTa
if config.MasqueradeBit != nil && (*config.MasqueradeBit < 0 || *config.MasqueradeBit > 31) { if config.MasqueradeBit != nil && (*config.MasqueradeBit < 0 || *config.MasqueradeBit > 31) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]")) allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]"))
} }
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", fldPath.Child("MinSyncPeriod").String())))
}
return allErrs return allErrs
} }
func validateKubeProxyIPVSConfiguration(config kubeproxyconfig.KubeProxyIPVSConfiguration, fldPath *field.Path) field.ErrorList { func validateKubeProxyIPVSConfiguration(config kubeproxyconfig.KubeProxyIPVSConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", fldPath.Child("MinSyncPeriod").String())))
}
allErrs = append(allErrs, validateIPVSTimeout(config, fldPath)...) allErrs = append(allErrs, validateIPVSTimeout(config, fldPath)...)
allErrs = append(allErrs, validateIPVSExcludeCIDRs(config.ExcludeCIDRs, fldPath.Child("ExcludeCidrs"))...) allErrs = append(allErrs, validateIPVSExcludeCIDRs(config.ExcludeCIDRs, fldPath.Child("ExcludeCidrs"))...)
@ -159,18 +143,6 @@ func validateKubeProxyNFTablesConfiguration(config kubeproxyconfig.KubeProxyNFTa
allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]")) allErrs = append(allErrs, field.Invalid(fldPath.Child("MasqueradeBit"), config.MasqueradeBit, "must be within the range [0, 31]"))
} }
if config.SyncPeriod.Duration <= 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.SyncPeriod, "must be greater than 0"))
}
if config.MinSyncPeriod.Duration < 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("MinSyncPeriod"), config.MinSyncPeriod, "must be greater than or equal to 0"))
}
if config.MinSyncPeriod.Duration > config.SyncPeriod.Duration {
allErrs = append(allErrs, field.Invalid(fldPath.Child("SyncPeriod"), config.MinSyncPeriod, fmt.Sprintf("must be greater than or equal to %s", fldPath.Child("MinSyncPeriod").String())))
}
return allErrs return allErrs
} }

View File

@ -1,42 +0,0 @@
//go:build !windows
// +build !windows
/*
Copyright 2024 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 validation
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
)
var (
kubeProxyConfigNewPath = field.NewPath("KubeProxyConfiguration")
osKubeProxyConfigTestCases = map[string]struct {
mutateConfigFunc func(*kubeproxyconfig.KubeProxyConfiguration)
expectedErrs field.ErrorList
}{
// Windows doesn't support IPVS, so this test will fail.
"IPVS mode selected without providing required SyncPeriod": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.Mode = kubeproxyconfig.ProxyModeIPVS
},
expectedErrs: field.ErrorList{field.Invalid(kubeProxyConfigNewPath.Child("KubeProxyIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 0}, "must be greater than 0")},
},
}
)

View File

@ -37,11 +37,10 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
HealthzBindAddress: "0.0.0.0:10256", HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
ClusterCIDR: "192.168.59.0/24", ClusterCIDR: "192.168.59.0/24",
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second}, ConfigSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{ IPTables: kubeproxyconfig.KubeProxyIPTablesConfiguration{},
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{ Linux: kubeproxyconfig.KubeProxyLinuxConfiguration{
Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{ Conntrack: kubeproxyconfig.KubeProxyConntrackConfiguration{
MaxPerCore: ptr.To[int32](1), MaxPerCore: ptr.To[int32](1),
@ -70,10 +69,6 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
config.Mode = kubeproxyconfig.ProxyModeKernelspace config.Mode = kubeproxyconfig.ProxyModeKernelspace
} else { } else {
config.Mode = kubeproxyconfig.ProxyModeIPVS config.Mode = kubeproxyconfig.ProxyModeIPVS
config.IPVS = kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
}
} }
}, },
}, },
@ -157,6 +152,26 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
}, },
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ConfigSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than 0")}, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ConfigSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than 0")},
}, },
"SyncPeriod must be > 0": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.SyncPeriod = metav1.Duration{Duration: -5 * time.Second}
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("SyncPeriod"), metav1.Duration{Duration: -5 * time.Second}, "must be greater than 0"),
field.Invalid(newPath.Child("SyncPeriod"), metav1.Duration{Duration: 2 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.MinSyncPeriod")},
},
"MinSyncPeriod must be > 0": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.MinSyncPeriod = metav1.Duration{Duration: -2 * time.Second}
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("MinSyncPeriod"), metav1.Duration{Duration: -2 * time.Second}, "must be greater than or equal to 0")},
},
"SyncPeriod must be >= MinSyncPeriod": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.SyncPeriod = metav1.Duration{Duration: 1 * time.Second}
config.MinSyncPeriod = metav1.Duration{Duration: 5 * time.Second}
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("SyncPeriod"), metav1.Duration{Duration: 5 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.MinSyncPeriod")},
},
"interfacePrefix is empty": { "interfacePrefix is empty": {
mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) { mutateConfigFunc: func(config *kubeproxyconfig.KubeProxyConfiguration) {
config.DetectLocalMode = kubeproxyconfig.LocalModeInterfaceNamePrefix config.DetectLocalMode = kubeproxyconfig.LocalModeInterfaceNamePrefix
@ -191,10 +206,6 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
}, },
} }
for name, testCase := range osKubeProxyConfigTestCases {
testCases[name] = testCase
}
for name, testCase := range testCases { for name, testCase := range testCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
config := baseConfig.DeepCopy() config := baseConfig.DeepCopy()
@ -216,53 +227,18 @@ func TestValidateKubeProxyIPTablesConfiguration(t *testing.T) {
config kubeproxyconfig.KubeProxyIPTablesConfiguration config kubeproxyconfig.KubeProxyIPTablesConfiguration
expectedErrs field.ErrorList expectedErrs field.ErrorList
}{ }{
"valid iptables config": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"valid custom MasqueradeBit": { "valid custom MasqueradeBit": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{ config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](5), MasqueradeBit: ptr.To[int32](5),
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
}, },
expectedErrs: field.ErrorList{}, expectedErrs: field.ErrorList{},
}, },
"SyncPeriod must be > 0": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
SyncPeriod: metav1.Duration{Duration: -5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.SyncPeriod"), metav1.Duration{Duration: -5 * time.Second}, "must be greater than 0"),
field.Invalid(newPath.Child("KubeIPTablesConfiguration.SyncPeriod"), metav1.Duration{Duration: 2 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPTablesConfiguration.MinSyncPeriod")},
},
"MinSyncPeriod must be > 0": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](5),
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.MinSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than or equal to 0")},
},
"MasqueradeBit cannot be < 0": { "MasqueradeBit cannot be < 0": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{ config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](-10), MasqueradeBit: ptr.To[int32](-10),
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
}, },
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.MasqueradeBit"), ptr.To[int32](-10), "must be within the range [0, 31]")}, expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.MasqueradeBit"), ptr.To[int32](-10), "must be within the range [0, 31]")},
}, },
"SyncPeriod must be >= MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPTablesConfiguration{
MasqueradeBit: ptr.To[int32](5),
SyncPeriod: metav1.Duration{Duration: 1 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPTablesConfiguration.SyncPeriod"), metav1.Duration{Duration: 5 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPTablesConfiguration.MinSyncPeriod")},
},
} { } {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
errs := validateKubeProxyIPTablesConfiguration(testCase.config, newPath.Child("KubeIPTablesConfiguration")) errs := validateKubeProxyIPTablesConfiguration(testCase.config, newPath.Child("KubeIPTablesConfiguration"))
@ -277,60 +253,8 @@ func TestValidateKubeProxyIPVSConfiguration(t *testing.T) {
config kubeproxyconfig.KubeProxyIPVSConfiguration config kubeproxyconfig.KubeProxyIPVSConfiguration
expectedErrs field.ErrorList expectedErrs field.ErrorList
}{ }{
"SyncPeriod is not greater than 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: -5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 2 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: -5 * time.Second}, "must be greater than 0"),
field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 2 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPVSConfiguration.MinSyncPeriod")},
},
"SyncPeriod cannot be 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 0 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 0}, "must be greater than 0"),
field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 10 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPVSConfiguration.MinSyncPeriod")},
},
"MinSyncPeriod cannot be less than 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: -1 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.MinSyncPeriod"), metav1.Duration{Duration: -1 * time.Second}, "must be greater than or equal to 0")},
},
"SyncPeriod must be greater than MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 1 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("KubeIPVSConfiguration.SyncPeriod"), metav1.Duration{Duration: 5 * time.Second}, "must be greater than or equal to KubeProxyConfiguration.KubeIPVSConfiguration.MinSyncPeriod")},
},
"SyncPeriod == MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"SyncPeriod should be > MinSyncPeriod": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 10 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 5 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"MinSyncPeriod can be 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 0 * time.Second},
},
expectedErrs: field.ErrorList{},
},
"IPVS Timeout can be 0": { "IPVS Timeout can be 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{ config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
TCPTimeout: metav1.Duration{Duration: 0 * time.Second}, TCPTimeout: metav1.Duration{Duration: 0 * time.Second},
TCPFinTimeout: metav1.Duration{Duration: 0 * time.Second}, TCPFinTimeout: metav1.Duration{Duration: 0 * time.Second},
UDPTimeout: metav1.Duration{Duration: 0 * time.Second}, UDPTimeout: metav1.Duration{Duration: 0 * time.Second},
@ -339,7 +263,6 @@ func TestValidateKubeProxyIPVSConfiguration(t *testing.T) {
}, },
"IPVS Timeout > 0": { "IPVS Timeout > 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{ config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
TCPTimeout: metav1.Duration{Duration: 1 * time.Second}, TCPTimeout: metav1.Duration{Duration: 1 * time.Second},
TCPFinTimeout: metav1.Duration{Duration: 2 * time.Second}, TCPFinTimeout: metav1.Duration{Duration: 2 * time.Second},
UDPTimeout: metav1.Duration{Duration: 3 * time.Second}, UDPTimeout: metav1.Duration{Duration: 3 * time.Second},
@ -348,7 +271,6 @@ func TestValidateKubeProxyIPVSConfiguration(t *testing.T) {
}, },
"TCP,TCPFin,UDP Timeouts < 0": { "TCP,TCPFin,UDP Timeouts < 0": {
config: kubeproxyconfig.KubeProxyIPVSConfiguration{ config: kubeproxyconfig.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 5 * time.Second},
TCPTimeout: metav1.Duration{Duration: -1 * time.Second}, TCPTimeout: metav1.Duration{Duration: -1 * time.Second},
UDPTimeout: metav1.Duration{Duration: -1 * time.Second}, UDPTimeout: metav1.Duration{Duration: -1 * time.Second},
TCPFinTimeout: metav1.Duration{Duration: -1 * time.Second}, TCPFinTimeout: metav1.Duration{Duration: -1 * time.Second},

View File

@ -1,32 +0,0 @@
//go:build windows
// +build windows
/*
Copyright 2024 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 validation
import (
"k8s.io/apimachinery/pkg/util/validation/field"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
)
var (
osKubeProxyConfigTestCases = map[string]struct {
mutateConfigFunc func(*kubeproxyconfig.KubeProxyConfiguration)
expectedErrs field.ErrorList
}{}
)

View File

@ -67,6 +67,8 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
*out = make([]string, len(*in)) *out = make([]string, len(*in))
copy(*out, *in) copy(*out, *in)
} }
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
out.ConfigSyncPeriod = in.ConfigSyncPeriod out.ConfigSyncPeriod = in.ConfigSyncPeriod
return return
} }
@ -140,8 +142,6 @@ func (in *KubeProxyIPTablesConfiguration) DeepCopyInto(out *KubeProxyIPTablesCon
*out = new(bool) *out = new(bool)
**out = **in **out = **in
} }
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return return
} }
@ -158,8 +158,6 @@ func (in *KubeProxyIPTablesConfiguration) DeepCopy() *KubeProxyIPTablesConfigura
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyIPVSConfiguration) DeepCopyInto(out *KubeProxyIPVSConfiguration) { func (in *KubeProxyIPVSConfiguration) DeepCopyInto(out *KubeProxyIPVSConfiguration) {
*out = *in *out = *in
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
if in.ExcludeCIDRs != nil { if in.ExcludeCIDRs != nil {
in, out := &in.ExcludeCIDRs, &out.ExcludeCIDRs in, out := &in.ExcludeCIDRs, &out.ExcludeCIDRs
*out = make([]string, len(*in)) *out = make([]string, len(*in))
@ -211,8 +209,6 @@ func (in *KubeProxyNFTablesConfiguration) DeepCopyInto(out *KubeProxyNFTablesCon
*out = new(int32) *out = new(int32)
**out = **in **out = **in
} }
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return return
} }