Merge pull request #139397 from adrianmoisey/ipvs-feature-gate

KEP-5495: Add featuregate for IPVS
This commit is contained in:
Kubernetes Prow Robot 2026-06-04 17:47:48 +05:30 committed by GitHub
commit 9fa4c1cfa3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 64 additions and 5 deletions

View file

@ -182,7 +182,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *kubeproxyconfig
ipts := utiliptables.NewBestEffort()
logger.Info("Using ipvs Proxier")
message := "The ipvs proxier is now deprecated and may be removed in a future release. Please use 'nftables' instead."
message := "The ipvs proxier has been deprecated and will be disabled by default in Kubernetes 1.40 and removed in Kubernetes 1.43. Migrate to the 'nftables' proxier instead."
logger.Error(nil, message)
s.Recorder.Eventf(s.NodeRef, nil, v1.EventTypeWarning, "IPVSDeprecation", "StartKubeProxy", message)
if dualStack {

View file

@ -470,6 +470,12 @@ const (
// Allows to delegate reconciliation of a Job object to an external controller.
JobManagedBy featuregate.Feature = "JobManagedBy"
// owner: @adrianmoisey @danwinship
// kep: https://kep.k8s.io/5495
//
// Allow use of IPVS mode in kube-proxy
KubeProxyIPVS featuregate.Feature = "KubeProxyIPVS"
// owner: @marquiz
// kep: http://kep.k8s.io/4033
//
@ -1494,6 +1500,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.35"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.38
},
KubeProxyIPVS: {
{Version: version.MustParse("1.11"), Default: true, PreRelease: featuregate.GA},
},
KubeletCgroupDriverFromCRI: {
{Version: version.MustParse("1.28"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.31"), Default: true, PreRelease: featuregate.Beta},
@ -2362,6 +2372,8 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature
JobManagedBy: {},
KubeProxyIPVS: {},
KubeletCgroupDriverFromCRI: {},
KubeletCrashLoopBackOffMax: {},

View file

@ -30,6 +30,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"
)
@ -171,10 +172,13 @@ func validateProxyMode(mode kubeproxyconfig.ProxyMode, fldPath *field.Path) fiel
func validateProxyModeLinux(mode kubeproxyconfig.ProxyMode, fldPath *field.Path) field.ErrorList {
validModes := sets.New[string](
string(kubeproxyconfig.ProxyModeIPTables),
string(kubeproxyconfig.ProxyModeIPVS),
string(kubeproxyconfig.ProxyModeNFTables),
)
if utilfeature.DefaultFeatureGate.Enabled(features.KubeProxyIPVS) {
validModes.Insert(string(kubeproxyconfig.ProxyModeIPVS))
}
if mode == "" || validModes.Has(string(mode)) {
return nil
}

View file

@ -27,8 +27,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature"
componentbaseconfig "k8s.io/component-base/config"
featuregatetesting "k8s.io/component-base/featuregate/testing"
logsapi "k8s.io/component-base/logs/api/v1"
"k8s.io/kubernetes/pkg/features"
kubeproxyconfig "k8s.io/kubernetes/pkg/proxy/apis/config"
"k8s.io/utils/ptr"
)
@ -429,8 +432,9 @@ func TestValidateProxyMode(t *testing.T) {
func testValidateProxyModeLinux(t *testing.T) {
newPath := field.NewPath("KubeProxyConfiguration")
for name, testCase := range map[string]struct {
mode kubeproxyconfig.ProxyMode
expectedErrs field.ErrorList
mode kubeproxyconfig.ProxyMode
expectedErrs field.ErrorList
enableKubeProxyIPVS *bool
}{
"blank mode should default": {
mode: kubeproxyconfig.ProxyMode(""),
@ -438,12 +442,38 @@ func testValidateProxyModeLinux(t *testing.T) {
"iptables is allowed": {
mode: kubeproxyconfig.ProxyModeIPTables,
},
"ipvs is allowed": {
"iptables is allowed - with KubeProxyIPVS feature gate enabled": {
mode: kubeproxyconfig.ProxyModeIPTables,
enableKubeProxyIPVS: new(true),
},
"iptables is allowed - with KubeProxyIPVS feature gate disabled": {
mode: kubeproxyconfig.ProxyModeIPTables,
enableKubeProxyIPVS: new(false),
},
"ipvs is allowed - with KubeProxyIPVS feature gate in default state": {
mode: kubeproxyconfig.ProxyModeIPVS,
},
"ipvs is allowed - with KubeProxyIPVS feature gate enabled": {
mode: kubeproxyconfig.ProxyModeIPVS,
enableKubeProxyIPVS: new(true),
},
"ipvs is not allowed - with KubeProxyIPVS feature gate disabled": {
mode: kubeproxyconfig.ProxyModeIPVS,
enableKubeProxyIPVS: new(false),
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ProxyMode"), "ipvs", "must be iptables, nftables or blank (blank means the best-available proxy [currently iptables])")},
},
"nftables is allowed": {
mode: kubeproxyconfig.ProxyModeNFTables,
},
"nftables is allowed - with KubeProxyIPVS feature gate enabled": {
mode: kubeproxyconfig.ProxyModeNFTables,
enableKubeProxyIPVS: new(true),
},
"nftables is allowed - with KubeProxyIPVS feature gate disabled": {
mode: kubeproxyconfig.ProxyModeNFTables,
enableKubeProxyIPVS: new(false),
},
"winkernel is not allowed": {
mode: kubeproxyconfig.ProxyModeKernelspace,
expectedErrs: field.ErrorList{field.Invalid(newPath.Child("ProxyMode"), "kernelspace", "must be iptables, ipvs, nftables or blank (blank means the best-available proxy [currently iptables])")},
@ -454,6 +484,12 @@ func testValidateProxyModeLinux(t *testing.T) {
},
} {
t.Run(name, func(t *testing.T) {
if testCase.enableKubeProxyIPVS != nil {
featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{
features.KubeProxyIPVS: *testCase.enableKubeProxyIPVS,
})
}
errs := validateProxyMode(testCase.mode, newPath)
assert.Equal(t, testCase.expectedErrs, errs, "did not get expected validation errors")
})

View file

@ -99,6 +99,7 @@
| InformerResourceVersion | :ballot_box_with_check: 1.35+ | | 1.301.34 | | 1.35 | | | [code](https://cs.k8s.io/?q=%5CbInformerResourceVersion%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbInformerResourceVersion%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| JobManagedBy | :ballot_box_with_check: 1.32+ | :closed_lock_with_key: 1.35+ | 1.301.31 | 1.321.34 | 1.35 | | | [code](https://cs.k8s.io/?q=%5CbJobManagedBy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbJobManagedBy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| KMSv1 | :ballot_box_with_check: 1.0+ | | | | 1.01.27 | 1.28 | | [code](https://cs.k8s.io/?q=%5CbKMSv1%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbKMSv1%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| KubeProxyIPVS | :ballot_box_with_check: 1.11+ | | | | 1.11 | | | [code](https://cs.k8s.io/?q=%5CbKubeProxyIPVS%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbKubeProxyIPVS%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| KubeletCgroupDriverFromCRI | :ballot_box_with_check: 1.31+ | :closed_lock_with_key: 1.34+ | 1.281.30 | 1.311.33 | 1.34 | | | [code](https://cs.k8s.io/?q=%5CbKubeletCgroupDriverFromCRI%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbKubeletCgroupDriverFromCRI%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| KubeletCrashLoopBackOffMax | :ballot_box_with_check: 1.35+ | | 1.321.34 | 1.35 | | | | [code](https://cs.k8s.io/?q=%5CbKubeletCrashLoopBackOffMax%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbKubeletCrashLoopBackOffMax%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| KubeletEnsureSecretPulledImages | :ballot_box_with_check: 1.35+ | | 1.331.34 | 1.35 | | | | [code](https://cs.k8s.io/?q=%5CbKubeletEnsureSecretPulledImages%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbKubeletEnsureSecretPulledImages%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |

View file

@ -987,6 +987,12 @@
lockToDefault: true
preRelease: GA
version: "1.34"
- name: KubeProxyIPVS
versionedSpecs:
- default: true
lockToDefault: false
preRelease: GA
version: "1.11"
- name: ListFromCacheSnapshot
versionedSpecs:
- default: false