Fix client-ca dynamic reload in apiserver

This commit is contained in:
Tomas Nozicka
2020-04-29 16:03:09 +02:00
parent 47daccb272
commit b22a170d46
8 changed files with 280 additions and 122 deletions

View File

@@ -14,6 +14,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/kubeapiserver/options",
visibility = ["//visibility:public"],
deps = [
"//pkg/controller/serviceaccount:go_default_library",
"//pkg/features:go_default_library",
"//pkg/kubeapiserver/authenticator:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library",
@@ -50,6 +51,8 @@ go_library(
"//plugin/pkg/admission/storage/persistentvolume/resize:go_default_library",
"//plugin/pkg/admission/storage/storageclass/setdefault:go_default_library",
"//plugin/pkg/admission/storage/storageobjectinuseprotection:go_default_library",
"//plugin/pkg/auth/authenticator/token/bootstrap:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
@@ -58,14 +61,17 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/server/options:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/component-base/cli/flag:go_default_library",
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/common:go_default_library",
],
)

View File

@@ -24,17 +24,24 @@ import (
"time"
"github.com/spf13/pflag"
"k8s.io/klog"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/authenticator"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/egressselector"
genericoptions "k8s.io/apiserver/pkg/server/options"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
openapicommon "k8s.io/kube-openapi/pkg/common"
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/features"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap"
)
type BuiltInAuthenticationOptions struct {
@@ -406,35 +413,60 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() (kubeauthenticat
return ret, nil
}
func (o *BuiltInAuthenticationOptions) ApplyTo(c *genericapiserver.Config) error {
// ApplyTo requires already applied OpenAPIConfig and EgressSelector if present.
func (o *BuiltInAuthenticationOptions) ApplyTo(authInfo *genericapiserver.AuthenticationInfo, secureServing *genericapiserver.SecureServingInfo, egressSelector *egressselector.EgressSelector, openAPIConfig *openapicommon.Config, extclient kubernetes.Interface, versionedInformer informers.SharedInformerFactory) error {
if o == nil {
return nil
}
if o.ClientCert != nil {
clientCertificateCAContentProvider, err := o.ClientCert.GetClientCAContentProvider()
if err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
if err = c.Authentication.ApplyClientCert(clientCertificateCAContentProvider, c.SecureServing); err != nil {
if openAPIConfig == nil {
return errors.New("uninitialized OpenAPIConfig")
}
authenticatorConfig, err := o.ToAuthenticationConfig()
if err != nil {
return err
}
if authenticatorConfig.ClientCAContentProvider != nil {
if err = authInfo.ApplyClientCert(authenticatorConfig.ClientCAContentProvider, secureServing); err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
}
if o.RequestHeader != nil {
requestHeaderConfig, err := o.RequestHeader.ToAuthenticationRequestHeaderConfig()
if err != nil {
return fmt.Errorf("unable to create request header authentication config: %v", err)
}
if requestHeaderConfig != nil {
if err = c.Authentication.ApplyClientCert(requestHeaderConfig.CAContentProvider, c.SecureServing); err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
if authenticatorConfig.RequestHeaderConfig != nil && authenticatorConfig.RequestHeaderConfig.CAContentProvider != nil {
if err = authInfo.ApplyClientCert(authenticatorConfig.RequestHeaderConfig.CAContentProvider, secureServing); err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
}
c.Authentication.APIAudiences = o.APIAudiences
authInfo.APIAudiences = o.APIAudiences
if o.ServiceAccounts != nil && o.ServiceAccounts.Issuer != "" && len(o.APIAudiences) == 0 {
c.Authentication.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer}
authInfo.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer}
}
if o.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(metav1.NamespaceSystem),
)
if egressSelector != nil {
egressDialer, err := egressSelector.Lookup(egressselector.Master.AsNetworkContext())
if err != nil {
return err
}
authenticatorConfig.CustomDial = egressDialer
}
authInfo.Authenticator, openAPIConfig.SecurityDefinitions, err = authenticatorConfig.New()
if err != nil {
return err
}
return nil