mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-09 03:57:41 +00:00
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:
commit
84a6ed4862
@ -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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user