Skip to content

Commit 05f6812

Browse files
authored
Merge pull request kubernetes#90822 from deads2k/csr-separate-signer-flags-02
allow setting different certificates for kube-controller-managed CSR signers
2 parents 242f3d9 + 1233a6f commit 05f6812

File tree

12 files changed

+652
-82
lines changed

12 files changed

+652
-82
lines changed

api/api-rules/violation_exceptions.list

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,15 @@ API rule violation: names_match,k8s.io/apimachinery/pkg/util/intstr,IntOrString,
472472
API rule violation: names_match,k8s.io/apimachinery/pkg/util/intstr,IntOrString,Type
473473
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,AttachDetachControllerConfiguration,DisableAttachDetachReconcilerSync
474474
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,AttachDetachControllerConfiguration,ReconcilerSyncLoopPeriod
475+
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningConfiguration,CertFile
476+
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningConfiguration,KeyFile
475477
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,ClusterSigningCertFile
476478
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,ClusterSigningDuration
477479
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,ClusterSigningKeyFile
480+
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,KubeAPIServerClientSignerConfiguration
481+
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,KubeletClientSignerConfiguration
482+
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,KubeletServingSignerConfiguration
483+
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CSRSigningControllerConfiguration,LegacyUnknownSignerConfiguration
478484
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CloudProviderConfiguration,CloudConfigFile
479485
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,CloudProviderConfiguration,Name
480486
API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,DaemonSetControllerConfiguration,ConcurrentDaemonSetSyncs

