From ca60f81cfd3839f2c8bda2c6723a37e11f898fa5 Mon Sep 17 00:00:00 2001 From: kaiyou <dev@kaiyou.fr> Date: Sun, 23 Apr 2023 15:17:25 +0200 Subject: [PATCH] Improve documentation about the apiserver --- services/apiserver.go | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/services/apiserver.go b/services/apiserver.go index bd5bfce..81afb46 100644 --- a/services/apiserver.go +++ b/services/apiserver.go @@ -9,7 +9,6 @@ import ( "time" "github.com/google/uuid" - // extensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" extensions "k8s.io/apiextensions-apiserver/pkg/apiserver" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -214,11 +213,17 @@ var kubeApiserver = &Unit{ // Allow privileged pods capabilities.Setup(true, 0) - // Configure etcd backend + // Configure the etcd backend, this is used by both the default and CRD apiservers etcdConfig := storagebackend.NewDefaultConfig("/registry", nil) etcdConfig.Transport.ServerList = []string{"http://[::1]:2379"} // Servers are created in reverse orders for proper delegation + // First notFound is the default handler, that basically returns a 404, + // then the extensions serves CRD for unknown kinds, finally + // the default apiserver is first in the chain and serves all default kinds + // Note that no API aggregation is setup, which means that k8s API aggregation + // is not supported by hepto. + notFound := notfoundhandler.New(config.Serializer, apifilters.NoMuxAndDiscoveryIncompleteKey) // Tweak the configuration and build the extension server @@ -233,7 +238,6 @@ var kubeApiserver = &Unit{ extensionsConfig.GenericConfig.RESTOptionsGetter = &RestOptionsFactory{ StorageFactory: storage.NewDefaultStorageFactory( *etcdConfig, - //*storagebackend.NewDefaultConfig("/registry", extensions.Codecs.LegacyCodec(extensionsv1.SchemeGroupVersion)), runtime.ContentTypeJSON, legacyscheme.Codecs, storage.NewDefaultResourceEncodingConfig(extensions.Scheme), @@ -256,7 +260,7 @@ var kubeApiserver = &Unit{ controlplane.DefaultAPIResourceConfigSource(), kubeapiserver.SpecialDefaultResourcePrefixes, ) - signer, err := serviceaccount.JWTTokenGenerator("https://kubernetes.default.svc.cluster.local", c.masterCerts.APITokens.Key) + signer, err := serviceaccount.JWTTokenGenerator(audience, c.masterCerts.APITokens.Key) if err != nil { return fmt.Errorf("could not initilize service account signer: %w", err) } @@ -271,32 +275,30 @@ var kubeApiserver = &Unit{ ReadOnlyPort: ports.KubeletReadOnlyPort, PreferredAddressTypes: []string{string(core.NodeInternalIP), string(core.NodeExternalIP)}, }, - ServiceIPRange: *c.networking.ServiceNet, - APIServerServiceIP: c.networking.APIAddress, - APIServerServicePort: 443, - ServiceNodePortRange: options.DefaultServiceNodePortRange, + ServiceIPRange: *c.networking.ServiceNet, + APIServerServiceIP: c.networking.APIAddress, + APIServerServicePort: 443, + ServiceNodePortRange: options.DefaultServiceNodePortRange, + // This still triggers an error, stating that stale data was found and cleaned up, + // which is inevitable EndpointReconcilerType: reconcilers.NoneEndpointReconcilerType, MasterCount: 1, ServiceAccountIssuer: signer, - ServiceAccountIssuerURL: "https://kubernetes.default.svc.cluster.local", - ServiceAccountPublicKeys: nil, // TODO + ServiceAccountIssuerURL: audience, + ServiceAccountPublicKeys: []interface{}{&c.masterCerts.APITokens.Key.PublicKey}, VersionedInformers: clients.Informer, }, } apiConfig.GenericConfig.RESTOptionsGetter = &RestOptionsFactory{StorageFactory: storageFactory} - getOpenapi := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions) - apiConfig.GenericConfig.OpenAPIConfig = server.DefaultOpenAPIConfig(getOpenapi, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensions.Scheme)) - apiConfig.GenericConfig.OpenAPIConfig = server.DefaultOpenAPIConfig(getOpenapi, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensions.Scheme)) + openapiFactory := openapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions) + apiConfig.GenericConfig.OpenAPIConfig = server.DefaultOpenAPIConfig(openapiFactory, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensions.Scheme)) + apiConfig.GenericConfig.OpenAPIConfig = server.DefaultOpenAPIConfig(openapiFactory, openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensions.Scheme)) apiConfig.ExtraConfig.ClusterAuthenticationInfo.ClientCA = config.SecureServing.ClientCA apiServer, err := apiConfig.Complete().New(extensionServer.GenericAPIServer) if err != nil { return fmt.Errorf("could not initialize generic apiserver: %w", err) } - // TODO: no aggregation layer is setup - - server := apiServer.GenericAPIServer.PrepareRun() - // Write a loopback config (different for every start) name := "loopback" clientConfig := api.Config{ @@ -324,12 +326,16 @@ var kubeApiserver = &Unit{ return fmt.Errorf("could not write privileged kubeconfig: %w", err) } + // Finally start the apiserver + server := apiServer.GenericAPIServer.PrepareRun() return server.Run(ctx.Done()) }, Ready: func(u *Unit, c *Cluster) bool { u.Logger.Info("checking if apiserver is ready") + // Use the scheduler certificate for readiness test, which is more relevant than + // using the internal privileged API token kc := &rest.Config{ - Host: fmt.Sprintf("https://[%s]:6443", c.networking.NodeAddress.IP.String()), + Host: fmt.Sprintf("https://[%s]:%d", c.networking.NodeAddress.IP.String(), apiserverPort), TLSClientConfig: rest.TLSClientConfig{ CAFile: c.pki.TLS.CertPath(), CertFile: c.masterCerts.SchedulerAPI.CertPath(), -- GitLab