Add a dummy nftables kube-proxy backend which is just a copy of iptables

This commit is contained in:
Dan Winship 2023-05-09 15:55:04 -04:00
parent 3631efd85c
commit a70653143e
18 changed files with 9049 additions and 5 deletions

View File

@ -553,6 +553,7 @@ API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,V
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,FlexVolumePluginDir
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,VolumeConfiguration,PersistentVolumeRecyclerConfiguration
API rule violation: names_match,k8s.io/kube-proxy/config/v1alpha1,KubeProxyConfiguration,IPTables
API rule violation: names_match,k8s.io/kube-proxy/config/v1alpha1,KubeProxyConfiguration,NFTables
API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,IPTablesDropBit
API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,IPTablesMasqueradeBit
API rule violation: names_match,k8s.io/kubelet/config/v1beta1,KubeletConfiguration,ResolverConfig

View File

@ -50,6 +50,7 @@ import (
utilipset "k8s.io/kubernetes/pkg/proxy/ipvs/ipset"
utilipvs "k8s.io/kubernetes/pkg/proxy/ipvs/util"
proxymetrics "k8s.io/kubernetes/pkg/proxy/metrics"
"k8s.io/kubernetes/pkg/proxy/nftables"
proxyutil "k8s.io/kubernetes/pkg/proxy/util"
proxyutiliptables "k8s.io/kubernetes/pkg/proxy/util/iptables"
utiliptables "k8s.io/kubernetes/pkg/util/iptables"
@ -282,6 +283,67 @@ func (s *ProxyServer) createProxier(config *proxyconfigapi.KubeProxyConfiguratio
initOnly,
)
}
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
} else if config.Mode == proxyconfigapi.ProxyModeNFTables {
klog.InfoS("Using nftables Proxier")
if dualStack {
// Always ordered to match []ipt
var localDetectors [2]proxyutiliptables.LocalTrafficDetector
localDetectors, err = getDualStackLocalDetectorTuple(config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
// TODO this has side effects that should only happen when Run() is invoked.
proxier, err = nftables.NewDualStackProxier(
ipt,
utilsysctl.New(),
execer,
config.NFTables.SyncPeriod.Duration,
config.NFTables.MinSyncPeriod.Duration,
config.NFTables.MasqueradeAll,
*config.NFTables.LocalhostNodePorts,
int(*config.NFTables.MasqueradeBit),
localDetectors,
s.Hostname,
s.NodeIPs,
s.Recorder,
s.HealthzServer,
config.NodePortAddresses,
initOnly,
)
} else {
// Create a single-stack proxier if and only if the node does not support dual-stack (i.e, no iptables support).
var localDetector proxyutiliptables.LocalTrafficDetector
localDetector, err = getLocalDetector(s.PrimaryIPFamily, config.DetectLocalMode, config, s.podCIDRs)
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
// TODO this has side effects that should only happen when Run() is invoked.
proxier, err = nftables.NewProxier(
s.PrimaryIPFamily,
iptInterface,
utilsysctl.New(),
execer,
config.NFTables.SyncPeriod.Duration,
config.NFTables.MinSyncPeriod.Duration,
config.NFTables.MasqueradeAll,
*config.NFTables.LocalhostNodePorts,
int(*config.NFTables.MasqueradeBit),
localDetector,
s.Hostname,
s.NodeIPs[s.PrimaryIPFamily],
s.Recorder,
s.HealthzServer,
config.NodePortAddresses,
initOnly,
)
}
if err != nil {
return nil, fmt.Errorf("unable to create proxier: %v", err)
}
@ -492,6 +554,7 @@ func cleanupAndExit() error {
for _, ipt := range ipts {
encounteredError = iptables.CleanupLeftovers(ipt) || encounteredError
encounteredError = ipvs.CleanupLeftovers(ipvsInterface, ipt, ipsetInterface) || encounteredError
encounteredError = nftables.CleanupLeftovers(ipt) || encounteredError
}
if encounteredError {
return errors.New("encountered an error while tearing down rules")

View File

@ -74,6 +74,12 @@ ipvs:
excludeCIDRs:
- "10.20.30.40/16"
- "fd00:1::0/64"
nftables:
masqueradeAll: true
masqueradeBit: 18
minSyncPeriod: 10s
syncPeriod: 60s
localhostNodePorts: false
kind: KubeProxyConfiguration
metricsBindAddress: "%s"
mode: "%s"
@ -218,6 +224,13 @@ nodePortAddresses:
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
ExcludeCIDRs: []string{"10.20.30.40/16", "fd00:1::0/64"},
},
NFTables: kubeproxyconfig.KubeProxyNFTablesConfiguration{
MasqueradeAll: true,
MasqueradeBit: ptr.To[int32](18),
LocalhostNodePorts: ptr.To(false),
MinSyncPeriod: metav1.Duration{Duration: 10 * time.Second},
SyncPeriod: metav1.Duration{Duration: 60 * time.Second},
},
MetricsBindAddress: tc.metricsBindAddress,
Mode: kubeproxyconfig.ProxyMode(tc.mode),
OOMScoreAdj: ptr.To[int32](17),

View File

@ -564,6 +564,13 @@ const (
// Robust VolumeManager reconstruction after kubelet restart.
NewVolumeManagerReconstruction featuregate.Feature = "NewVolumeManagerReconstruction"
// owner: @danwinship
// kep: https://kep.k8s.io/3866
// alpha: v1.29
//
// Allows running kube-proxy with `--mode nftables`.
NFTablesProxyMode featuregate.Feature = "NFTablesProxyMode"
// owner: @aravindhp @LorbusChris
// kep: http://kep.k8s.io/2271
// alpha: v1.27
@ -1103,6 +1110,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
NewVolumeManagerReconstruction: {Default: true, PreRelease: featuregate.Beta},
NFTablesProxyMode: {Default: false, PreRelease: featuregate.Alpha},
NodeLogQuery: {Default: false, PreRelease: featuregate.Alpha},
NodeOutOfServiceVolumeDetach: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31

View File

@ -1095,6 +1095,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
"k8s.io/kube-proxy/config/v1alpha1.KubeProxyConntrackConfiguration": schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyConntrackConfiguration(ref),
"k8s.io/kube-proxy/config/v1alpha1.KubeProxyIPTablesConfiguration": schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyIPTablesConfiguration(ref),
"k8s.io/kube-proxy/config/v1alpha1.KubeProxyIPVSConfiguration": schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyIPVSConfiguration(ref),
"k8s.io/kube-proxy/config/v1alpha1.KubeProxyNFTablesConfiguration": schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyNFTablesConfiguration(ref),
"k8s.io/kube-proxy/config/v1alpha1.KubeProxyWinkernelConfiguration": schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyWinkernelConfiguration(ref),
"k8s.io/kube-scheduler/config/v1.DefaultPreemptionArgs": schema_k8sio_kube_scheduler_config_v1_DefaultPreemptionArgs(ref),
"k8s.io/kube-scheduler/config/v1.Extender": schema_k8sio_kube_scheduler_config_v1_Extender(ref),
@ -54415,6 +54416,13 @@ func schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyConfiguration(ref common.R
Ref: ref("k8s.io/kube-proxy/config/v1alpha1.KubeProxyIPVSConfiguration"),
},
},
"nftables": {
SchemaProps: spec.SchemaProps{
Description: "nftables contains nftables-related configuration options.",
Default: map[string]interface{}{},
Ref: ref("k8s.io/kube-proxy/config/v1alpha1.KubeProxyNFTablesConfiguration"),
},
},
"winkernel": {
SchemaProps: spec.SchemaProps{
Description: "winkernel contains winkernel-related configuration options.",
@ -54489,11 +54497,11 @@ func schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyConfiguration(ref common.R
},
},
},
Required: []string{"clientConnection", "hostnameOverride", "bindAddress", "healthzBindAddress", "metricsBindAddress", "bindAddressHardFail", "enableProfiling", "showHiddenMetricsForVersion", "mode", "iptables", "ipvs", "winkernel", "detectLocalMode", "detectLocal", "clusterCIDR", "nodePortAddresses", "oomScoreAdj", "conntrack", "configSyncPeriod", "portRange"},
Required: []string{"clientConnection", "hostnameOverride", "bindAddress", "healthzBindAddress", "metricsBindAddress", "bindAddressHardFail", "enableProfiling", "showHiddenMetricsForVersion", "mode", "iptables", "ipvs", "nftables", "winkernel", "detectLocalMode", "detectLocal", "clusterCIDR", "nodePortAddresses", "oomScoreAdj", "conntrack", "configSyncPeriod", "portRange"},
},
},
Dependencies: []string{
"k8s.io/apimachinery/pkg/apis/meta/v1.Duration", "k8s.io/component-base/config/v1alpha1.ClientConnectionConfiguration", "k8s.io/component-base/logs/api/v1.LoggingConfiguration", "k8s.io/kube-proxy/config/v1alpha1.DetectLocalConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyConntrackConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyIPTablesConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyIPVSConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyWinkernelConfiguration"},
"k8s.io/apimachinery/pkg/apis/meta/v1.Duration", "k8s.io/component-base/config/v1alpha1.ClientConnectionConfiguration", "k8s.io/component-base/logs/api/v1.LoggingConfiguration", "k8s.io/kube-proxy/config/v1alpha1.DetectLocalConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyConntrackConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyIPTablesConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyIPVSConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyNFTablesConfiguration", "k8s.io/kube-proxy/config/v1alpha1.KubeProxyWinkernelConfiguration"},
}
}
@ -54686,6 +54694,56 @@ func schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyIPVSConfiguration(ref comm
}
}
func schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyNFTablesConfiguration(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "KubeProxyNFTablesConfiguration contains nftables-related configuration details for the Kubernetes proxy server.",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"masqueradeBit": {
SchemaProps: spec.SchemaProps{
Description: "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].",
Type: []string{"integer"},
Format: "int32",
},
},
"masqueradeAll": {
SchemaProps: spec.SchemaProps{
Description: "masqueradeAll tells kube-proxy to SNAT all traffic sent to Service cluster IPs, when using the nftables mode. This may be required with some CNI plugins.",
Default: false,
Type: []string{"boolean"},
Format: "",
},
},
"localhostNodePorts": {
SchemaProps: spec.SchemaProps{
Description: "localhostNodePorts, if false, tells kube-proxy to disable the legacy behavior of allowing NodePort services to be accessed via localhost. FIXME: remove.",
Type: []string{"boolean"},
Format: "",
},
},
"syncPeriod": {
SchemaProps: spec.SchemaProps{
Description: "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.",
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"),
},
},
"minSyncPeriod": {
SchemaProps: spec.SchemaProps{
Description: "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.",
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"),
},
},
},
Required: []string{"masqueradeBit", "masqueradeAll", "localhostNodePorts", "syncPeriod", "minSyncPeriod"},
},
},
Dependencies: []string{
"k8s.io/apimachinery/pkg/apis/meta/v1.Duration"},
}
}
func schema_k8sio_kube_proxy_config_v1alpha1_KubeProxyWinkernelConfiguration(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{

View File

@ -43,6 +43,8 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
obj.HealthzBindAddress = fmt.Sprintf("%d.%d.%d.%d:%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(65536))
obj.IPTables.MasqueradeBit = ptr.To(c.Int31())
obj.IPTables.LocalhostNodePorts = ptr.To(c.RandBool())
obj.NFTables.MasqueradeBit = ptr.To(c.Int31())
obj.NFTables.LocalhostNodePorts = ptr.To(c.RandBool())
obj.MetricsBindAddress = fmt.Sprintf("%d.%d.%d.%d:%d", c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(256), c.Intn(65536))
obj.OOMScoreAdj = ptr.To(c.Int31())
obj.ClientConnection.ContentType = "bar"

View File

@ -49,6 +49,12 @@ logging:
verbosity: 0
metricsBindAddress: 127.0.0.1:10249
mode: ""
nftables:
localhostNodePorts: true
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 1s
syncPeriod: 30s
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""

View File

@ -49,6 +49,12 @@ logging:
verbosity: 0
metricsBindAddress: 127.0.0.1:10249
mode: ""
nftables:
localhostNodePorts: true
masqueradeAll: false
masqueradeBit: 14
minSyncPeriod: 1s
syncPeriod: 30s
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""

View File

@ -81,6 +81,28 @@ type KubeProxyIPVSConfiguration struct {
UDPTimeout metav1.Duration
}
// KubeProxyNFTablesConfiguration contains nftables-related configuration
// details for the Kubernetes proxy server.
type KubeProxyNFTablesConfiguration struct {
// 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].
MasqueradeBit *int32
// masqueradeAll tells kube-proxy to SNAT all traffic sent to Service cluster IPs,
// when using the nftables mode. This may be required with some CNI plugins.
MasqueradeAll bool
// localhostNodePorts, if false, tells kube-proxy to disable the legacy behavior
// of allowing NodePort services to be accessed via localhost. FIXME: remove.
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
}
// KubeProxyConntrackConfiguration contains conntrack settings for
// the Kubernetes proxy server.
type KubeProxyConntrackConfiguration struct {
@ -195,6 +217,8 @@ type KubeProxyConfiguration struct {
IPVS KubeProxyIPVSConfiguration
// winkernel contains winkernel-related configuration options.
Winkernel KubeProxyWinkernelConfiguration
// nftables contains nftables-related configuration options.
NFTables KubeProxyNFTablesConfiguration
// detectLocalMode determines mode to use for detecting local traffic, defaults to LocalModeClusterCIDR
DetectLocalMode LocalMode
@ -228,8 +252,8 @@ type KubeProxyConfiguration struct {
// ProxyMode represents modes used by the Kubernetes proxy server.
//
// Currently, two modes of proxy are available on Linux platforms: 'iptables' and 'ipvs'.
// One mode of proxy is available on Windows platforms: 'kernelspace'.
// Currently, three modes of proxy are available on Linux platforms: 'iptables', 'ipvs',
// and 'nftables'. One mode of proxy is available on Windows platforms: 'kernelspace'.
//
// If the proxy mode is unspecified, the best-available proxy mode will be used (currently this
// is `iptables` on Linux and `kernelspace` on Windows). If the selected proxy mode cannot be
@ -240,6 +264,7 @@ type ProxyMode string
const (
ProxyModeIPTables ProxyMode = "iptables"
ProxyModeIPVS ProxyMode = "ipvs"
ProxyModeNFTables ProxyMode = "nftables"
ProxyModeKernelspace ProxyMode = "kernelspace"
)

View File

@ -71,6 +71,15 @@ func SetDefaults_KubeProxyConfiguration(obj *kubeproxyconfigv1alpha1.KubeProxyCo
if obj.IPVS.SyncPeriod.Duration == 0 {
obj.IPVS.SyncPeriod = metav1.Duration{Duration: 30 * time.Second}
}
if obj.NFTables.SyncPeriod.Duration == 0 {
obj.NFTables.SyncPeriod = metav1.Duration{Duration: 30 * time.Second}
}
if obj.NFTables.MinSyncPeriod.Duration == 0 {
obj.NFTables.MinSyncPeriod = metav1.Duration{Duration: 1 * time.Second}
}
if obj.NFTables.LocalhostNodePorts == nil {
obj.NFTables.LocalhostNodePorts = ptr.To(true)
}
if obj.Conntrack.MaxPerCore == nil {
obj.Conntrack.MaxPerCore = ptr.To[int32](32 * 1024)
@ -83,6 +92,10 @@ func SetDefaults_KubeProxyConfiguration(obj *kubeproxyconfigv1alpha1.KubeProxyCo
temp := int32(14)
obj.IPTables.MasqueradeBit = &temp
}
if obj.NFTables.MasqueradeBit == nil {
temp := int32(14)
obj.NFTables.MasqueradeBit = &temp
}
if obj.Conntrack.TCPEstablishedTimeout == nil {
obj.Conntrack.TCPEstablishedTimeout = &metav1.Duration{Duration: 24 * time.Hour} // 1 day (1/5 default)
}

View File

@ -62,6 +62,13 @@ func TestDefaultsKubeProxyConfiguration(t *testing.T) {
IPVS: kubeproxyconfigv1alpha1.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 30 * time.Second},
},
NFTables: kubeproxyconfigv1alpha1.KubeProxyNFTablesConfiguration{
MasqueradeBit: ptr.To[int32](14),
MasqueradeAll: false,
LocalhostNodePorts: ptr.To(true),
SyncPeriod: metav1.Duration{Duration: 30 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
},
OOMScoreAdj: &oomScore,
Conntrack: kubeproxyconfigv1alpha1.KubeProxyConntrackConfiguration{
MaxPerCore: &ctMaxPerCore,
@ -102,6 +109,13 @@ func TestDefaultsKubeProxyConfiguration(t *testing.T) {
IPVS: kubeproxyconfigv1alpha1.KubeProxyIPVSConfiguration{
SyncPeriod: metav1.Duration{Duration: 30 * time.Second},
},
NFTables: kubeproxyconfigv1alpha1.KubeProxyNFTablesConfiguration{
MasqueradeBit: ptr.To[int32](14),
MasqueradeAll: false,
LocalhostNodePorts: ptr.To(true),
SyncPeriod: metav1.Duration{Duration: 30 * time.Second},
MinSyncPeriod: metav1.Duration{Duration: 1 * time.Second},
},
OOMScoreAdj: &oomScore,
Conntrack: kubeproxyconfigv1alpha1.KubeProxyConntrackConfiguration{
MaxPerCore: &ctMaxPerCore,

View File

@ -89,6 +89,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*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)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*config.KubeProxyNFTablesConfiguration)(nil), (*v1alpha1.KubeProxyNFTablesConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(a.(*config.KubeProxyNFTablesConfiguration), b.(*v1alpha1.KubeProxyNFTablesConfiguration), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*v1alpha1.KubeProxyWinkernelConfiguration)(nil), (*config.KubeProxyWinkernelConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_KubeProxyWinkernelConfiguration_To_config_KubeProxyWinkernelConfiguration(a.(*v1alpha1.KubeProxyWinkernelConfiguration), b.(*config.KubeProxyWinkernelConfiguration), scope)
}); err != nil {
@ -144,6 +154,9 @@ func autoConvert_v1alpha1_KubeProxyConfiguration_To_config_KubeProxyConfiguratio
if err := Convert_v1alpha1_KubeProxyIPVSConfiguration_To_config_KubeProxyIPVSConfiguration(&in.IPVS, &out.IPVS, s); err != nil {
return err
}
if err := Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(&in.NFTables, &out.NFTables, s); err != nil {
return err
}
if err := Convert_v1alpha1_KubeProxyWinkernelConfiguration_To_config_KubeProxyWinkernelConfiguration(&in.Winkernel, &out.Winkernel, s); err != nil {
return err
}
@ -190,6 +203,9 @@ func autoConvert_config_KubeProxyConfiguration_To_v1alpha1_KubeProxyConfiguratio
if err := Convert_config_KubeProxyWinkernelConfiguration_To_v1alpha1_KubeProxyWinkernelConfiguration(&in.Winkernel, &out.Winkernel, s); err != nil {
return err
}
if err := Convert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(&in.NFTables, &out.NFTables, s); err != nil {
return err
}
out.DetectLocalMode = v1alpha1.LocalMode(in.DetectLocalMode)
if err := Convert_config_DetectLocalConfiguration_To_v1alpha1_DetectLocalConfiguration(&in.DetectLocal, &out.DetectLocal, s); err != nil {
return err
@ -304,6 +320,34 @@ func Convert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfigur
return autoConvert_config_KubeProxyIPVSConfiguration_To_v1alpha1_KubeProxyIPVSConfiguration(in, out, s)
}
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.MasqueradeAll = in.MasqueradeAll
out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts))
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return nil
}
// Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration is an autogenerated conversion function.
func Convert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in *v1alpha1.KubeProxyNFTablesConfiguration, out *config.KubeProxyNFTablesConfiguration, s conversion.Scope) error {
return autoConvert_v1alpha1_KubeProxyNFTablesConfiguration_To_config_KubeProxyNFTablesConfiguration(in, out, s)
}
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.MasqueradeAll = in.MasqueradeAll
out.LocalhostNodePorts = (*bool)(unsafe.Pointer(in.LocalhostNodePorts))
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return nil
}
// Convert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration is an autogenerated conversion function.
func Convert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(in *config.KubeProxyNFTablesConfiguration, out *v1alpha1.KubeProxyNFTablesConfiguration, s conversion.Scope) error {
return autoConvert_config_KubeProxyNFTablesConfiguration_To_v1alpha1_KubeProxyNFTablesConfiguration(in, out, s)
}
func autoConvert_v1alpha1_KubeProxyWinkernelConfiguration_To_config_KubeProxyWinkernelConfiguration(in *v1alpha1.KubeProxyWinkernelConfiguration, out *config.KubeProxyWinkernelConfiguration, s conversion.Scope) error {
out.NetworkName = in.NetworkName
out.SourceVip = in.SourceVip

View File

@ -31,6 +31,7 @@ import (
logsapi "k8s.io/component-base/logs/api/v1"
"k8s.io/component-base/metrics"
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/features"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
netutils "k8s.io/utils/net"
)
@ -47,8 +48,11 @@ func Validate(config *kubeproxyconfig.KubeProxyConfiguration) field.ErrorList {
}
allErrs = append(allErrs, validateKubeProxyIPTablesConfiguration(config.IPTables, newPath.Child("KubeProxyIPTablesConfiguration"))...)
if config.Mode == kubeproxyconfig.ProxyModeIPVS {
switch config.Mode {
case kubeproxyconfig.ProxyModeIPVS:
allErrs = append(allErrs, validateKubeProxyIPVSConfiguration(config.IPVS, newPath.Child("KubeProxyIPVSConfiguration"))...)
case kubeproxyconfig.ProxyModeNFTables:
allErrs = append(allErrs, validateKubeProxyNFTablesConfiguration(config.NFTables, newPath.Child("KubeProxyNFTablesConfiguration"))...)
}
allErrs = append(allErrs, validateKubeProxyConntrackConfiguration(config.Conntrack, newPath.Child("KubeProxyConntrackConfiguration"))...)
allErrs = append(allErrs, validateProxyMode(config.Mode, newPath.Child("Mode"))...)
@ -152,6 +156,28 @@ func validateKubeProxyIPVSConfiguration(config kubeproxyconfig.KubeProxyIPVSConf
return allErrs
}
func validateKubeProxyNFTablesConfiguration(config kubeproxyconfig.KubeProxyNFTablesConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
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]"))
}
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
}
func validateKubeProxyConntrackConfiguration(config kubeproxyconfig.KubeProxyConntrackConfiguration, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
@ -198,6 +224,10 @@ func validateProxyModeLinux(mode kubeproxyconfig.ProxyMode, fldPath *field.Path)
string(kubeproxyconfig.ProxyModeIPVS),
)
if utilfeature.DefaultFeatureGate.Enabled(features.NFTablesProxyMode) {
validModes.Insert(string(kubeproxyconfig.ProxyModeNFTables))
}
if mode == "" || validModes.Has(string(mode)) {
return nil
}

View File

@ -80,6 +80,7 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
in.IPTables.DeepCopyInto(&out.IPTables)
in.IPVS.DeepCopyInto(&out.IPVS)
out.Winkernel = in.Winkernel
in.NFTables.DeepCopyInto(&out.NFTables)
out.DetectLocal = in.DetectLocal
if in.NodePortAddresses != nil {
in, out := &in.NodePortAddresses, &out.NodePortAddresses
@ -206,6 +207,34 @@ func (in *KubeProxyIPVSConfiguration) DeepCopy() *KubeProxyIPVSConfiguration {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyNFTablesConfiguration) DeepCopyInto(out *KubeProxyNFTablesConfiguration) {
*out = *in
if in.MasqueradeBit != nil {
in, out := &in.MasqueradeBit, &out.MasqueradeBit
*out = new(int32)
**out = **in
}
if in.LocalhostNodePorts != nil {
in, out := &in.LocalhostNodePorts, &out.LocalhostNodePorts
*out = new(bool)
**out = **in
}
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProxyNFTablesConfiguration.
func (in *KubeProxyNFTablesConfiguration) DeepCopy() *KubeProxyNFTablesConfiguration {
if in == nil {
return nil
}
out := new(KubeProxyNFTablesConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyWinkernelConfiguration) DeepCopyInto(out *KubeProxyWinkernelConfiguration) {
*out = *in

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -77,6 +77,28 @@ type KubeProxyIPVSConfiguration struct {
UDPTimeout metav1.Duration `json:"udpTimeout"`
}
// KubeProxyNFTablesConfiguration contains nftables-related configuration
// details for the Kubernetes proxy server.
type KubeProxyNFTablesConfiguration struct {
// 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].
MasqueradeBit *int32 `json:"masqueradeBit"`
// masqueradeAll tells kube-proxy to SNAT all traffic sent to Service cluster IPs,
// when using the nftables mode. This may be required with some CNI plugins.
MasqueradeAll bool `json:"masqueradeAll"`
// localhostNodePorts, if false, tells kube-proxy to disable the legacy behavior
// of allowing NodePort services to be accessed via localhost. FIXME: remove.
LocalhostNodePorts *bool `json:"localhostNodePorts"`
// 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 `json:"syncPeriod"`
// 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 `json:"minSyncPeriod"`
}
// KubeProxyConntrackConfiguration contains conntrack settings for
// the Kubernetes proxy server.
type KubeProxyConntrackConfiguration struct {
@ -189,6 +211,8 @@ type KubeProxyConfiguration struct {
IPTables KubeProxyIPTablesConfiguration `json:"iptables"`
// ipvs contains ipvs-related configuration options.
IPVS KubeProxyIPVSConfiguration `json:"ipvs"`
// nftables contains nftables-related configuration options.
NFTables KubeProxyNFTablesConfiguration `json:"nftables"`
// winkernel contains winkernel-related configuration options.
Winkernel KubeProxyWinkernelConfiguration `json:"winkernel"`

View File

@ -57,6 +57,7 @@ func (in *KubeProxyConfiguration) DeepCopyInto(out *KubeProxyConfiguration) {
in.Logging.DeepCopyInto(&out.Logging)
in.IPTables.DeepCopyInto(&out.IPTables)
in.IPVS.DeepCopyInto(&out.IPVS)
in.NFTables.DeepCopyInto(&out.NFTables)
out.Winkernel = in.Winkernel
out.DetectLocal = in.DetectLocal
if in.NodePortAddresses != nil {
@ -184,6 +185,34 @@ func (in *KubeProxyIPVSConfiguration) DeepCopy() *KubeProxyIPVSConfiguration {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyNFTablesConfiguration) DeepCopyInto(out *KubeProxyNFTablesConfiguration) {
*out = *in
if in.MasqueradeBit != nil {
in, out := &in.MasqueradeBit, &out.MasqueradeBit
*out = new(int32)
**out = **in
}
if in.LocalhostNodePorts != nil {
in, out := &in.LocalhostNodePorts, &out.LocalhostNodePorts
*out = new(bool)
**out = **in
}
out.SyncPeriod = in.SyncPeriod
out.MinSyncPeriod = in.MinSyncPeriod
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeProxyNFTablesConfiguration.
func (in *KubeProxyNFTablesConfiguration) DeepCopy() *KubeProxyNFTablesConfiguration {
if in == nil {
return nil
}
out := new(KubeProxyNFTablesConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeProxyWinkernelConfiguration) DeepCopyInto(out *KubeProxyWinkernelConfiguration) {
*out = *in