Merge pull request #124638 from sttts/sttts-kube-apiserver-config-split-up
kube-apiserver: split up config creation into generic and non-generic part
This commit is contained in:
		@@ -18,11 +18,16 @@ package app
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	apiextensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
 | 
						apiextensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/util/webhook"
 | 
						"k8s.io/apiserver/pkg/util/webhook"
 | 
				
			||||||
	aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
 | 
						aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
 | 
				
			||||||
 | 
						aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
 | 
						"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controlplane"
 | 
						"k8s.io/kubernetes/pkg/controlplane"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controlplane/apiserver"
 | 
						controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver"
 | 
				
			||||||
 | 
						generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Config struct {
 | 
					type Config struct {
 | 
				
			||||||
@@ -71,13 +76,23 @@ func NewConfig(opts options.CompletedOptions) (*Config, error) {
 | 
				
			|||||||
		Options: opts,
 | 
							Options: opts,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kubeAPIs, serviceResolver, pluginInitializer, err := CreateKubeAPIServerConfig(opts)
 | 
						genericConfig, versionedInformers, storageFactory, err := controlplaneapiserver.BuildGenericConfig(
 | 
				
			||||||
 | 
							opts.CompletedOptions,
 | 
				
			||||||
 | 
							[]*runtime.Scheme{legacyscheme.Scheme, apiextensionsapiserver.Scheme, aggregatorscheme.Scheme},
 | 
				
			||||||
 | 
							controlplane.DefaultAPIResourceConfigSource(),
 | 
				
			||||||
 | 
							generatedopenapi.GetOpenAPIDefinitions,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kubeAPIs, serviceResolver, pluginInitializer, err := CreateKubeAPIServerConfig(opts, genericConfig, versionedInformers, storageFactory)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.KubeAPIs = kubeAPIs
 | 
						c.KubeAPIs = kubeAPIs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	apiExtensions, err := apiserver.CreateAPIExtensionsConfig(*kubeAPIs.ControlPlane.Generic, kubeAPIs.ControlPlane.VersionedInformers, pluginInitializer, opts.CompletedOptions, opts.MasterCount,
 | 
						apiExtensions, err := controlplaneapiserver.CreateAPIExtensionsConfig(*kubeAPIs.ControlPlane.Generic, kubeAPIs.ControlPlane.VersionedInformers, pluginInitializer, opts.CompletedOptions, opts.MasterCount,
 | 
				
			||||||
		serviceResolver, webhook.NewDefaultAuthenticationInfoResolverWrapper(kubeAPIs.ControlPlane.ProxyTransport, kubeAPIs.ControlPlane.Generic.EgressSelector, kubeAPIs.ControlPlane.Generic.LoopbackClientConfig, kubeAPIs.ControlPlane.Generic.TracerProvider))
 | 
							serviceResolver, webhook.NewDefaultAuthenticationInfoResolverWrapper(kubeAPIs.ControlPlane.ProxyTransport, kubeAPIs.ControlPlane.Generic.EgressSelector, kubeAPIs.ControlPlane.Generic.LoopbackClientConfig, kubeAPIs.ControlPlane.Generic.TracerProvider))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,31 +21,24 @@ package app
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"crypto/tls"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 | 
						apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 | 
				
			||||||
	extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
 | 
					 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
					 | 
				
			||||||
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 | 
						utilerrors "k8s.io/apimachinery/pkg/util/errors"
 | 
				
			||||||
	utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
					 | 
				
			||||||
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 | 
						utilruntime "k8s.io/apimachinery/pkg/util/runtime"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/admission"
 | 
						"k8s.io/apiserver/pkg/admission"
 | 
				
			||||||
	genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
 | 
						genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
 | 
				
			||||||
	genericapiserver "k8s.io/apiserver/pkg/server"
 | 
						genericapiserver "k8s.io/apiserver/pkg/server"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/server/egressselector"
 | 
						"k8s.io/apiserver/pkg/server/egressselector"
 | 
				
			||||||
 | 
						serverstorage "k8s.io/apiserver/pkg/server/storage"
 | 
				
			||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/util/notfoundhandler"
 | 
						"k8s.io/apiserver/pkg/util/notfoundhandler"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/util/webhook"
 | 
						"k8s.io/apiserver/pkg/util/webhook"
 | 
				
			||||||
	"k8s.io/client-go/dynamic"
 | 
					 | 
				
			||||||
	clientgoinformers "k8s.io/client-go/informers"
 | 
						clientgoinformers "k8s.io/client-go/informers"
 | 
				
			||||||
	clientset "k8s.io/client-go/kubernetes"
 | 
					 | 
				
			||||||
	"k8s.io/client-go/rest"
 | 
						"k8s.io/client-go/rest"
 | 
				
			||||||
	"k8s.io/client-go/util/keyutil"
 | 
					 | 
				
			||||||
	cliflag "k8s.io/component-base/cli/flag"
 | 
						cliflag "k8s.io/component-base/cli/flag"
 | 
				
			||||||
	"k8s.io/component-base/cli/globalflag"
 | 
						"k8s.io/component-base/cli/globalflag"
 | 
				
			||||||
	"k8s.io/component-base/logs"
 | 
						"k8s.io/component-base/logs"
 | 
				
			||||||
@@ -56,19 +49,12 @@ import (
 | 
				
			|||||||
	"k8s.io/component-base/version/verflag"
 | 
						"k8s.io/component-base/version/verflag"
 | 
				
			||||||
	"k8s.io/klog/v2"
 | 
						"k8s.io/klog/v2"
 | 
				
			||||||
	aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
 | 
						aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
 | 
				
			||||||
	aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
 | 
					 | 
				
			||||||
	controlplaneadmission "k8s.io/kubernetes/pkg/controlplane/apiserver/admission"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
 | 
						"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/pkg/capabilities"
 | 
						"k8s.io/kubernetes/pkg/capabilities"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controlplane"
 | 
						"k8s.io/kubernetes/pkg/controlplane"
 | 
				
			||||||
	controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver"
 | 
						controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controlplane/reconcilers"
 | 
						"k8s.io/kubernetes/pkg/controlplane/reconcilers"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/features"
 | 
					 | 
				
			||||||
	generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
 | 
					 | 
				
			||||||
	kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
 | 
						kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/serviceaccount"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
@@ -196,49 +182,22 @@ func CreateServerChain(config CompletedConfig) (*aggregatorapiserver.APIAggregat
 | 
				
			|||||||
	return aggregatorServer, nil
 | 
						return aggregatorServer, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateProxyTransport creates the dialer infrastructure to connect to the nodes.
 | 
					 | 
				
			||||||
func CreateProxyTransport() *http.Transport {
 | 
					 | 
				
			||||||
	var proxyDialerFn utilnet.DialFunc
 | 
					 | 
				
			||||||
	// Proxying to pods and services is IP-based... don't expect to be able to verify the hostname
 | 
					 | 
				
			||||||
	proxyTLSClientConfig := &tls.Config{InsecureSkipVerify: true}
 | 
					 | 
				
			||||||
	proxyTransport := utilnet.SetTransportDefaults(&http.Transport{
 | 
					 | 
				
			||||||
		DialContext:     proxyDialerFn,
 | 
					 | 
				
			||||||
		TLSClientConfig: proxyTLSClientConfig,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	return proxyTransport
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CreateKubeAPIServerConfig creates all the resources for running the API server, but runs none of them
 | 
					// CreateKubeAPIServerConfig creates all the resources for running the API server, but runs none of them
 | 
				
			||||||
func CreateKubeAPIServerConfig(opts options.CompletedOptions) (
 | 
					func CreateKubeAPIServerConfig(
 | 
				
			||||||
 | 
						opts options.CompletedOptions,
 | 
				
			||||||
 | 
						genericConfig *genericapiserver.Config,
 | 
				
			||||||
 | 
						versionedInformers clientgoinformers.SharedInformerFactory,
 | 
				
			||||||
 | 
						storageFactory *serverstorage.DefaultStorageFactory,
 | 
				
			||||||
 | 
					) (
 | 
				
			||||||
	*controlplane.Config,
 | 
						*controlplane.Config,
 | 
				
			||||||
	aggregatorapiserver.ServiceResolver,
 | 
						aggregatorapiserver.ServiceResolver,
 | 
				
			||||||
	[]admission.PluginInitializer,
 | 
						[]admission.PluginInitializer,
 | 
				
			||||||
	error,
 | 
						error,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
	proxyTransport := CreateProxyTransport()
 | 
						// global stuff
 | 
				
			||||||
 | 
						capabilities.Setup(opts.AllowPrivileged, opts.MaxConnectionBytesPerSec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	genericConfig, versionedInformers, storageFactory, err := controlplaneapiserver.BuildGenericConfig(
 | 
						// additional admission initializers
 | 
				
			||||||
		opts.CompletedOptions,
 | 
					 | 
				
			||||||
		[]*runtime.Scheme{legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme},
 | 
					 | 
				
			||||||
		controlplane.DefaultAPIResourceConfigSource(),
 | 
					 | 
				
			||||||
		generatedopenapi.GetOpenAPIDefinitions,
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, fmt.Errorf("failed to create generic config: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// generic controlplane admission initializers
 | 
					 | 
				
			||||||
	controlPlaneAdmissionConfig := &controlplaneadmission.Config{
 | 
					 | 
				
			||||||
		ExternalInformers:    versionedInformers,
 | 
					 | 
				
			||||||
		LoopbackClientConfig: genericConfig.LoopbackClientConfig,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	serviceResolver := buildServiceResolver(opts.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, versionedInformers)
 | 
					 | 
				
			||||||
	pluginInitializers, err := controlPlaneAdmissionConfig.New(proxyTransport, genericConfig.EgressSelector, serviceResolver, genericConfig.TracerProvider)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// additional kube admission initializers
 | 
					 | 
				
			||||||
	kubeAdmissionConfig := &kubeapiserveradmission.Config{
 | 
						kubeAdmissionConfig := &kubeapiserveradmission.Config{
 | 
				
			||||||
		CloudConfigFile: opts.CloudProvider.CloudConfigFile,
 | 
							CloudConfigFile: opts.CloudProvider.CloudConfigFile,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -246,31 +205,15 @@ func CreateKubeAPIServerConfig(opts options.CompletedOptions) (
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %w", err)
 | 
							return nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pluginInitializers = append(pluginInitializers, kubeInitializers...)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	capabilities.Setup(opts.AllowPrivileged, opts.MaxConnectionBytesPerSec)
 | 
						serviceResolver := buildServiceResolver(opts.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, versionedInformers)
 | 
				
			||||||
 | 
						controlplaneConfig, admissionInitializers, err := controlplaneapiserver.CreateConfig(opts.CompletedOptions, genericConfig, versionedInformers, storageFactory, serviceResolver, kubeInitializers)
 | 
				
			||||||
	opts.Metrics.Apply()
 | 
						if err != nil {
 | 
				
			||||||
	serviceaccount.RegisterMetrics()
 | 
							return nil, nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	config := &controlplane.Config{
 | 
						config := &controlplane.Config{
 | 
				
			||||||
		ControlPlane: controlplaneapiserver.Config{
 | 
							ControlPlane: *controlplaneConfig,
 | 
				
			||||||
			Generic: genericConfig,
 | 
					 | 
				
			||||||
			Extra: controlplaneapiserver.Extra{
 | 
					 | 
				
			||||||
				APIResourceConfigSource: storageFactory.APIResourceConfigSource,
 | 
					 | 
				
			||||||
				StorageFactory:          storageFactory,
 | 
					 | 
				
			||||||
				EventTTL:                opts.EventTTL,
 | 
					 | 
				
			||||||
				EnableLogsSupport:       opts.EnableLogsHandler,
 | 
					 | 
				
			||||||
				ProxyTransport:          proxyTransport,
 | 
					 | 
				
			||||||
				SystemNamespaces:        opts.SystemNamespaces,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				ServiceAccountIssuer:        opts.ServiceAccountIssuer,
 | 
					 | 
				
			||||||
				ServiceAccountMaxExpiration: opts.ServiceAccountTokenMaxExpiration,
 | 
					 | 
				
			||||||
				ExtendExpiration:            opts.Authentication.ServiceAccounts.ExtendExpiration,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				VersionedInformers: versionedInformers,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		Extra: controlplane.Extra{
 | 
							Extra: controlplane.Extra{
 | 
				
			||||||
			KubeletClientConfig: opts.KubeletConfig,
 | 
								KubeletClientConfig: opts.KubeletConfig,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -288,59 +231,6 @@ func CreateKubeAPIServerConfig(opts options.CompletedOptions) (
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if utilfeature.DefaultFeatureGate.Enabled(features.UnknownVersionInteroperabilityProxy) {
 | 
					 | 
				
			||||||
		config.ControlPlane.PeerEndpointLeaseReconciler, err = controlplaneapiserver.CreatePeerEndpointLeaseReconciler(*genericConfig, storageFactory)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, nil, nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// build peer proxy config only if peer ca file exists
 | 
					 | 
				
			||||||
		if opts.PeerCAFile != "" {
 | 
					 | 
				
			||||||
			config.ControlPlane.PeerProxy, err = controlplaneapiserver.BuildPeerProxy(versionedInformers, genericConfig.StorageVersionManager, opts.ProxyClientCertFile,
 | 
					 | 
				
			||||||
				opts.ProxyClientKeyFile, opts.PeerCAFile, opts.PeerAdvertiseAddress, genericConfig.APIServerID, config.ControlPlane.Extra.PeerEndpointLeaseReconciler, config.ControlPlane.Generic.Serializer)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, nil, nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	clientCAProvider, err := opts.Authentication.ClientCert.GetClientCAContentProvider()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	config.ControlPlane.ClusterAuthenticationInfo.ClientCA = clientCAProvider
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	requestHeaderConfig, err := opts.Authentication.RequestHeader.ToAuthenticationRequestHeaderConfig()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if requestHeaderConfig != nil {
 | 
					 | 
				
			||||||
		config.ControlPlane.ClusterAuthenticationInfo.RequestHeaderCA = requestHeaderConfig.CAContentProvider
 | 
					 | 
				
			||||||
		config.ControlPlane.ClusterAuthenticationInfo.RequestHeaderAllowedNames = requestHeaderConfig.AllowedClientNames
 | 
					 | 
				
			||||||
		config.ControlPlane.ClusterAuthenticationInfo.RequestHeaderExtraHeaderPrefixes = requestHeaderConfig.ExtraHeaderPrefixes
 | 
					 | 
				
			||||||
		config.ControlPlane.ClusterAuthenticationInfo.RequestHeaderGroupHeaders = requestHeaderConfig.GroupHeaders
 | 
					 | 
				
			||||||
		config.ControlPlane.ClusterAuthenticationInfo.RequestHeaderUsernameHeaders = requestHeaderConfig.UsernameHeaders
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// setup admission
 | 
					 | 
				
			||||||
	clientgoExternalClient, err := clientset.NewForConfig(genericConfig.LoopbackClientConfig)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, fmt.Errorf("failed to create real client-go external client: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	dynamicExternalClient, err := dynamic.NewForConfig(genericConfig.LoopbackClientConfig)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, fmt.Errorf("failed to create real dynamic external client: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	err = opts.Admission.ApplyTo(
 | 
					 | 
				
			||||||
		genericConfig,
 | 
					 | 
				
			||||||
		versionedInformers,
 | 
					 | 
				
			||||||
		clientgoExternalClient,
 | 
					 | 
				
			||||||
		dynamicExternalClient,
 | 
					 | 
				
			||||||
		utilfeature.DefaultFeatureGate,
 | 
					 | 
				
			||||||
		pluginInitializers...)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, nil, fmt.Errorf("failed to apply admission: %w", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if config.ControlPlane.Generic.EgressSelector != nil {
 | 
						if config.ControlPlane.Generic.EgressSelector != nil {
 | 
				
			||||||
		// Use the config.ControlPlane.Generic.EgressSelector lookup to find the dialer to connect to the kubelet
 | 
							// Use the config.ControlPlane.Generic.EgressSelector lookup to find the dialer to connect to the kubelet
 | 
				
			||||||
		config.Extra.KubeletClientConfig.Lookup = config.ControlPlane.Generic.EgressSelector.Lookup
 | 
							config.Extra.KubeletClientConfig.Lookup = config.ControlPlane.Generic.EgressSelector.Lookup
 | 
				
			||||||
@@ -351,25 +241,12 @@ func CreateKubeAPIServerConfig(opts options.CompletedOptions) (
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, nil, nil, err
 | 
								return nil, nil, nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		c := proxyTransport.Clone()
 | 
							c := config.ControlPlane.Extra.ProxyTransport.Clone()
 | 
				
			||||||
		c.DialContext = dialer
 | 
							c.DialContext = dialer
 | 
				
			||||||
		config.ControlPlane.ProxyTransport = c
 | 
							config.ControlPlane.ProxyTransport = c
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Load and set the public keys.
 | 
						return config, serviceResolver, admissionInitializers, nil
 | 
				
			||||||
	var pubKeys []interface{}
 | 
					 | 
				
			||||||
	for _, f := range opts.Authentication.ServiceAccounts.KeyFiles {
 | 
					 | 
				
			||||||
		keys, err := keyutil.PublicKeysFromFile(f)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, nil, nil, fmt.Errorf("failed to parse key file %q: %v", f, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		pubKeys = append(pubKeys, keys...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	config.ControlPlane.ServiceAccountIssuerURL = opts.Authentication.ServiceAccounts.Issuers[0]
 | 
					 | 
				
			||||||
	config.ControlPlane.ServiceAccountJWKSURI = opts.Authentication.ServiceAccounts.JWKSURI
 | 
					 | 
				
			||||||
	config.ControlPlane.ServiceAccountPublicKeys = pubKeys
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return config, serviceResolver, pluginInitializers, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var testServiceResolver webhook.ServiceResolver
 | 
					var testServiceResolver webhook.ServiceResolver
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ package apiserver
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"crypto/tls"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -25,8 +26,10 @@ import (
 | 
				
			|||||||
	oteltrace "go.opentelemetry.io/otel/trace"
 | 
						oteltrace "go.opentelemetry.io/otel/trace"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
 | 
						utilnet "k8s.io/apimachinery/pkg/util/net"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
 | 
						"k8s.io/apiserver/pkg/admission"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/authorization/authorizer"
 | 
						"k8s.io/apiserver/pkg/authorization/authorizer"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/endpoints/discovery/aggregated"
 | 
						"k8s.io/apiserver/pkg/endpoints/discovery/aggregated"
 | 
				
			||||||
	openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
 | 
						openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
 | 
				
			||||||
@@ -39,14 +42,19 @@ import (
 | 
				
			|||||||
	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/util/openapi"
 | 
						"k8s.io/apiserver/pkg/util/openapi"
 | 
				
			||||||
	utilpeerproxy "k8s.io/apiserver/pkg/util/peerproxy"
 | 
						utilpeerproxy "k8s.io/apiserver/pkg/util/peerproxy"
 | 
				
			||||||
 | 
						"k8s.io/client-go/dynamic"
 | 
				
			||||||
	clientgoinformers "k8s.io/client-go/informers"
 | 
						clientgoinformers "k8s.io/client-go/informers"
 | 
				
			||||||
	clientgoclientset "k8s.io/client-go/kubernetes"
 | 
						clientgoclientset "k8s.io/client-go/kubernetes"
 | 
				
			||||||
 | 
						"k8s.io/client-go/util/keyutil"
 | 
				
			||||||
	"k8s.io/component-base/version"
 | 
						"k8s.io/component-base/version"
 | 
				
			||||||
 | 
						aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
 | 
				
			||||||
	openapicommon "k8s.io/kube-openapi/pkg/common"
 | 
						openapicommon "k8s.io/kube-openapi/pkg/common"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
						"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
				
			||||||
 | 
						controlplaneadmission "k8s.io/kubernetes/pkg/controlplane/apiserver/admission"
 | 
				
			||||||
	controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
 | 
						controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controlplane/controller/clusterauthenticationtrust"
 | 
						"k8s.io/kubernetes/pkg/controlplane/controller/clusterauthenticationtrust"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubeapiserver"
 | 
						"k8s.io/kubernetes/pkg/kubeapiserver"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
 | 
						"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
 | 
				
			||||||
	rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
 | 
						rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
 | 
				
			||||||
@@ -254,3 +262,131 @@ func BuildAuthorizer(ctx context.Context, s controlplaneapiserver.CompletedOptio
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return authorizer, ruleResolver, enablesRBAC, err
 | 
						return authorizer, ruleResolver, enablesRBAC, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateConfig takes the generic controlplane apiserver options and
 | 
				
			||||||
 | 
					// creates a config for the generic Kube APIs out of it.
 | 
				
			||||||
 | 
					func CreateConfig(
 | 
				
			||||||
 | 
						opts controlplaneapiserver.CompletedOptions,
 | 
				
			||||||
 | 
						genericConfig *genericapiserver.Config,
 | 
				
			||||||
 | 
						versionedInformers clientgoinformers.SharedInformerFactory,
 | 
				
			||||||
 | 
						storageFactory *serverstorage.DefaultStorageFactory,
 | 
				
			||||||
 | 
						serviceResolver aggregatorapiserver.ServiceResolver,
 | 
				
			||||||
 | 
						additionalInitializers []admission.PluginInitializer,
 | 
				
			||||||
 | 
					) (
 | 
				
			||||||
 | 
						*Config,
 | 
				
			||||||
 | 
						[]admission.PluginInitializer,
 | 
				
			||||||
 | 
						error,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						proxyTransport := CreateProxyTransport()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opts.Metrics.Apply()
 | 
				
			||||||
 | 
						serviceaccount.RegisterMetrics()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config := &Config{
 | 
				
			||||||
 | 
							Generic: genericConfig,
 | 
				
			||||||
 | 
							Extra: Extra{
 | 
				
			||||||
 | 
								APIResourceConfigSource: storageFactory.APIResourceConfigSource,
 | 
				
			||||||
 | 
								StorageFactory:          storageFactory,
 | 
				
			||||||
 | 
								EventTTL:                opts.EventTTL,
 | 
				
			||||||
 | 
								EnableLogsSupport:       opts.EnableLogsHandler,
 | 
				
			||||||
 | 
								ProxyTransport:          proxyTransport,
 | 
				
			||||||
 | 
								SystemNamespaces:        opts.SystemNamespaces,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ServiceAccountIssuer:        opts.ServiceAccountIssuer,
 | 
				
			||||||
 | 
								ServiceAccountMaxExpiration: opts.ServiceAccountTokenMaxExpiration,
 | 
				
			||||||
 | 
								ExtendExpiration:            opts.Authentication.ServiceAccounts.ExtendExpiration,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								VersionedInformers: versionedInformers,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if utilfeature.DefaultFeatureGate.Enabled(features.UnknownVersionInteroperabilityProxy) {
 | 
				
			||||||
 | 
							var err error
 | 
				
			||||||
 | 
							config.PeerEndpointLeaseReconciler, err = CreatePeerEndpointLeaseReconciler(*genericConfig, storageFactory)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// build peer proxy config only if peer ca file exists
 | 
				
			||||||
 | 
							if opts.PeerCAFile != "" {
 | 
				
			||||||
 | 
								config.PeerProxy, err = BuildPeerProxy(versionedInformers, genericConfig.StorageVersionManager, opts.ProxyClientCertFile,
 | 
				
			||||||
 | 
									opts.ProxyClientKeyFile, opts.PeerCAFile, opts.PeerAdvertiseAddress, genericConfig.APIServerID, config.Extra.PeerEndpointLeaseReconciler, config.Generic.Serializer)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						clientCAProvider, err := opts.Authentication.ClientCert.GetClientCAContentProvider()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						config.ClusterAuthenticationInfo.ClientCA = clientCAProvider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						requestHeaderConfig, err := opts.Authentication.RequestHeader.ToAuthenticationRequestHeaderConfig()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if requestHeaderConfig != nil {
 | 
				
			||||||
 | 
							config.ClusterAuthenticationInfo.RequestHeaderCA = requestHeaderConfig.CAContentProvider
 | 
				
			||||||
 | 
							config.ClusterAuthenticationInfo.RequestHeaderAllowedNames = requestHeaderConfig.AllowedClientNames
 | 
				
			||||||
 | 
							config.ClusterAuthenticationInfo.RequestHeaderExtraHeaderPrefixes = requestHeaderConfig.ExtraHeaderPrefixes
 | 
				
			||||||
 | 
							config.ClusterAuthenticationInfo.RequestHeaderGroupHeaders = requestHeaderConfig.GroupHeaders
 | 
				
			||||||
 | 
							config.ClusterAuthenticationInfo.RequestHeaderUsernameHeaders = requestHeaderConfig.UsernameHeaders
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// setup admission
 | 
				
			||||||
 | 
						genericAdmissionConfig := controlplaneadmission.Config{
 | 
				
			||||||
 | 
							ExternalInformers:    versionedInformers,
 | 
				
			||||||
 | 
							LoopbackClientConfig: genericConfig.LoopbackClientConfig,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						genericInitializers, err := genericAdmissionConfig.New(proxyTransport, genericConfig.EgressSelector, serviceResolver, genericConfig.TracerProvider)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, fmt.Errorf("failed to create admission plugin initializer: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						clientgoExternalClient, err := clientgoclientset.NewForConfig(genericConfig.LoopbackClientConfig)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, fmt.Errorf("failed to create real client-go external client: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dynamicExternalClient, err := dynamic.NewForConfig(genericConfig.LoopbackClientConfig)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, fmt.Errorf("failed to create real dynamic external client: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						err = opts.Admission.ApplyTo(
 | 
				
			||||||
 | 
							genericConfig,
 | 
				
			||||||
 | 
							versionedInformers,
 | 
				
			||||||
 | 
							clientgoExternalClient,
 | 
				
			||||||
 | 
							dynamicExternalClient,
 | 
				
			||||||
 | 
							utilfeature.DefaultFeatureGate,
 | 
				
			||||||
 | 
							append(genericInitializers, additionalInitializers...)...,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, fmt.Errorf("failed to apply admission: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Load and set the public keys.
 | 
				
			||||||
 | 
						var pubKeys []interface{}
 | 
				
			||||||
 | 
						for _, f := range opts.Authentication.ServiceAccounts.KeyFiles {
 | 
				
			||||||
 | 
							keys, err := keyutil.PublicKeysFromFile(f)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, nil, fmt.Errorf("failed to parse key file %q: %w", f, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pubKeys = append(pubKeys, keys...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						config.ServiceAccountIssuerURL = opts.Authentication.ServiceAccounts.Issuers[0]
 | 
				
			||||||
 | 
						config.ServiceAccountJWKSURI = opts.Authentication.ServiceAccounts.JWKSURI
 | 
				
			||||||
 | 
						config.ServiceAccountPublicKeys = pubKeys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return config, genericInitializers, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateProxyTransport creates the dialer infrastructure to connect to the nodes.
 | 
				
			||||||
 | 
					func CreateProxyTransport() *http.Transport {
 | 
				
			||||||
 | 
						var proxyDialerFn utilnet.DialFunc
 | 
				
			||||||
 | 
						// Proxying to pods and services is IP-based... don't expect to be able to verify the hostname
 | 
				
			||||||
 | 
						proxyTLSClientConfig := &tls.Config{InsecureSkipVerify: true}
 | 
				
			||||||
 | 
						proxyTransport := utilnet.SetTransportDefaults(&http.Transport{
 | 
				
			||||||
 | 
							DialContext:     proxyDialerFn,
 | 
				
			||||||
 | 
							TLSClientConfig: proxyTLSClientConfig,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						return proxyTransport
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,9 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apiextensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
 | 
				
			||||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/runtime"
 | 
				
			||||||
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 | 
						utilerrors "k8s.io/apimachinery/pkg/util/errors"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
	genericapiserver "k8s.io/apiserver/pkg/server"
 | 
						genericapiserver "k8s.io/apiserver/pkg/server"
 | 
				
			||||||
@@ -36,11 +38,16 @@ import (
 | 
				
			|||||||
	client "k8s.io/client-go/kubernetes"
 | 
						client "k8s.io/client-go/kubernetes"
 | 
				
			||||||
	"k8s.io/client-go/rest"
 | 
						"k8s.io/client-go/rest"
 | 
				
			||||||
	"k8s.io/client-go/util/cert"
 | 
						"k8s.io/client-go/util/cert"
 | 
				
			||||||
 | 
						aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
 | 
				
			||||||
 | 
						netutils "k8s.io/utils/net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/kube-apiserver/app"
 | 
						"k8s.io/kubernetes/cmd/kube-apiserver/app"
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
 | 
						"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/api/legacyscheme"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/controlplane"
 | 
						"k8s.io/kubernetes/pkg/controlplane"
 | 
				
			||||||
 | 
						controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver"
 | 
				
			||||||
 | 
						generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
 | 
				
			||||||
	"k8s.io/kubernetes/test/utils"
 | 
						"k8s.io/kubernetes/test/utils"
 | 
				
			||||||
	netutils "k8s.io/utils/net"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This key is for testing purposes only and is not considered secure.
 | 
					// This key is for testing purposes only and is not considered secure.
 | 
				
			||||||
@@ -160,7 +167,17 @@ func StartTestServer(ctx context.Context, t testing.TB, setup TestServerSetup) (
 | 
				
			|||||||
		t.Fatalf("failed to validate ServerRunOptions: %v", utilerrors.NewAggregate(errs))
 | 
							t.Fatalf("failed to validate ServerRunOptions: %v", utilerrors.NewAggregate(errs))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kubeAPIServerConfig, _, _, err := app.CreateKubeAPIServerConfig(completedOptions)
 | 
						genericConfig, versionedInformers, storageFactory, err := controlplaneapiserver.BuildGenericConfig(
 | 
				
			||||||
 | 
							completedOptions.CompletedOptions,
 | 
				
			||||||
 | 
							[]*runtime.Scheme{legacyscheme.Scheme, apiextensionsapiserver.Scheme, aggregatorscheme.Scheme},
 | 
				
			||||||
 | 
							controlplane.DefaultAPIResourceConfigSource(),
 | 
				
			||||||
 | 
							generatedopenapi.GetOpenAPIDefinitions,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kubeAPIServerConfig, _, _, err := app.CreateKubeAPIServerConfig(completedOptions, genericConfig, versionedInformers, storageFactory)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user