remove AggregatedDiscoveryEndpoint that was GAed in v1.30

This commit is contained in:
Paco Xu 2025-03-03 11:01:02 +08:00
parent bb79c29dd5
commit 8195f82fe8
10 changed files with 68 additions and 143 deletions

View File

@ -231,9 +231,7 @@ func BuildGenericConfig(
return return
} }
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AggregatedDiscoveryEndpoint) { genericConfig.AggregatedDiscoveryGroupManager = aggregated.NewResourceManager("apis")
genericConfig.AggregatedDiscoveryGroupManager = aggregated.NewResourceManager("apis")
}
return return
} }

View File

@ -204,12 +204,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
}, },
genericfeatures.AggregatedDiscoveryEndpoint: {
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
},
genericfeatures.AllowParsingUserUIDFromCertAuth: { genericfeatures.AllowParsingUserUIDFromCertAuth: {
{Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta},
}, },

View File

@ -28,8 +28,6 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
) )
type WrappedHandler struct { type WrappedHandler struct {
@ -39,13 +37,11 @@ type WrappedHandler struct {
} }
func (wrapped *WrappedHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { func (wrapped *WrappedHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AggregatedDiscoveryEndpoint) { mediaType, _ := negotiation.NegotiateMediaTypeOptions(req.Header.Get("Accept"), wrapped.s.SupportedMediaTypes(), DiscoveryEndpointRestrictions)
mediaType, _ := negotiation.NegotiateMediaTypeOptions(req.Header.Get("Accept"), wrapped.s.SupportedMediaTypes(), DiscoveryEndpointRestrictions) // mediaType.Convert looks at the request accept headers and is used to control whether the discovery document will be aggregated.
// mediaType.Convert looks at the request accept headers and is used to control whether the discovery document will be aggregated. if IsAggregatedDiscoveryGVK(mediaType.Convert) {
if IsAggregatedDiscoveryGVK(mediaType.Convert) { wrapped.aggHandler.ServeHTTP(resp, req)
wrapped.aggHandler.ServeHTTP(resp, req) return
return
}
} }
wrapped.handler.ServeHTTP(resp, req) wrapped.handler.ServeHTTP(resp, req)
} }

View File

