k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kube-controller-manager/app/certificates.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package app implements a server that runs a set of active 18 // components. This includes replication controllers, service endpoints and 19 // nodes. 20 package app 21 22 import ( 23 "context" 24 "fmt" 25 26 "k8s.io/controller-manager/controller" 27 "k8s.io/klog/v2" 28 "k8s.io/kubernetes/cmd/kube-controller-manager/names" 29 "k8s.io/kubernetes/pkg/controller/certificates/approver" 30 "k8s.io/kubernetes/pkg/controller/certificates/cleaner" 31 "k8s.io/kubernetes/pkg/controller/certificates/rootcacertpublisher" 32 "k8s.io/kubernetes/pkg/controller/certificates/signer" 33 csrsigningconfig "k8s.io/kubernetes/pkg/controller/certificates/signer/config" 34 ) 35 36 func newCertificateSigningRequestSigningControllerDescriptor() *ControllerDescriptor { 37 return &ControllerDescriptor{ 38 name: names.CertificateSigningRequestSigningController, 39 aliases: []string{"csrsigning"}, 40 initFunc: startCertificateSigningRequestSigningController, 41 } 42 } 43 44 func startCertificateSigningRequestSigningController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) { 45 logger := klog.FromContext(ctx) 46 missingSingleSigningFile := controllerContext.ComponentConfig.CSRSigningController.ClusterSigningCertFile == "" || controllerContext.ComponentConfig.CSRSigningController.ClusterSigningKeyFile == "" 47 if missingSingleSigningFile && !anySpecificFilesSet(controllerContext.ComponentConfig.CSRSigningController) { 48 logger.Info("Skipping CSR signer controller because no csr cert/key was specified") 49 return nil, false, nil 50 } 51 if !missingSingleSigningFile && anySpecificFilesSet(controllerContext.ComponentConfig.CSRSigningController) { 52 return nil, false, fmt.Errorf("cannot specify default and per controller certs at the same time") 53 } 54 55 c := controllerContext.ClientBuilder.ClientOrDie("certificate-controller") 56 csrInformer := controllerContext.InformerFactory.Certificates().V1().CertificateSigningRequests() 57 certTTL := controllerContext.ComponentConfig.CSRSigningController.ClusterSigningDuration.Duration 58 59 if kubeletServingSignerCertFile, kubeletServingSignerKeyFile := getKubeletServingSignerFiles(controllerContext.ComponentConfig.CSRSigningController); len(kubeletServingSignerCertFile) > 0 || len(kubeletServingSignerKeyFile) > 0 { 60 kubeletServingSigner, err := signer.NewKubeletServingCSRSigningController(ctx, c, csrInformer, kubeletServingSignerCertFile, kubeletServingSignerKeyFile, certTTL) 61 if err != nil { 62 return nil, false, fmt.Errorf("failed to start kubernetes.io/kubelet-serving certificate controller: %v", err) 63 } 64 go kubeletServingSigner.Run(ctx, 5) 65 } else { 66 logger.Info("Skipping CSR signer controller because specific files were specified for other signers and not this one", "controller", "kubernetes.io/kubelet-serving") 67 } 68 69 if kubeletClientSignerCertFile, kubeletClientSignerKeyFile := getKubeletClientSignerFiles(controllerContext.ComponentConfig.CSRSigningController); len(kubeletClientSignerCertFile) > 0 || len(kubeletClientSignerKeyFile) > 0 { 70 kubeletClientSigner, err := signer.NewKubeletClientCSRSigningController(ctx, c, csrInformer, kubeletClientSignerCertFile, kubeletClientSignerKeyFile, certTTL) 71 if err != nil { 72 return nil, false, fmt.Errorf("failed to start kubernetes.io/kube-apiserver-client-kubelet certificate controller: %v", err) 73 } 74 go kubeletClientSigner.Run(ctx, 5) 75 } else { 76 logger.Info("Skipping CSR signer controller because specific files were specified for other signers and not this one", "controller", "kubernetes.io/kube-apiserver-client-kubelet") 77 } 78 79 if kubeAPIServerSignerCertFile, kubeAPIServerSignerKeyFile := getKubeAPIServerClientSignerFiles(controllerContext.ComponentConfig.CSRSigningController); len(kubeAPIServerSignerCertFile) > 0 || len(kubeAPIServerSignerKeyFile) > 0 { 80 kubeAPIServerClientSigner, err := signer.NewKubeAPIServerClientCSRSigningController(ctx, c, csrInformer, kubeAPIServerSignerCertFile, kubeAPIServerSignerKeyFile, certTTL) 81 if err != nil { 82 return nil, false, fmt.Errorf("failed to start kubernetes.io/kube-apiserver-client certificate controller: %v", err) 83 } 84 go kubeAPIServerClientSigner.Run(ctx, 5) 85 } else { 86 logger.Info("Skipping CSR signer controller because specific files were specified for other signers and not this one", "controller", "kubernetes.io/kube-apiserver-client") 87 } 88 89 if legacyUnknownSignerCertFile, legacyUnknownSignerKeyFile := getLegacyUnknownSignerFiles(controllerContext.ComponentConfig.CSRSigningController); len(legacyUnknownSignerCertFile) > 0 || len(legacyUnknownSignerKeyFile) > 0 { 90 legacyUnknownSigner, err := signer.NewLegacyUnknownCSRSigningController(ctx, c, csrInformer, legacyUnknownSignerCertFile, legacyUnknownSignerKeyFile, certTTL) 91 if err != nil { 92 return nil, false, fmt.Errorf("failed to start kubernetes.io/legacy-unknown certificate controller: %v", err) 93 } 94 go legacyUnknownSigner.Run(ctx, 5) 95 } else { 96 logger.Info("Skipping CSR signer controller because specific files were specified for other signers and not this one", "controller", "kubernetes.io/legacy-unknown") 97 } 98 99 return nil, true, nil 100 } 101 102 func areKubeletServingSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool { 103 // if only one is specified, it will error later during construction 104 return len(config.KubeletServingSignerConfiguration.CertFile) > 0 || len(config.KubeletServingSignerConfiguration.KeyFile) > 0 105 } 106 func areKubeletClientSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool { 107 // if only one is specified, it will error later during construction 108 return len(config.KubeletClientSignerConfiguration.CertFile) > 0 || len(config.KubeletClientSignerConfiguration.KeyFile) > 0 109 } 110 111 func areKubeAPIServerClientSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool { 112 // if only one is specified, it will error later during construction 113 return len(config.KubeAPIServerClientSignerConfiguration.CertFile) > 0 || len(config.KubeAPIServerClientSignerConfiguration.KeyFile) > 0 114 } 115 116 func areLegacyUnknownSignerFilesSpecified(config csrsigningconfig.CSRSigningControllerConfiguration) bool { 117 // if only one is specified, it will error later during construction 118 return len(config.LegacyUnknownSignerConfiguration.CertFile) > 0 || len(config.LegacyUnknownSignerConfiguration.KeyFile) > 0 119 } 120 121 func anySpecificFilesSet(config csrsigningconfig.CSRSigningControllerConfiguration) bool { 122 return areKubeletServingSignerFilesSpecified(config) || 123 areKubeletClientSignerFilesSpecified(config) || 124 areKubeAPIServerClientSignerFilesSpecified(config) || 125 areLegacyUnknownSignerFilesSpecified(config) 126 } 127 128 func getKubeletServingSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) { 129 // 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. 130 if anySpecificFilesSet(config) { 131 return config.KubeletServingSignerConfiguration.CertFile, config.KubeletServingSignerConfiguration.KeyFile 132 } 133 return config.ClusterSigningCertFile, config.ClusterSigningKeyFile 134 } 135 136 func getKubeletClientSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) { 137 // 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. 138 if anySpecificFilesSet(config) { 139 return config.KubeletClientSignerConfiguration.CertFile, config.KubeletClientSignerConfiguration.KeyFile 140 } 141 return config.ClusterSigningCertFile, config.ClusterSigningKeyFile 142 } 143 144 func getKubeAPIServerClientSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) { 145 // 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. 146 if anySpecificFilesSet(config) { 147 return config.KubeAPIServerClientSignerConfiguration.CertFile, config.KubeAPIServerClientSignerConfiguration.KeyFile 148 } 149 return config.ClusterSigningCertFile, config.ClusterSigningKeyFile 150 } 151 152 func getLegacyUnknownSignerFiles(config csrsigningconfig.CSRSigningControllerConfiguration) (string, string) { 153 // 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. 154 if anySpecificFilesSet(config) { 155 return config.LegacyUnknownSignerConfiguration.CertFile, config.LegacyUnknownSignerConfiguration.KeyFile 156 } 157 return config.ClusterSigningCertFile, config.ClusterSigningKeyFile 158 } 159 160 func newCertificateSigningRequestApprovingControllerDescriptor() *ControllerDescriptor { 161 return &ControllerDescriptor{ 162 name: names.CertificateSigningRequestApprovingController, 163 aliases: []string{"csrapproving"}, 164 initFunc: startCertificateSigningRequestApprovingController, 165 } 166 } 167 func startCertificateSigningRequestApprovingController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) { 168 approver := approver.NewCSRApprovingController( 169 ctx, 170 controllerContext.ClientBuilder.ClientOrDie("certificate-controller"), 171 controllerContext.InformerFactory.Certificates().V1().CertificateSigningRequests(), 172 ) 173 go approver.Run(ctx, 5) 174 175 return nil, true, nil 176 } 177 178 func newCertificateSigningRequestCleanerControllerDescriptor() *ControllerDescriptor { 179 return &ControllerDescriptor{ 180 name: names.CertificateSigningRequestCleanerController, 181 aliases: []string{"csrcleaner"}, 182 initFunc: startCertificateSigningRequestCleanerController, 183 } 184 } 185 func startCertificateSigningRequestCleanerController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) { 186 cleaner := cleaner.NewCSRCleanerController( 187 controllerContext.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1().CertificateSigningRequests(), 188 controllerContext.InformerFactory.Certificates().V1().CertificateSigningRequests(), 189 ) 190 go cleaner.Run(ctx, 1) 191 return nil, true, nil 192 } 193 194 func newRootCACertificatePublisherControllerDescriptor() *ControllerDescriptor { 195 return &ControllerDescriptor{ 196 name: names.RootCACertificatePublisherController, 197 aliases: []string{"root-ca-cert-publisher"}, 198 initFunc: startRootCACertificatePublisherController, 199 } 200 } 201 202 func startRootCACertificatePublisherController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) { 203 var ( 204 rootCA []byte 205 err error 206 ) 207 if controllerContext.ComponentConfig.SAController.RootCAFile != "" { 208 if rootCA, err = readCA(controllerContext.ComponentConfig.SAController.RootCAFile); err != nil { 209 return nil, true, fmt.Errorf("error parsing root-ca-file at %s: %v", controllerContext.ComponentConfig.SAController.RootCAFile, err) 210 } 211 } else { 212 rootCA = controllerContext.ClientBuilder.ConfigOrDie("root-ca-cert-publisher").CAData 213 } 214 215 sac, err := rootcacertpublisher.NewPublisher( 216 controllerContext.InformerFactory.Core().V1().ConfigMaps(), 217 controllerContext.InformerFactory.Core().V1().Namespaces(), 218 controllerContext.ClientBuilder.ClientOrDie("root-ca-cert-publisher"), 219 rootCA, 220 ) 221 if err != nil { 222 return nil, true, fmt.Errorf("error creating root CA certificate publisher: %v", err) 223 } 224 go sac.Run(ctx, 1) 225 return nil, true, nil 226 }