mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 00:07:50 +00:00
Promote ServiceInternalTrafficPolicy to GA
This commit is contained in:
parent
c98aef484d
commit
29f4862ed8
@ -3945,7 +3945,6 @@ type ServiceSpec struct {
|
|||||||
// dropping the traffic if there are no local endpoints. The default value,
|
// dropping the traffic if there are no local endpoints. The default value,
|
||||||
// "Cluster", uses the standard behavior of routing to all endpoints evenly
|
// "Cluster", uses the standard behavior of routing to all endpoints evenly
|
||||||
// (possibly modified by topology and other features).
|
// (possibly modified by topology and other features).
|
||||||
// +featureGate=ServiceInternalTrafficPolicy
|
|
||||||
// +optional
|
// +optional
|
||||||
InternalTrafficPolicy *ServiceInternalTrafficPolicyType
|
InternalTrafficPolicy *ServiceInternalTrafficPolicyType
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ import (
|
|||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/util/parsers"
|
"k8s.io/kubernetes/pkg/util/parsers"
|
||||||
"k8s.io/utils/pointer"
|
"k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
@ -130,14 +128,11 @@ func SetDefaults_Service(obj *v1.Service) {
|
|||||||
obj.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeCluster
|
obj.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeCluster
|
||||||
}
|
}
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
|
if obj.Spec.InternalTrafficPolicy == nil {
|
||||||
if obj.Spec.InternalTrafficPolicy == nil {
|
if obj.Spec.Type == v1.ServiceTypeNodePort || obj.Spec.Type == v1.ServiceTypeLoadBalancer || obj.Spec.Type == v1.ServiceTypeClusterIP {
|
||||||
if obj.Spec.Type == v1.ServiceTypeNodePort || obj.Spec.Type == v1.ServiceTypeLoadBalancer || obj.Spec.Type == v1.ServiceTypeClusterIP {
|
serviceInternalTrafficPolicyCluster := v1.ServiceInternalTrafficPolicyCluster
|
||||||
serviceInternalTrafficPolicyCluster := v1.ServiceInternalTrafficPolicyCluster
|
obj.Spec.InternalTrafficPolicy = &serviceInternalTrafficPolicyCluster
|
||||||
obj.Spec.InternalTrafficPolicy = &serviceInternalTrafficPolicyCluster
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj.Spec.Type == v1.ServiceTypeLoadBalancer {
|
if obj.Spec.Type == v1.ServiceTypeLoadBalancer {
|
||||||
|
@ -33,7 +33,6 @@ import (
|
|||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
utilpointer "k8s.io/utils/pointer"
|
utilpointer "k8s.io/utils/pointer"
|
||||||
|
|
||||||
// ensure types are installed
|
// ensure types are installed
|
||||||
@ -1862,13 +1861,11 @@ func TestSetDefaultServiceInternalTrafficPolicy(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
expectedInternalTrafficPolicy *v1.ServiceInternalTrafficPolicyType
|
expectedInternalTrafficPolicy *v1.ServiceInternalTrafficPolicyType
|
||||||
svc v1.Service
|
svc v1.Service
|
||||||
featureGateOn bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "must set default internalTrafficPolicy",
|
name: "must set default internalTrafficPolicy",
|
||||||
expectedInternalTrafficPolicy: &cluster,
|
expectedInternalTrafficPolicy: &cluster,
|
||||||
svc: v1.Service{},
|
svc: v1.Service{},
|
||||||
featureGateOn: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "must not set default internalTrafficPolicy when it's cluster",
|
name: "must not set default internalTrafficPolicy when it's cluster",
|
||||||
@ -1878,7 +1875,6 @@ func TestSetDefaultServiceInternalTrafficPolicy(t *testing.T) {
|
|||||||
InternalTrafficPolicy: &cluster,
|
InternalTrafficPolicy: &cluster,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureGateOn: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "must not set default internalTrafficPolicy when type is ExternalName",
|
name: "must not set default internalTrafficPolicy when type is ExternalName",
|
||||||
@ -1888,7 +1884,6 @@ func TestSetDefaultServiceInternalTrafficPolicy(t *testing.T) {
|
|||||||
Type: v1.ServiceTypeExternalName,
|
Type: v1.ServiceTypeExternalName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureGateOn: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "must not set default internalTrafficPolicy when it's local",
|
name: "must not set default internalTrafficPolicy when it's local",
|
||||||
@ -1898,18 +1893,10 @@ func TestSetDefaultServiceInternalTrafficPolicy(t *testing.T) {
|
|||||||
InternalTrafficPolicy: &local,
|
InternalTrafficPolicy: &local,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureGateOn: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "must not set default internalTrafficPolicy when gate is disabled",
|
|
||||||
expectedInternalTrafficPolicy: nil,
|
|
||||||
svc: v1.Service{},
|
|
||||||
featureGateOn: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, test.featureGateOn)()
|
|
||||||
obj := roundTrip(t, runtime.Object(&test.svc))
|
obj := roundTrip(t, runtime.Object(&test.svc))
|
||||||
svc := obj.(*v1.Service)
|
svc := obj.(*v1.Service)
|
||||||
|
|
||||||
|
@ -4876,14 +4876,12 @@ func validateServiceExternalTrafficFieldsUpdate(before, after *core.Service) fie
|
|||||||
func validateServiceInternalTrafficFieldsValue(service *core.Service) field.ErrorList {
|
func validateServiceInternalTrafficFieldsValue(service *core.Service) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
|
if service.Spec.InternalTrafficPolicy == nil {
|
||||||
if service.Spec.InternalTrafficPolicy == nil {
|
// We do not forbid internalTrafficPolicy on other Service types because of historical reasons.
|
||||||
// We do not forbid internalTrafficPolicy on other Service types because of historical reasons.
|
// We did not check that before it went beta and we don't want to invalidate existing stored objects.
|
||||||
// We did not check that before it went beta and we don't want to invalidate existing stored objects.
|
if service.Spec.Type == core.ServiceTypeNodePort ||
|
||||||
if service.Spec.Type == core.ServiceTypeNodePort ||
|
service.Spec.Type == core.ServiceTypeLoadBalancer || service.Spec.Type == core.ServiceTypeClusterIP {
|
||||||
service.Spec.Type == core.ServiceTypeLoadBalancer || service.Spec.Type == core.ServiceTypeClusterIP {
|
allErrs = append(allErrs, field.Required(field.NewPath("spec").Child("internalTrafficPolicy"), ""))
|
||||||
allErrs = append(allErrs, field.Required(field.NewPath("spec").Child("internalTrafficPolicy"), ""))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13335,8 +13335,7 @@ func TestValidateServiceCreate(t *testing.T) {
|
|||||||
tweakSvc: func(s *core.Service) {
|
tweakSvc: func(s *core.Service) {
|
||||||
s.Spec.InternalTrafficPolicy = nil
|
s.Spec.InternalTrafficPolicy = nil
|
||||||
},
|
},
|
||||||
featureGates: []featuregate.Feature{features.ServiceInternalTrafficPolicy},
|
numErrs: 1,
|
||||||
numErrs: 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "internalTrafficPolicy field nil when type is ExternalName",
|
name: "internalTrafficPolicy field nil when type is ExternalName",
|
||||||
@ -13345,8 +13344,7 @@ func TestValidateServiceCreate(t *testing.T) {
|
|||||||
s.Spec.Type = core.ServiceTypeExternalName
|
s.Spec.Type = core.ServiceTypeExternalName
|
||||||
s.Spec.ExternalName = "foo.bar.com"
|
s.Spec.ExternalName = "foo.bar.com"
|
||||||
},
|
},
|
||||||
featureGates: []featuregate.Feature{features.ServiceInternalTrafficPolicy},
|
numErrs: 0,
|
||||||
numErrs: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Typically this should fail validation, but in v1.22 we have existing clusters
|
// Typically this should fail validation, but in v1.22 we have existing clusters
|
||||||
@ -13360,8 +13358,7 @@ func TestValidateServiceCreate(t *testing.T) {
|
|||||||
s.Spec.Type = core.ServiceTypeExternalName
|
s.Spec.Type = core.ServiceTypeExternalName
|
||||||
s.Spec.ExternalName = "foo.bar.com"
|
s.Spec.ExternalName = "foo.bar.com"
|
||||||
},
|
},
|
||||||
featureGates: []featuregate.Feature{features.ServiceInternalTrafficPolicy},
|
numErrs: 0,
|
||||||
numErrs: 0,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid internalTraffic field",
|
name: "invalid internalTraffic field",
|
||||||
|
@ -719,6 +719,7 @@ const (
|
|||||||
// kep: https://kep.k8s.io/2086
|
// kep: https://kep.k8s.io/2086
|
||||||
// alpha: v1.21
|
// alpha: v1.21
|
||||||
// beta: v1.22
|
// beta: v1.22
|
||||||
|
// GA: v1.26
|
||||||
//
|
//
|
||||||
// Enables node-local routing for Service internal traffic
|
// Enables node-local routing for Service internal traffic
|
||||||
ServiceInternalTrafficPolicy featuregate.Feature = "ServiceInternalTrafficPolicy"
|
ServiceInternalTrafficPolicy featuregate.Feature = "ServiceInternalTrafficPolicy"
|
||||||
@ -1016,7 +1017,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
|
|
||||||
ServiceIPStaticSubrange: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
ServiceIPStaticSubrange: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||||
|
|
||||||
ServiceInternalTrafficPolicy: {Default: true, PreRelease: featuregate.Beta},
|
ServiceInternalTrafficPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.28
|
||||||
|
|
||||||
SizeMemoryBackedVolumes: {Default: true, PreRelease: featuregate.Beta},
|
SizeMemoryBackedVolumes: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
|
||||||
|
@ -5275,34 +5275,10 @@ func TestInternalTrafficPolicyE2E(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Local internalTrafficPolicy is ignored when feature gate is off",
|
|
||||||
line: getLine(),
|
|
||||||
internalTrafficPolicy: &local,
|
|
||||||
featureGateOn: false,
|
|
||||||
endpoints: []endpoint{
|
|
||||||
{"10.0.1.1", testHostname},
|
|
||||||
{"10.0.1.2", "host1"},
|
|
||||||
{"10.0.1.3", "host2"},
|
|
||||||
},
|
|
||||||
expectEndpointRule: false,
|
|
||||||
expectedIPTablesWithSlice: clusterExpectedIPTables,
|
|
||||||
flowTests: []packetFlowTest{
|
|
||||||
{
|
|
||||||
name: "pod to ClusterIP hits all endpoints",
|
|
||||||
sourceIP: "10.0.0.2",
|
|
||||||
destIP: "172.30.1.1",
|
|
||||||
destPort: 80,
|
|
||||||
output: "10.0.1.1:80, 10.0.1.2:80, 10.0.1.3:80",
|
|
||||||
masq: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, tc.featureGateOn)()
|
|
||||||
ipt := iptablestest.NewFake()
|
ipt := iptablestest.NewFake()
|
||||||
fp := NewFakeProxier(ipt)
|
fp := NewFakeProxier(ipt)
|
||||||
fp.OnServiceSynced()
|
fp.OnServiceSynced()
|
||||||
@ -7434,8 +7410,6 @@ func TestInternalExternalMasquerade(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, true)()
|
|
||||||
|
|
||||||
ipt := iptablestest.NewFake()
|
ipt := iptablestest.NewFake()
|
||||||
fp := NewFakeProxier(ipt)
|
fp := NewFakeProxier(ipt)
|
||||||
fp.masqueradeAll = tc.masqueradeAll
|
fp.masqueradeAll = tc.masqueradeAll
|
||||||
@ -8274,7 +8248,6 @@ func TestNoEndpointsMetric(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, true)()
|
|
||||||
ipt := iptablestest.NewFake()
|
ipt := iptablestest.NewFake()
|
||||||
fp := NewFakeProxier(ipt)
|
fp := NewFakeProxier(ipt)
|
||||||
fp.OnServiceSynced()
|
fp.OnServiceSynced()
|
||||||
|
@ -42,10 +42,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/version"
|
"k8s.io/apimachinery/pkg/util/version"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/client-go/tools/events"
|
"k8s.io/client-go/tools/events"
|
||||||
utilsysctl "k8s.io/component-helpers/node/util/sysctl"
|
utilsysctl "k8s.io/component-helpers/node/util/sysctl"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/proxy"
|
"k8s.io/kubernetes/pkg/proxy"
|
||||||
"k8s.io/kubernetes/pkg/proxy/healthcheck"
|
"k8s.io/kubernetes/pkg/proxy/healthcheck"
|
||||||
"k8s.io/kubernetes/pkg/proxy/metaproxier"
|
"k8s.io/kubernetes/pkg/proxy/metaproxier"
|
||||||
@ -1239,7 +1237,7 @@ func (proxier *Proxier) syncProxyRules() {
|
|||||||
// ExternalTrafficPolicy only works for NodePort and external LB traffic, does not affect ClusterIP
|
// ExternalTrafficPolicy only works for NodePort and external LB traffic, does not affect ClusterIP
|
||||||
// So we still need clusterIP rules in onlyNodeLocalEndpoints mode.
|
// So we still need clusterIP rules in onlyNodeLocalEndpoints mode.
|
||||||
internalNodeLocal := false
|
internalNodeLocal := false
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) && svcInfo.InternalPolicyLocal() {
|
if svcInfo.InternalPolicyLocal() {
|
||||||
internalNodeLocal = true
|
internalNodeLocal = true
|
||||||
}
|
}
|
||||||
if err := proxier.syncEndpoint(svcPortName, internalNodeLocal, serv); err != nil {
|
if err := proxier.syncEndpoint(svcPortName, internalNodeLocal, serv); err != nil {
|
||||||
@ -2018,7 +2016,7 @@ func (proxier *Proxier) syncEndpoint(svcPortName proxy.ServicePortName, onlyNode
|
|||||||
// will have the POD address and will be discarded.
|
// will have the POD address and will be discarded.
|
||||||
endpoints = clusterEndpoints
|
endpoints = clusterEndpoints
|
||||||
|
|
||||||
if hasAnyEndpoints && svcInfo.InternalPolicyLocal() && utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
|
if hasAnyEndpoints && svcInfo.InternalPolicyLocal() {
|
||||||
proxier.serviceNoLocalEndpointsInternal.Insert(svcPortName.NamespacedName.String())
|
proxier.serviceNoLocalEndpointsInternal.Insert(svcPortName.NamespacedName.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4876,8 +4876,6 @@ func TestTestInternalTrafficPolicyE2E(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, true)()
|
|
||||||
|
|
||||||
ipt := iptablestest.NewFake()
|
ipt := iptablestest.NewFake()
|
||||||
ipvs := ipvstest.NewFake()
|
ipvs := ipvstest.NewFake()
|
||||||
ipset := ipsettest.NewFake(testIPSetVersion)
|
ipset := ipsettest.NewFake(testIPSetVersion)
|
||||||
@ -6025,8 +6023,6 @@ func TestNoEndpointsMetric(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, true)()
|
|
||||||
|
|
||||||
ipt := iptablestest.NewFake()
|
ipt := iptablestest.NewFake()
|
||||||
ipvs := ipvstest.NewFake()
|
ipvs := ipvstest.NewFake()
|
||||||
ipset := ipsettest.NewFake(testIPSetVersion)
|
ipset := ipsettest.NewFake(testIPSetVersion)
|
||||||
|
@ -30,9 +30,7 @@ import (
|
|||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
apiservice "k8s.io/kubernetes/pkg/api/v1/service"
|
apiservice "k8s.io/kubernetes/pkg/api/v1/service"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/proxy/metrics"
|
"k8s.io/kubernetes/pkg/proxy/metrics"
|
||||||
utilproxy "k8s.io/kubernetes/pkg/proxy/util"
|
utilproxy "k8s.io/kubernetes/pkg/proxy/util"
|
||||||
)
|
)
|
||||||
@ -158,14 +156,9 @@ func (bsvcPortInfo *BaseServicePortInfo) UsesLocalEndpoints() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (sct *ServiceChangeTracker) newBaseServiceInfo(port *v1.ServicePort, service *v1.Service) *BaseServicePortInfo {
|
func (sct *ServiceChangeTracker) newBaseServiceInfo(port *v1.ServicePort, service *v1.Service) *BaseServicePortInfo {
|
||||||
externalPolicyLocal := false
|
externalPolicyLocal := apiservice.ExternalPolicyLocal(service)
|
||||||
if apiservice.ExternalPolicyLocal(service) {
|
internalPolicyLocal := apiservice.InternalPolicyLocal(service)
|
||||||
externalPolicyLocal = true
|
|
||||||
}
|
|
||||||
internalPolicyLocal := false
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
|
|
||||||
internalPolicyLocal = apiservice.InternalPolicyLocal(service)
|
|
||||||
}
|
|
||||||
var stickyMaxAgeSeconds int
|
var stickyMaxAgeSeconds int
|
||||||
if service.Spec.SessionAffinity == v1.ServiceAffinityClientIP {
|
if service.Spec.SessionAffinity == v1.ServiceAffinityClientIP {
|
||||||
// Kube-apiserver side guarantees SessionAffinityConfig won't be nil when session affinity type is ClientIP
|
// Kube-apiserver side guarantees SessionAffinityConfig won't be nil when session affinity type is ClientIP
|
||||||
|
@ -24,11 +24,9 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/apiserver/pkg/storage/names"
|
"k8s.io/apiserver/pkg/storage/names"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -117,19 +115,6 @@ func (svcStrategy) AllowUnconditionalUpdate() bool {
|
|||||||
// }
|
// }
|
||||||
func dropServiceDisabledFields(newSvc *api.Service, oldSvc *api.Service) {
|
func dropServiceDisabledFields(newSvc *api.Service, oldSvc *api.Service) {
|
||||||
|
|
||||||
// Clear InternalTrafficPolicy if not enabled
|
|
||||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ServiceInternalTrafficPolicy) {
|
|
||||||
if !serviceInternalTrafficPolicyInUse(oldSvc) {
|
|
||||||
newSvc.Spec.InternalTrafficPolicy = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceInternalTrafficPolicyInUse(svc *api.Service) bool {
|
|
||||||
if svc == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return svc.Spec.InternalTrafficPolicy != nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type serviceStatusStrategy struct {
|
type serviceStatusStrategy struct {
|
||||||
|
@ -26,11 +26,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
utilpointer "k8s.io/utils/pointer"
|
utilpointer "k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -153,23 +150,12 @@ func makeServiceWithPorts(ports []api.PortStatus) *api.Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeServiceWithInternalTrafficPolicy(policy *api.ServiceInternalTrafficPolicyType) *api.Service {
|
|
||||||
return &api.Service{
|
|
||||||
Spec: api.ServiceSpec{
|
|
||||||
InternalTrafficPolicy: policy,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDropDisabledField(t *testing.T) {
|
func TestDropDisabledField(t *testing.T) {
|
||||||
localInternalTrafficPolicy := api.ServiceInternalTrafficPolicyLocal
|
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
enableInternalTrafficPolicy bool
|
svc *api.Service
|
||||||
svc *api.Service
|
oldSvc *api.Service
|
||||||
oldSvc *api.Service
|
compareSvc *api.Service
|
||||||
compareSvc *api.Service
|
|
||||||
}{
|
}{
|
||||||
/* svc.Status.Conditions */
|
/* svc.Status.Conditions */
|
||||||
{
|
{
|
||||||
@ -221,33 +207,10 @@ func TestDropDisabledField(t *testing.T) {
|
|||||||
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
oldSvc: makeServiceWithPorts([]api.PortStatus{}),
|
||||||
compareSvc: makeServiceWithPorts(nil),
|
compareSvc: makeServiceWithPorts(nil),
|
||||||
},
|
},
|
||||||
/* svc.spec.internalTrafficPolicy */
|
|
||||||
{
|
|
||||||
name: "internal traffic policy not enabled, field used in old, not used in new",
|
|
||||||
enableInternalTrafficPolicy: false,
|
|
||||||
svc: makeServiceWithInternalTrafficPolicy(nil),
|
|
||||||
oldSvc: makeServiceWithInternalTrafficPolicy(&localInternalTrafficPolicy),
|
|
||||||
compareSvc: makeServiceWithInternalTrafficPolicy(nil),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "internal traffic policy not enabled, field not used in old, used in new",
|
|
||||||
enableInternalTrafficPolicy: false,
|
|
||||||
svc: makeServiceWithInternalTrafficPolicy(&localInternalTrafficPolicy),
|
|
||||||
oldSvc: makeServiceWithInternalTrafficPolicy(nil),
|
|
||||||
compareSvc: makeServiceWithInternalTrafficPolicy(nil),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "internal traffic policy enabled, field not used in old, used in new",
|
|
||||||
enableInternalTrafficPolicy: true,
|
|
||||||
svc: makeServiceWithInternalTrafficPolicy(&localInternalTrafficPolicy),
|
|
||||||
oldSvc: makeServiceWithInternalTrafficPolicy(nil),
|
|
||||||
compareSvc: makeServiceWithInternalTrafficPolicy(&localInternalTrafficPolicy),
|
|
||||||
},
|
|
||||||
/* add more tests for other dropped fields as needed */
|
/* add more tests for other dropped fields as needed */
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
func() {
|
func() {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceInternalTrafficPolicy, tc.enableInternalTrafficPolicy)()
|
|
||||||
old := tc.oldSvc.DeepCopy()
|
old := tc.oldSvc.DeepCopy()
|
||||||
|
|
||||||
// to test against user using IPFamily not set on cluster
|
// to test against user using IPFamily not set on cluster
|
||||||
|
@ -5212,7 +5212,6 @@ message ServiceSpec {
|
|||||||
// dropping the traffic if there are no local endpoints. The default value,
|
// dropping the traffic if there are no local endpoints. The default value,
|
||||||
// "Cluster", uses the standard behavior of routing to all endpoints evenly
|
// "Cluster", uses the standard behavior of routing to all endpoints evenly
|
||||||
// (possibly modified by topology and other features).
|
// (possibly modified by topology and other features).
|
||||||
// +featureGate=ServiceInternalTrafficPolicy
|
|
||||||
// +optional
|
// +optional
|
||||||
optional string internalTrafficPolicy = 22;
|
optional string internalTrafficPolicy = 22;
|
||||||
}
|
}
|
||||||
|
@ -4591,7 +4591,6 @@ type ServiceSpec struct {
|
|||||||
// dropping the traffic if there are no local endpoints. The default value,
|
// dropping the traffic if there are no local endpoints. The default value,
|
||||||
// "Cluster", uses the standard behavior of routing to all endpoints evenly
|
// "Cluster", uses the standard behavior of routing to all endpoints evenly
|
||||||
// (possibly modified by topology and other features).
|
// (possibly modified by topology and other features).
|
||||||
// +featureGate=ServiceInternalTrafficPolicy
|
|
||||||
// +optional
|
// +optional
|
||||||
InternalTrafficPolicy *ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"`
|
InternalTrafficPolicy *ServiceInternalTrafficPolicyType `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user