@ -24,9 +24,6 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
) )
const discoveryPath = "/apis" const discoveryPath = "/apis"
@ -60,8 +57,6 @@ func (f fakeHTTPHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request)
} }
func TestAggregationEnabled(t *testing.T) { func TestAggregationEnabled(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AggregatedDiscoveryEndpoint, true)
unaggregated := fakeHTTPHandler{data: "unaggregated"} unaggregated := fakeHTTPHandler{data: "unaggregated"}
aggregated := fakeHTTPHandler{data: "aggregated"} aggregated := fakeHTTPHandler{data: "aggregated"}
wrapped := WrapAggregatedDiscoveryToHandler(unaggregated, aggregated) wrapped := WrapAggregatedDiscoveryToHandler(unaggregated, aggregated)

View File

@ -41,13 +41,6 @@ const (
// Enables usage of MatchConditions fields to use CEL expressions for matching on admission webhooks // Enables usage of MatchConditions fields to use CEL expressions for matching on admission webhooks
AdmissionWebhookMatchConditions featuregate.Feature = "AdmissionWebhookMatchConditions" AdmissionWebhookMatchConditions featuregate.Feature = "AdmissionWebhookMatchConditions"
// owner: @jefftree @alexzielenski
// stable: v1.30
//
// Enables an single HTTP endpoint /discovery/<version> which supports native HTTP
// caching with ETags containing all APIResources known to the apiserver.
AggregatedDiscoveryEndpoint featuregate.Feature = "AggregatedDiscoveryEndpoint"
// owner: @modulitos // owner: @modulitos
// //
// Allow user.DefaultInfo.UID to be set from x509 cert during cert auth. // Allow user.DefaultInfo.UID to be set from x509 cert during cert auth.
@ -266,12 +259,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, {Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
}, },
AggregatedDiscoveryEndpoint: {
{Version: version.MustParse("1.26"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.27"), Default: true, PreRelease: featuregate.Beta},
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
},
AllowParsingUserUIDFromCertAuth: { AllowParsingUserUIDFromCertAuth: {
{Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta}, {Version: version.MustParse("1.33"), Default: true, PreRelease: featuregate.Beta},
}, },

View File

@ -845,14 +845,12 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
muxAndDiscoveryCompleteSignals: map[string]<-chan struct{}{}, muxAndDiscoveryCompleteSignals: map[string]<-chan struct{}{},
} }
if c.FeatureGate.Enabled(genericfeatures.AggregatedDiscoveryEndpoint) { manager := c.AggregatedDiscoveryGroupManager
manager := c.AggregatedDiscoveryGroupManager if manager == nil {
if manager == nil { manager = discoveryendpoint.NewResourceManager("apis")
manager = discoveryendpoint.NewResourceManager("apis")
}
s.AggregatedDiscoveryGroupManager = manager
s.AggregatedLegacyDiscoveryGroupManager = discoveryendpoint.NewResourceManager("api")
} }
s.AggregatedDiscoveryGroupManager = manager
s.AggregatedLegacyDiscoveryGroupManager = discoveryendpoint.NewResourceManager("api")
for { for {
if c.JSONPatchMaxCopyBytes <= 0 { if c.JSONPatchMaxCopyBytes <= 0 {
break break
@ -1111,12 +1109,8 @@ func installAPI(name string, s *GenericAPIServer, c *Config) {
routes.Version{Version: c.EffectiveVersion.BinaryVersion().Info()}.Install(s.Handler.GoRestfulContainer) routes.Version{Version: c.EffectiveVersion.BinaryVersion().Info()}.Install(s.Handler.GoRestfulContainer)
if c.EnableDiscovery { if c.EnableDiscovery {
if c.FeatureGate.Enabled(genericfeatures.AggregatedDiscoveryEndpoint) { wrapped := discoveryendpoint.WrapAggregatedDiscoveryToHandler(s.DiscoveryGroupManager, s.AggregatedDiscoveryGroupManager)
wrapped := discoveryendpoint.WrapAggregatedDiscoveryToHandler(s.DiscoveryGroupManager, s.AggregatedDiscoveryGroupManager) s.Handler.GoRestfulContainer.Add(wrapped.GenerateWebService("/apis", metav1.APIGroupList{}))
s.Handler.GoRestfulContainer.Add(wrapped.GenerateWebService("/apis", metav1.APIGroupList{}))
} else {
s.Handler.GoRestfulContainer.Add(s.DiscoveryGroupManager.WebService())
}
} }
if c.FlowControl != nil { if c.FlowControl != nil {
c.FlowControl.Install(s.Handler.NonGoRestfulMux) c.FlowControl.Install(s.Handler.NonGoRestfulMux)

View File

@ -785,28 +785,26 @@ func (s *GenericAPIServer) installAPIResources(apiPrefix string, apiGroupInfo *A
} }
resourceInfos = append(resourceInfos, r...) resourceInfos = append(resourceInfos, r...)
if s.FeatureGate.Enabled(features.AggregatedDiscoveryEndpoint) { // Aggregated discovery only aggregates resources under /apis
// Aggregated discovery only aggregates resources under /apis if apiPrefix == APIGroupPrefix {
if apiPrefix == APIGroupPrefix { s.AggregatedDiscoveryGroupManager.AddGroupVersion(
s.AggregatedDiscoveryGroupManager.AddGroupVersion( groupVersion.Group,
groupVersion.Group, apidiscoveryv2.APIVersionDiscovery{
apidiscoveryv2.APIVersionDiscovery{ Freshness: apidiscoveryv2.DiscoveryFreshnessCurrent,
Freshness: apidiscoveryv2.DiscoveryFreshnessCurrent, Version: groupVersion.Version,
Version: groupVersion.Version, Resources: discoveryAPIResources,
Resources: discoveryAPIResources, },
}, )
) } else {
} else { // There is only one group version for legacy resources, priority can be defaulted to 0.
// There is only one group version for legacy resources, priority can be defaulted to 0. s.AggregatedLegacyDiscoveryGroupManager.AddGroupVersion(
s.AggregatedLegacyDiscoveryGroupManager.AddGroupVersion( groupVersion.Group,
groupVersion.Group, apidiscoveryv2.APIVersionDiscovery{
apidiscoveryv2.APIVersionDiscovery{ Freshness: apidiscoveryv2.DiscoveryFreshnessCurrent,
Freshness: apidiscoveryv2.DiscoveryFreshnessCurrent, Version: groupVersion.Version,
Version: groupVersion.Version, Resources: discoveryAPIResources,
Resources: discoveryAPIResources, },
}, )
)
}
} }
} }
@ -844,12 +842,8 @@ func (s *GenericAPIServer) InstallLegacyAPIGroup(apiPrefix string, apiGroupInfo
// Install the version handler. // Install the version handler.
// Add a handler at /<apiPrefix> to enumerate the supported api versions. // Add a handler at /<apiPrefix> to enumerate the supported api versions.
legacyRootAPIHandler := discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix) legacyRootAPIHandler := discovery.NewLegacyRootAPIHandler(s.discoveryAddresses, s.Serializer, apiPrefix)
if s.FeatureGate.Enabled(features.AggregatedDiscoveryEndpoint) { wrapped := discoveryendpoint.WrapAggregatedDiscoveryToHandler(legacyRootAPIHandler, s.AggregatedLegacyDiscoveryGroupManager)
wrapped := discoveryendpoint.WrapAggregatedDiscoveryToHandler(legacyRootAPIHandler, s.AggregatedLegacyDiscoveryGroupManager) s.Handler.GoRestfulContainer.Add(wrapped.GenerateWebService("/api", metav1.APIVersions{}))
s.Handler.GoRestfulContainer.Add(wrapped.GenerateWebService("/api", metav1.APIVersions{}))
} else {
s.Handler.GoRestfulContainer.Add(legacyRootAPIHandler.WebService())
}
s.registerStorageReadinessCheck("", apiGroupInfo) s.registerStorageReadinessCheck("", apiGroupInfo)
return nil return nil

View File

@ -275,12 +275,8 @@ func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.Deleg
discoveryGroup: discoveryGroup(enabledVersions), discoveryGroup: discoveryGroup(enabledVersions),
} }
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AggregatedDiscoveryEndpoint) { apisHandlerWithAggregationSupport := aggregated.WrapAggregatedDiscoveryToHandler(apisHandler, s.GenericAPIServer.AggregatedDiscoveryGroupManager)
apisHandlerWithAggregationSupport := aggregated.WrapAggregatedDiscoveryToHandler(apisHandler, s.GenericAPIServer.AggregatedDiscoveryGroupManager) s.GenericAPIServer.Handler.NonGoRestfulMux.Handle("/apis", apisHandlerWithAggregationSupport)
s.GenericAPIServer.Handler.NonGoRestfulMux.Handle("/apis", apisHandlerWithAggregationSupport)
} else {
s.GenericAPIServer.Handler.NonGoRestfulMux.Handle("/apis", apisHandler)
}
s.GenericAPIServer.Handler.NonGoRestfulMux.UnlistedHandle("/apis/", apisHandler) s.GenericAPIServer.Handler.NonGoRestfulMux.UnlistedHandle("/apis/", apisHandler)
apiserviceRegistrationController := NewAPIServiceRegistrationController(informerFactory.Apiregistration().V1().APIServices(), s) apiserviceRegistrationController := NewAPIServiceRegistrationController(informerFactory.Apiregistration().V1().APIServices(), s)
@ -365,41 +361,39 @@ func (c completedConfig) NewWithDelegate(delegationTarget genericapiserver.Deleg
return nil return nil
}) })
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.AggregatedDiscoveryEndpoint) { s.discoveryAggregationController = NewDiscoveryManager(
s.discoveryAggregationController = NewDiscoveryManager( // Use aggregator as the source name to avoid overwriting native/CRD
// Use aggregator as the source name to avoid overwriting native/CRD // groups
// groups s.GenericAPIServer.AggregatedDiscoveryGroupManager.WithSource(aggregated.AggregatorSource),
s.GenericAPIServer.AggregatedDiscoveryGroupManager.WithSource(aggregated.AggregatorSource), )
)
// Setup discovery endpoint // Setup discovery endpoint
s.GenericAPIServer.AddPostStartHookOrDie("apiservice-discovery-controller", func(context genericapiserver.PostStartHookContext) error { s.GenericAPIServer.AddPostStartHookOrDie("apiservice-discovery-controller", func(context genericapiserver.PostStartHookContext) error {
// Discovery aggregation depends on the apiservice registration controller // Discovery aggregation depends on the apiservice registration controller
// having the full list of APIServices already synced // having the full list of APIServices already synced
select { select {
case <-context.Done(): case <-context.Done():
return nil
// Context cancelled, should abort/clean goroutines
case <-apiServiceRegistrationControllerInitiated:
}
// Run discovery manager's worker to watch for new/removed/updated
// APIServices to the discovery document can be updated at runtime
// When discovery is ready, all APIServices will be present, with APIServices
// that have not successfully synced discovery to be present but marked as Stale.
discoverySyncedCh := make(chan struct{})
go s.discoveryAggregationController.Run(context.Done(), discoverySyncedCh)
select {
case <-context.Done():
return nil
// Context cancelled, should abort/clean goroutines
case <-discoverySyncedCh:
// API services successfully sync
}
return nil return nil
}) // Context cancelled, should abort/clean goroutines
} case <-apiServiceRegistrationControllerInitiated:
}
// Run discovery manager's worker to watch for new/removed/updated
// APIServices to the discovery document can be updated at runtime
// When discovery is ready, all APIServices will be present, with APIServices
// that have not successfully synced discovery to be present but marked as Stale.
discoverySyncedCh := make(chan struct{})
go s.discoveryAggregationController.Run(context.Done(), discoverySyncedCh)
select {
case <-context.Done():
return nil
// Context cancelled, should abort/clean goroutines
case <-discoverySyncedCh:
// API services successfully sync
}
return nil
})
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StorageVersionAPI) && if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StorageVersionAPI) &&
utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerIdentity) { utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerIdentity) {

View File

@ -12,20 +12,6 @@
lockToDefault: true lockToDefault: true
preRelease: GA preRelease: GA
version: "1.30" version: "1.30"
- name: AggregatedDiscoveryEndpoint
versionedSpecs:
- default: false
lockToDefault: false
preRelease: Alpha
version: "1.26"
- default: true
lockToDefault: false
preRelease: Beta
version: "1.27"
- default: true
lockToDefault: true
preRelease: GA
version: "1.30"
- name: AllowDNSOnlyNodeCSR - name: AllowDNSOnlyNodeCSR
versionedSpecs: versionedSpecs:
- default: true - default: true

View File

@ -39,13 +39,10 @@ import (
utilruntime "k8s.io/apimachinery/pkg/util/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
discoveryendpoint "k8s.io/apiserver/pkg/endpoints/discovery/aggregated" discoveryendpoint "k8s.io/apiserver/pkg/endpoints/discovery/aggregated"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/discovery" "k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
kubernetes "k8s.io/client-go/kubernetes" kubernetes "k8s.io/client-go/kubernetes"
k8sscheme "k8s.io/client-go/kubernetes/scheme" k8sscheme "k8s.io/client-go/kubernetes/scheme"
featuregatetesting "k8s.io/component-base/featuregate/testing"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
@ -185,8 +182,6 @@ func setup(t *testing.T) (context.Context, testClientSet, context.CancelFunc) {
} }
func TestReadinessAggregatedAPIServiceDiscovery(t *testing.T) { func TestReadinessAggregatedAPIServiceDiscovery(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AggregatedDiscoveryEndpoint, true)
// Keep any goroutines spawned from running past the execution of this test // Keep any goroutines spawned from running past the execution of this test
ctx, client, cleanup := setup(t) ctx, client, cleanup := setup(t)
defer cleanup() defer cleanup()
@ -284,8 +279,6 @@ func unregisterAPIService(ctx context.Context, client aggregator.Interface, gv m
} }
func TestAggregatedAPIServiceDiscovery(t *testing.T) { func TestAggregatedAPIServiceDiscovery(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AggregatedDiscoveryEndpoint, true)
// Keep any goroutines spawned from running past the execution of this test // Keep any goroutines spawned from running past the execution of this test
ctx, client, cleanup := setup(t) ctx, client, cleanup := setup(t)
defer cleanup() defer cleanup()
@ -386,8 +379,6 @@ func runTestCases(t *testing.T, cases []testCase) {
// Declarative tests targeting CRD integration // Declarative tests targeting CRD integration
func TestCRD(t *testing.T) { func TestCRD(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AggregatedDiscoveryEndpoint, true)
runTestCases(t, []testCase{ runTestCases(t, []testCase{
{ {
// Show that when a CRD is added it gets included on the discovery doc // Show that when a CRD is added it gets included on the discovery doc
@ -626,8 +617,6 @@ func TestCRD(t *testing.T) {
} }
func TestFreshness(t *testing.T) { func TestFreshness(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AggregatedDiscoveryEndpoint, true)
requireStaleGVs := func(gvs ...metav1.GroupVersion) inlineAction { requireStaleGVs := func(gvs ...metav1.GroupVersion) inlineAction {
return inlineAction(func(ctx context.Context, client testClient) error { return inlineAction(func(ctx context.Context, client testClient) error {
document, err := FetchV2Discovery(ctx, client) document, err := FetchV2Discovery(ctx, client)
@ -716,8 +705,6 @@ func TestFreshness(t *testing.T) {
// Shows a group for which multiple APIServices specify a GroupPriorityMinimum, // Shows a group for which multiple APIServices specify a GroupPriorityMinimum,
// it is sorted the same in both versions of discovery // it is sorted the same in both versions of discovery
func TestGroupPriority(t *testing.T) { func TestGroupPriority(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.AggregatedDiscoveryEndpoint, true)
makeApiServiceSpec := func(gv metav1.GroupVersion, groupPriorityMin, versionPriority int) apiregistrationv1.APIServiceSpec { makeApiServiceSpec := func(gv metav1.GroupVersion, groupPriorityMin, versionPriority int) apiregistrationv1.APIServiceSpec {
return apiregistrationv1.APIServiceSpec{ return apiregistrationv1.APIServiceSpec{
Group: gv.Group, Group: gv.Group,