mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-29 21:29:24 +00:00
Fix client-ca dynamic reload in apiserver
This commit is contained in:
@@ -13,7 +13,6 @@ go_library(
|
||||
"//cmd/kube-apiserver/app/options:go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/controller/serviceaccount:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/generated/openapi:go_default_library",
|
||||
"//pkg/kubeapiserver:go_default_library",
|
||||
@@ -29,7 +28,6 @@ go_library(
|
||||
"//pkg/registry/cachesize:go_default_library",
|
||||
"//pkg/registry/rbac/rest:go_default_library",
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//plugin/pkg/auth/authenticator/token/bootstrap:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver:go_default_library",
|
||||
@@ -43,7 +41,6 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/endpoints/openapi:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
|
||||
@@ -76,12 +73,17 @@ go_library(
|
||||
"//staging/src/k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kube-aggregator/pkg/controllers/autoregister:go_default_library",
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["server_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
@@ -99,9 +101,3 @@ filegroup(
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["server_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
@@ -30,17 +30,14 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilwait "k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
openapinamer "k8s.io/apiserver/pkg/endpoints/openapi"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
@@ -70,7 +67,6 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/capabilities"
|
||||
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
|
||||
"k8s.io/kubernetes/pkg/kubeapiserver"
|
||||
@@ -85,7 +81,6 @@ import (
|
||||
"k8s.io/kubernetes/pkg/registry/cachesize"
|
||||
rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -440,9 +435,6 @@ func buildGenericConfig(
|
||||
if lastErr = s.SecureServing.ApplyTo(&genericConfig.SecureServing, &genericConfig.LoopbackClientConfig); lastErr != nil {
|
||||
return
|
||||
}
|
||||
if lastErr = s.Authentication.ApplyTo(genericConfig); lastErr != nil {
|
||||
return
|
||||
}
|
||||
if lastErr = s.Features.ApplyTo(genericConfig); lastErr != nil {
|
||||
return
|
||||
}
|
||||
@@ -498,9 +490,8 @@ func buildGenericConfig(
|
||||
}
|
||||
versionedInformers = clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute)
|
||||
|
||||
genericConfig.Authentication.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, genericConfig.EgressSelector, clientgoExternalClient, versionedInformers)
|
||||
if err != nil {
|
||||
lastErr = fmt.Errorf("invalid authentication config: %v", err)
|
||||
// Authentication.ApplyTo requires already applied OpenAPIConfig and EgressSelector if present
|
||||
if lastErr = s.Authentication.ApplyTo(&genericConfig.Authentication, genericConfig.SecureServing, genericConfig.EgressSelector, genericConfig.OpenAPIConfig, clientgoExternalClient, versionedInformers); lastErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -559,35 +550,6 @@ func buildGenericConfig(
|
||||
return
|
||||
}
|
||||
|
||||
// BuildAuthenticator constructs the authenticator
|
||||
func BuildAuthenticator(s *options.ServerRunOptions, EgressSelector *egressselector.EgressSelector, extclient clientgoclientset.Interface, versionedInformer clientgoinformers.SharedInformerFactory) (authenticator.Request, *spec.SecurityDefinitions, error) {
|
||||
authenticatorConfig, err := s.Authentication.ToAuthenticationConfig()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if s.Authentication.ServiceAccounts.Lookup || utilfeature.DefaultFeatureGate.Enabled(features.TokenRequest) {
|
||||
authenticatorConfig.ServiceAccountTokenGetter = serviceaccountcontroller.NewGetterFromClient(
|
||||
extclient,
|
||||
versionedInformer.Core().V1().Secrets().Lister(),
|
||||
versionedInformer.Core().V1().ServiceAccounts().Lister(),
|
||||
versionedInformer.Core().V1().Pods().Lister(),
|
||||
)
|
||||
}
|
||||
authenticatorConfig.BootstrapTokenAuthenticator = bootstrap.NewTokenAuthenticator(
|
||||
versionedInformer.Core().V1().Secrets().Lister().Secrets(v1.NamespaceSystem),
|
||||
)
|
||||
|
||||
if EgressSelector != nil {
|
||||
egressDialer, err := EgressSelector.Lookup(egressselector.Master.AsNetworkContext())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authenticatorConfig.CustomDial = egressDialer
|
||||
}
|
||||
|
||||
return authenticatorConfig.New()
|
||||
}
|
||||
|
||||
// BuildAuthorizer constructs the authorizer
|
||||
func BuildAuthorizer(s *options.ServerRunOptions, EgressSelector *egressselector.EgressSelector, versionedInformers clientgoinformers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) {
|
||||
authorizationConfig := s.Authorization.ToAuthorizationConfig(versionedInformers)
|
||||
|
||||
@@ -36,7 +36,8 @@ import (
|
||||
)
|
||||
|
||||
// BuildAuth creates an authenticator, an authorizer, and a matching authorizer attributes getter compatible with the kubelet's needs
|
||||
func BuildAuth(nodeName types.NodeName, client clientset.Interface, config kubeletconfig.KubeletConfiguration) (server.AuthInterface, error) {
|
||||
// It returns AuthInterface, a run method to start internal controllers (like cert reloading) and error.
|
||||
func BuildAuth(nodeName types.NodeName, client clientset.Interface, config kubeletconfig.KubeletConfiguration) (server.AuthInterface, func(<-chan struct{}), error) {
|
||||
// Get clients, if provided
|
||||
var (
|
||||
tokenClient authenticationclient.TokenReviewInterface
|
||||
@@ -47,47 +48,55 @@ func BuildAuth(nodeName types.NodeName, client clientset.Interface, config kubel
|
||||
sarClient = client.AuthorizationV1().SubjectAccessReviews()
|
||||
}
|
||||
|
||||
authenticator, err := BuildAuthn(tokenClient, config.Authentication)
|
||||
authenticator, runAuthenticatorCAReload, err := BuildAuthn(tokenClient, config.Authentication)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
attributes := server.NewNodeAuthorizerAttributesGetter(nodeName)
|
||||
|
||||
authorizer, err := BuildAuthz(sarClient, config.Authorization)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return server.NewKubeletAuth(authenticator, attributes, authorizer), nil
|
||||
return server.NewKubeletAuth(authenticator, attributes, authorizer), runAuthenticatorCAReload, nil
|
||||
}
|
||||
|
||||
// BuildAuthn creates an authenticator compatible with the kubelet's needs
|
||||
func BuildAuthn(client authenticationclient.TokenReviewInterface, authn kubeletconfig.KubeletAuthentication) (authenticator.Request, error) {
|
||||
var clientCertificateCAContentProvider authenticatorfactory.CAContentProvider
|
||||
func BuildAuthn(client authenticationclient.TokenReviewInterface, authn kubeletconfig.KubeletAuthentication) (authenticator.Request, func(<-chan struct{}), error) {
|
||||
var dynamicCAContentFromFile *dynamiccertificates.DynamicFileCAContent
|
||||
var err error
|
||||
if len(authn.X509.ClientCAFile) > 0 {
|
||||
clientCertificateCAContentProvider, err = dynamiccertificates.NewDynamicCAContentFromFile("client-ca-bundle", authn.X509.ClientCAFile)
|
||||
dynamicCAContentFromFile, err = dynamiccertificates.NewDynamicCAContentFromFile("client-ca-bundle", authn.X509.ClientCAFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
authenticatorConfig := authenticatorfactory.DelegatingAuthenticatorConfig{
|
||||
Anonymous: authn.Anonymous.Enabled,
|
||||
CacheTTL: authn.Webhook.CacheTTL.Duration,
|
||||
ClientCertificateCAContentProvider: clientCertificateCAContentProvider,
|
||||
ClientCertificateCAContentProvider: dynamicCAContentFromFile,
|
||||
}
|
||||
|
||||
if authn.Webhook.Enabled {
|
||||
if client == nil {
|
||||
return nil, errors.New("no client provided, cannot use webhook authentication")
|
||||
return nil, nil, errors.New("no client provided, cannot use webhook authentication")
|
||||
}
|
||||
authenticatorConfig.TokenAccessReviewClient = client
|
||||
}
|
||||
|
||||
authenticator, _, err := authenticatorConfig.New()
|
||||
return authenticator, err
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return authenticator, func(stopCh <-chan struct{}) {
|
||||
if dynamicCAContentFromFile != nil {
|
||||
go dynamicCAContentFromFile.Run(1, stopCh)
|
||||
}
|
||||
}, err
|
||||
}
|
||||
|
||||
// BuildAuthz creates an authorizer compatible with the kubelet's needs
|
||||
|
||||
@@ -599,11 +599,12 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, featureGate f
|
||||
}
|
||||
|
||||
if kubeDeps.Auth == nil {
|
||||
auth, err := BuildAuth(nodeName, kubeDeps.KubeClient, s.KubeletConfiguration)
|
||||
auth, runAuthenticatorCAReload, err := BuildAuth(nodeName, kubeDeps.KubeClient, s.KubeletConfiguration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
kubeDeps.Auth = auth
|
||||
runAuthenticatorCAReload(stopCh)
|
||||
}
|
||||
|
||||
var cgroupRoots []string
|
||||
|
||||
Reference in New Issue
Block a user