cmd/kube-controller-manager/app/BUILD

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,13 @@ go_library(
160160

161161
go_test(
162162
name = "go_default_test",
163-
srcs = ["core_test.go"],
163+
srcs = [
164+
"certificates_test.go",
165+
"core_test.go",
166+
],
164167
embed = [":go_default_library"],
165168
deps = [
169+
"//pkg/controller/certificates/signer/config:go_default_library",
166170
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
167171
"//staging/src/k8s.io/client-go/discovery:go_default_library",
168172
"//staging/src/k8s.io/client-go/discovery/fake:go_default_library",

cmd/kube-controller-manager/app/certificates.go

Lines changed: 102 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,11 @@ package app
2222

2323
import (
2424
"fmt"
25-
"os"
26-
2725
"net/http"
2826

2927
"k8s.io/apimachinery/pkg/runtime/schema"
3028
utilfeature "k8s.io/apiserver/pkg/util/feature"
3129
"k8s.io/klog/v2"
32-
kubeoptions "k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
3330
"k8s.io/kubernetes/pkg/controller/certificates/approver"
3431
"k8s.io/kubernetes/pkg/controller/certificates/cleaner"
3532
"k8s.io/kubernetes/pkg/controller/certificates/rootcacertpublisher"
@@ -44,87 +41,129 @@ func startCSRSigningController(ctx ControllerContext) (http.Handler, bool, error
4441
klog.Warningf("Resource %s is not available now", gvr.String())
4542
return nil, false, nil
4643
}
47-
if ctx.ComponentConfig.CSRSigningController.ClusterSigningCertFile == "" || ctx.ComponentConfig.CSRSigningController.ClusterSigningKeyFile == "" {
44+
missingSingleSigningFile := ctx.ComponentConfig.CSRSigningController.ClusterSigningCertFile == "" || ctx.ComponentConfig.CSRSigningController.ClusterSigningKeyFile == ""
45+
if missingSingleSigningFile && !anySpecificFilesSet(ctx.ComponentConfig.CSRSigningController) {
4846
klog.V(2).Info("skipping CSR signer controller because no csr cert/key was specified")
4947
return nil, false, nil
5048
}
51-
52-
// Deprecation warning for old defaults.
53-
//
54-
// * If the signing cert and key are the default paths but the files
55-
// exist, warn that the paths need to be specified explicitly in a
56-
// later release and the defaults will be removed. We don't expect this
57-
// to be the case.
58-
//
59-
// * If the signing cert and key are default paths but the files don't exist,
60-
// bail out of startController without logging.
61-
var keyFileExists, keyUsesDefault, certFileExists, certUsesDefault bool
62-
63-
_, err := os.Stat(ctx.ComponentConfig.CSRSigningController.ClusterSigningCertFile)
64-
certFileExists = !os.IsNotExist(err)
65-
66-
certUsesDefault = (ctx.ComponentConfig.CSRSigningController.ClusterSigningCertFile == kubeoptions.DefaultClusterSigningCertFile)
67-
68-
_, err = os.Stat(ctx.ComponentConfig.CSRSigningController.ClusterSigningKeyFile)
69-
keyFileExists = !os.IsNotExist(err)
70-
71-
keyUsesDefault = (ctx.ComponentConfig.CSRSigningController.ClusterSigningKeyFile == kubeoptions.DefaultClusterSigningKeyFile)
72-
73-
switch {
74-
case (keyFileExists && keyUsesDefault) || (certFileExists && certUsesDefault):
75-
klog.Warningf("You might be using flag defaulting for --cluster-signing-cert-file and" +
76-
" --cluster-signing-key-file. These defaults are deprecated and will be removed" +
77-
" in a subsequent release. Please pass these options explicitly.")
78-
case (!keyFileExists && keyUsesDefault) && (!certFileExists && certUsesDefault):
79-
// This is what we expect right now if people aren't
80-
// setting up the signing controller. This isn't
81-
// actually a problem since the signer is not a
82-
// required controller.
83-
klog.V(2).Info("skipping CSR signer controller because no csr cert/key was specified and the default files are missing")
84-
return nil, false, nil
85-
default:
86-
// Note that '!filesExist && !usesDefaults' is obviously
87-
// operator error. We don't handle this case here and instead
88-
// allow it to be handled by NewCSR... below.
49+
if !missingSingleSigningFile && anySpecificFilesSet(ctx.ComponentConfig.CSRSigningController) {
50+
return nil, false, fmt.Errorf("cannot specify default and per controller certs at the same time")
8951
}
9052

9153
c := ctx.ClientBuilder.ClientOrDie("certificate-controller")
9254
csrInformer := ctx.InformerFactory.Certificates().V1().CertificateSigningRequests()
9355
certTTL := ctx.ComponentConfig.CSRSigningController.ClusterSigningDuration.Duration
94-
caFile, caKeyFile := getKubeletServingSignerFiles(ctx.ComponentConfig.CSRSigningController)
9556

96-
// TODO get different signer cert and key files for each signer when we add flags.
97-
98-
kubeletServingSigner, err := signer.NewKubeletServingCSRSigningController(c, csrInformer, caFile, caKeyFile, certTTL)
99-
if err != nil {
100-
return nil, false, fmt.Errorf("failed to start kubernetes.io/kubelet-serving certificate controller: %v", err)
57+
if kubeletServingSignerCertFile, kubeletServingSignerKeyFile := getKubeletServingSignerFiles(ctx.ComponentConfig.CSRSigningController); len(kubeletServingSignerCertFile) > 0 || len(kubeletServingSignerKeyFile) > 0 {
58+
kubeletServingSigner, err := signer.NewKubeletServingCSRSigningController(c, csrInformer, kubeletServingSignerCertFile, kubeletServingSignerKeyFile, certTTL)
59+
if err != nil {
60+
return nil, false, fmt.Errorf("failed to start kubernetes.io/kubelet-serving certificate controller: %v", err)
61+
}
62+
go kubeletServingSigner.Run(1, ctx.Stop)
63+
} else {
64+
klog.V(2).Infof("skipping CSR signer controller %q because specific files were specified for other signers and not this one.", "kubernetes.io/kubelet-serving")
10165
}
102-
go kubeletServingSigner.Run(1, ctx.Stop)
10366

104-
kubeletClientSigner, err := signer.NewKubeletClientCSRSigningController(c, csrInformer, caFile, caKeyFile, certTTL)
105-
if err != nil {
106-
return nil, false, fmt.Errorf("failed to start kubernetes.io/kube-apiserver-client-kubelet certificate controller: %v", err)
67+
if kubeletClientSignerCertFile, kubeletClientSignerKeyFile := getKubeletClientSignerFiles(ctx.ComponentConfig.CSRSigningController); len(kubeletClientSignerCertFile) > 0 || len(kubeletClientSignerKeyFile) > 0 {
68+
kubeletClientSigner, err := signer.NewKubeletClientCSRSigningController(c, csrInformer, kubeletClientSignerCertFile, kubeletClientSignerKeyFile, certTTL)
69+
if err != nil {
70+
return nil, false, fmt.Errorf("failed to start kubernetes.io/kube-apiserver-client-kubelet certificate controller: %v", err)
71+
}
72+
go kubeletClientSigner.Run(1, ctx.Stop)
73+
} else {
74+
klog.V(2).Infof("skipping CSR signer controller %q because specific files were specified for other signers and not this one.", "kubernetes.io/kube-apiserver-client-kubelet")
10775
}
108-
go kubeletClientSigner.Run(1, ctx.Stop)
10976

110-
kubeAPIServerClientSigner, err := signer.NewKubeAPIServerClientCSRSigningController(c, csrInformer, caFile, caKeyFile, certTTL)
111-
if err != nil {
112-
return nil, false, fmt.Errorf("failed to start kubernetes.io/kube-apiserver-client certificate controller: %v", err)
77+
if kubeAPIServerSignerCertFile, kubeAPIServerSignerKeyFile := getKubeAPIServerClientSignerFiles(ctx.ComponentConfig.CSRSigningController); len(kubeAPIServerSignerCertFile) > 0 || len(kubeAPIServerSignerKeyFile) > 0 {
78+
kubeAPIServerClientSigner, err := signer.NewKubeAPIServerClientCSRSigningController(c, csrInformer, kubeAPIServerSignerCertFile, kubeAPIServerSignerKeyFile, certTTL)
79+
if err != nil {
80+
return nil, false, fmt.Errorf("failed to start kubernetes.io/kube-apiserver-client certificate controller: %v", err)
81+
}
82+
go kubeAPIServerClientSigner.Run(1, ctx.Stop)
83+
} else {
84+
klog.V(2).Infof("skipping CSR signer controller %q because specific files were specified for other signers and not this one.", "kubernetes.io/kube-apiserver-client")
11385
}
114-
go kubeAPIServerClientSigner.Run(1, ctx.Stop)
11586

116-
legacyUnknownSigner, err := signer.NewLegacyUnknownCSRSigningController(c, csrInformer, caFile, caKeyFile, certTTL)
117-
if err != nil {
118-
return nil, false, fmt.Errorf("failed to start kubernetes.io/legacy-unknown certificate controller: %v", err)
87+
if legacyUnknownSignerCertFile, legacyUnknownSignerKeyFile := getLegacyUnknownSignerFiles(ctx.ComponentConfig.CSRSigningController); len(legacyUnknownSignerCertFile) > 0 || len(legacyUnknownSignerKeyFile) > 0 {
88+
legacyUnknownSigner, err := signer.NewLegacyUnknownCSRSigningController(c, csrInformer, legacyUnknownSignerCertFile, legacyUnknownSignerKeyFile, certTTL)
89+
if err != nil {
90+
return nil, false, fmt.Errorf("failed to start kubernetes.io/legacy-unknown certificate controller: %v", err)
91+
}
92+
go legacyUnknownSigner.Run(1, ctx.Stop)
93+
} else {
94+
klog.V(2).Infof("skipping CSR signer controller %q because specific files were specified for other signers and not this one.", "kubernetes.io/legacy-unknown")
11995
}
120-
go legacyUnknownSigner.Run(1, ctx.Stop)
12196

12297
return nil, true, nil
12398
}
12499

125-
// getKubeletServingSignerFiles returns the cert and key for signing.
126-
// TODO we will extended this for each signer so that it prefers the specific flag (to be added) and falls back to the single flag
100+
func areKubeletServingSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool {
101+
if len(config.KubeletServingSignerConfiguration.CertFile) > 0 || len(config.KubeletServingSignerConfiguration.KeyFile) > 0 {
102+
// if only one is specified, it will error later during construction
103+
return true
104+
}
105+
return false
106+
}
107+
func areKubeletClientSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool {
108+
if len(config.KubeletClientSignerConfiguration.CertFile) > 0 || len(config.KubeletClientSignerConfiguration.KeyFile) > 0 {
109+
// if only one is specified, it will error later during construction
110+
return true
111+
}
112+
return false
113+
}
114+
115+
func areKubeAPIServerClientSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool {
116+
if len(config.KubeAPIServerClientSignerConfiguration.CertFile) > 0 || len(config.KubeAPIServerClientSignerConfiguration.KeyFile) > 0 {
117+
// if only one is specified, it will error later during construction
118+
return true
119+
}
120+
return false
121+
}
122+
123+
func areLegacyUnknownSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool {
124+
if len(config.LegacyUnknownSignerConfiguration.CertFile) > 0 || len(config.LegacyUnknownSignerConfiguration.KeyFile) > 0 {
125+
// if only one is specified, it will error later during construction
126+
return true
127+
}
128+
return false
129+
}
130+
131+
func anySpecificFilesSet(config csrsigningconfig.CSRSigningControllerConfiguration) bool {
132+
return areKubeletServingSignerFilesSpecified(config) ||
133+
areKubeletClientSignerFilesSpecified(config) ||
134+
areKubeAPIServerClientSignerFilesSpecified(config) ||
135+
areLegacyUnknownSignerFilesSpecified(config)
136+
}
137+
127138
func getKubeletServingSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) {
139+
// if any cert/key is set for specific CSR signing loops, then the --cluster-signing-{cert,key}-file are not used for any CSR signing loop.
140+
if anySpecificFilesSet(config) {
141+
return config.KubeletServingSignerConfiguration.CertFile, config.KubeletServingSignerConfiguration.KeyFile
142+
}
143+
return config.ClusterSigningCertFile, config.ClusterSigningKeyFile
144+
}
145+
146+
func getKubeletClientSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) {
147+
// if any cert/key is set for specific CSR signing loops, then the --cluster-signing-{cert,key}-file are not used for any CSR signing loop.
148+
if anySpecificFilesSet(config) {
149+
return config.KubeletClientSignerConfiguration.CertFile, config.KubeletClientSignerConfiguration.KeyFile
150+
}
151+
return config.ClusterSigningCertFile, config.ClusterSigningKeyFile
152+
}
153+
154+
func getKubeAPIServerClientSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) {
155+
// if any cert/key is set for specific CSR signing loops, then the --cluster-signing-{cert,key}-file are not used for any CSR signing loop.
156+
if anySpecificFilesSet(config) {
157+
return config.KubeAPIServerClientSignerConfiguration.CertFile, config.KubeAPIServerClientSignerConfiguration.KeyFile
158+
}
159+
return config.ClusterSigningCertFile, config.ClusterSigningKeyFile
160+
}
161+
162+
func getLegacyUnknownSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) {
163+
// if any cert/key is set for specific CSR signing loops, then the --cluster-signing-{cert,key}-file are not used for any CSR signing loop.
164+
if anySpecificFilesSet(config) {
165+
return config.LegacyUnknownSignerConfiguration.CertFile, config.LegacyUnknownSignerConfiguration.KeyFile
166+
}
128167
return config.ClusterSigningCertFile, config.ClusterSigningKeyFile
129168
}
130169

0 commit comments

Comments
 (0)