From 54f5f6752aa198e50e1e7ad6f1381be1f571f327 Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Tue, 10 Apr 2018 11:22:30 -0700 Subject: [PATCH] kubelet: add configuration to optionally enable server tls bootstrap right now if the RotateKubeletServerCertificate feature is enabled, kubelet will bootstrap server tls. this is undesirable if the deployment is not or cannot run an approver to handle these certificate signing requests. --- pkg/kubelet/apis/kubeletconfig/helpers_test.go | 1 + pkg/kubelet/apis/kubeletconfig/types.go | 6 ++++++ pkg/kubelet/apis/kubeletconfig/v1beta1/types.go | 7 +++++++ .../apis/kubeletconfig/v1beta1/zz_generated.conversion.go | 2 ++ pkg/kubelet/apis/kubeletconfig/validation/BUILD | 2 ++ pkg/kubelet/apis/kubeletconfig/validation/validation.go | 5 +++++ pkg/kubelet/kubelet.go | 6 +++--- 7 files changed, 26 insertions(+), 3 deletions(-) diff --git a/pkg/kubelet/apis/kubeletconfig/helpers_test.go b/pkg/kubelet/apis/kubeletconfig/helpers_test.go index 6c8602b2272..90689fd0ba0 100644 --- a/pkg/kubelet/apis/kubeletconfig/helpers_test.go +++ b/pkg/kubelet/apis/kubeletconfig/helpers_test.go @@ -187,6 +187,7 @@ var ( "KubeReserved[*]", "KubeletCgroups", "MakeIPTablesUtilChains", + "ServerTLSBootstrap", "StaticPodURL", "StaticPodURLHeader[*][*]", "MaxOpenFiles", diff --git a/pkg/kubelet/apis/kubeletconfig/types.go b/pkg/kubelet/apis/kubeletconfig/types.go index b593c2c25d8..340d4017c69 100644 --- a/pkg/kubelet/apis/kubeletconfig/types.go +++ b/pkg/kubelet/apis/kubeletconfig/types.go @@ -81,6 +81,12 @@ type KubeletConfiguration struct { // TLSMinVersion is the minimum TLS version supported. // Values are from tls package constants (https://golang.org/pkg/crypto/tls/#pkg-constants). TLSMinVersion string + // serverTLSBootstrap enables server certificate bootstrap. Instead of self + // signing a serving certificate, the Kubelet will request a certificate from + // the certificates.k8s.io API. This requires an approver to approve the + // certificate signing requests. The RotateKubeletServerCertificate feature + // must be enabled. + ServerTLSBootstrap bool // authentication specifies how requests to the Kubelet's server are authenticated Authentication KubeletAuthentication // authorization specifies how requests to the Kubelet's server are authorized diff --git a/pkg/kubelet/apis/kubeletconfig/v1beta1/types.go b/pkg/kubelet/apis/kubeletconfig/v1beta1/types.go index fd46f3c9dff..38cc88e2106 100644 --- a/pkg/kubelet/apis/kubeletconfig/v1beta1/types.go +++ b/pkg/kubelet/apis/kubeletconfig/v1beta1/types.go @@ -107,6 +107,13 @@ type KubeletConfiguration struct { // Default: "" // +optional TLSMinVersion string `json:"tlsMinVersion,omitempty"` + // serverTLSBootstrap enables server certificate bootstrap. Instead of self + // signing a serving certificate, the Kubelet will request a certificate from + // the certificates.k8s.io API. This requires an approver to approve the + // certificate signing requests. The RotateKubeletServerCertificate feature + // must be enabled. + // Default: false + ServerTLSBootstrap bool `json:"serverTLSBootstrap,omitempty"` // authentication specifies how requests to the Kubelet's server are authenticated // Defaults: // anonymous: diff --git a/pkg/kubelet/apis/kubeletconfig/v1beta1/zz_generated.conversion.go b/pkg/kubelet/apis/kubeletconfig/v1beta1/zz_generated.conversion.go index cd758225a2a..15bae024a43 100644 --- a/pkg/kubelet/apis/kubeletconfig/v1beta1/zz_generated.conversion.go +++ b/pkg/kubelet/apis/kubeletconfig/v1beta1/zz_generated.conversion.go @@ -154,6 +154,7 @@ func autoConvert_v1beta1_KubeletConfiguration_To_kubeletconfig_KubeletConfigurat out.TLSPrivateKeyFile = in.TLSPrivateKeyFile out.TLSCipherSuites = *(*[]string)(unsafe.Pointer(&in.TLSCipherSuites)) out.TLSMinVersion = in.TLSMinVersion + out.ServerTLSBootstrap = in.ServerTLSBootstrap if err := Convert_v1beta1_KubeletAuthentication_To_kubeletconfig_KubeletAuthentication(&in.Authentication, &out.Authentication, s); err != nil { return err } @@ -275,6 +276,7 @@ func autoConvert_kubeletconfig_KubeletConfiguration_To_v1beta1_KubeletConfigurat out.TLSPrivateKeyFile = in.TLSPrivateKeyFile out.TLSCipherSuites = *(*[]string)(unsafe.Pointer(&in.TLSCipherSuites)) out.TLSMinVersion = in.TLSMinVersion + out.ServerTLSBootstrap = in.ServerTLSBootstrap if err := Convert_kubeletconfig_KubeletAuthentication_To_v1beta1_KubeletAuthentication(&in.Authentication, &out.Authentication, s); err != nil { return err } diff --git a/pkg/kubelet/apis/kubeletconfig/validation/BUILD b/pkg/kubelet/apis/kubeletconfig/validation/BUILD index 18fbe0afdf8..7fd457643ea 100644 --- a/pkg/kubelet/apis/kubeletconfig/validation/BUILD +++ b/pkg/kubelet/apis/kubeletconfig/validation/BUILD @@ -11,10 +11,12 @@ go_library( srcs = ["validation.go"], importpath = "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig/validation", deps = [ + "//pkg/features:go_default_library", "//pkg/kubelet/apis/kubeletconfig:go_default_library", "//pkg/kubelet/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library", + "//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library", ], ) diff --git a/pkg/kubelet/apis/kubeletconfig/validation/validation.go b/pkg/kubelet/apis/kubeletconfig/validation/validation.go index 3f3e354be82..e060ee46555 100644 --- a/pkg/kubelet/apis/kubeletconfig/validation/validation.go +++ b/pkg/kubelet/apis/kubeletconfig/validation/validation.go @@ -21,6 +21,8 @@ import ( utilerrors "k8s.io/apimachinery/pkg/util/errors" utilvalidation "k8s.io/apimachinery/pkg/util/validation" + utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) @@ -86,6 +88,9 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration) error if kc.RegistryPullQPS < 0 { allErrors = append(allErrors, fmt.Errorf("invalid configuration: RegistryPullQPS (--registry-qps) %v must not be a negative number", kc.RegistryPullQPS)) } + if kc.ServerTLSBootstrap && !utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) { + allErrors = append(allErrors, fmt.Errorf("invalid configuration: ServerTLSBootstrap %v requires feature gate RotateKubeletServerCertificate", kc.ServerTLSBootstrap)) + } for _, val := range kc.EnforceNodeAllocatable { switch val { case kubetypes.NodeAllocatableEnforcementKey: diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 9a1755ffe7f..af63413c80a 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -707,7 +707,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, klet.statusManager = status.NewManager(klet.kubeClient, klet.podManager, klet) - if utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) && kubeDeps.TLSOptions != nil { + if kubeCfg.ServerTLSBootstrap && kubeDeps.TLSOptions != nil && utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) { var ( ips []net.IP names []string @@ -1233,8 +1233,8 @@ func (kl *Kubelet) initializeModules() error { // Start the image manager. kl.imageManager.Start() - // Start the certificate manager. - if utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) { + // Start the certificate manager if it was enabled. + if kl.serverCertificateManager != nil { kl.serverCertificateManager.Start() }