前言
认证体系知识繁杂,因此需要较多的基础理论才能明白认证的一个基本逻辑。
1、非对称加密体系:这块是加密解密、认证的基本原理以及知识点。有了这些基本数学基础,才能明白具体为什么非对称加密可以做认证。相关知识点如下所示:
http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html
https://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
2、另外就是需要了解加密认证的基本协议规范。即使有了上面的加密解密理论知识,但是应用到实践当中,还是要有规范以及相关的约定。比如说公钥如何给到相关的机构,相关机构如何二次签发,签发的认证证书如何验证真实性等等。这块涉及到互联网的相关的知识点,用的比较多的是X.509协议,如下:
https://blog.csdn.net/blue0bird/article/details/78656536
3、有了这些协议密码之后,需要一些现成的工具来完成这些信息的生成以及证书的只做。openssl就是一个很好的工具。使用它来完成具体的证书生成操作。
4、生成后具体证书在https中的应用逻辑。其实非对称加密算法只能加解密数字,因此无法直接对较大的文本进行加密传输。所以https就是使用证书进行秘钥的传递,传递之后再用相关秘钥进行数据传输,进而保证传输信息保密。
https://www.runoob.com/w3cnote/https-ssl-intro.html
一、kubernetes需要的证书列表
kubeadm用于生成各个证书的重要代码段,他把各个证书的的生成封装成一个个的对象。然后放到我们subPhases中,上层的逻辑会挨个调用对象中的run函数。
74 func newCertSubPhases() []workflow.Phase {
75 subPhases := []workflow.Phase{}
76
77 // All subphase
78 allPhase := workflow.Phase{
79 Name: "all",
80 Short: "Generate all certificates",
81 InheritFlags: getCertPhaseFlags("all"),
82 RunAllSiblings: true,
83 }
84
85 subPhases = append(subPhases, allPhase)
86
87 // This loop assumes that GetDefaultCertList() always returns a list of
88 // certificate that is preceded by the CAs that sign them.
89 var lastCACert *certsphase.KubeadmCert
90 for _, cert := range certsphase.GetDefaultCertList() {
91 var phase workflow.Phase
92 if cert.CAName == "" {
93 phase = newCertSubPhase(cert, runCAPhase(cert))
94 lastCACert = cert
95 } else {
96 phase = newCertSubPhase(cert, runCertPhase(cert, lastCACert))
97 phase.LocalFlags = localFlags()
98 }
99 subPhases = append(subPhases, phase)
100 }
101
102 // SA creates the private/public key pair, which doesn't use x509 at all
103 saPhase := workflow.Phase{
104 Name: "sa",
105 Short: "Generate a private key for signing service account tokens along with its public key",
106 Long: saKeyLongDesc,
107 Run: runCertsSa,
108 InheritFlags: []string{options.CertificatesDir},
109 }
110
111 subPhases = append(subPhases, saPhase)
112
113 return subPhases
114 }
具体生成的相关证书逻辑。加上上面的SA。共同组成了kubernetes的所有证书。
208 func GetDefaultCertList() Certificates {
209 return Certificates{
210 &KubeadmCertRootCA, //根证书
211 &KubeadmCertAPIServer, // apiserver的认证证书
212 &KubeadmCertKubeletClient, // kublete clietn的证书
213 // Front Proxy certs
214 &KubeadmCertFrontProxyCA, //前置proxy的证书
215 &KubeadmCertFrontProxyClient, //前置proxy client的证书
216 // etcd certs
217 &KubeadmCertEtcdCA, // etcd 的认证文件
218 &KubeadmCertEtcdServer, // etcd服务的认证文件
219 &KubeadmCertEtcdPeer, // etcd之间交互的认证文件
220 &KubeadmCertEtcdHealthcheck, //etcd 健康监测的认证文件
221 &KubeadmCertEtcdAPIClient, //etcd提供给api 的客户端认证文件
222 }
223 }
二、各个证书的生成逻辑
2.1 KubeadmCertRootCA
相关的对象片段:
239 KubeadmCertRootCA = KubeadmCert{
240 Name: "ca",
241 LongName: "self-signed Kubernetes CA to provision identities for other Kubernetes components",
242 BaseName: kubeadmconstants.CACertAndKeyBaseName,
243 config: pkiutil.CertConfig{
244 Config: certutil.Config{
245 CommonName: "kubernetes",
246 },
247 },
248 }
2.2 KubeadmCertAPIServer
249 // KubeadmCertAPIServer is the definition of the cert used to serve the Kubernetes API.
250 KubeadmCertAPIServer = KubeadmCert{
251 Name: "apiserver",
252 LongName: "certificate for serving the Kubernetes API",
253 BaseName: kubeadmconstants.APIServerCertAndKeyBaseName,
254 CAName: "ca",
255 config: pkiutil.CertConfig{
256 Config: certutil.Config{
257 CommonName: kubeadmconstants.APIServerCertCommonName,
258 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
259 },
260 },
261 configMutators: []configMutatorsFunc{
262 makeAltNamesMutator(pkiutil.GetAPIServerAltNames),
263 },
264 }
2.3 KubeadmCertKubeletClient
265 // KubeadmCertKubeletClient is the definition of the cert used by the API server to access the kubelet.
266 KubeadmCertKubeletClient = KubeadmCert{
267 Name: "apiserver-kubelet-client",
268 LongName: "certificate for the API server to connect to kubelet",
269 BaseName: kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName,
270 CAName: "ca",
271 config: pkiutil.CertConfig{
272 Config: certutil.Config{
273 CommonName: kubeadmconstants.APIServerKubeletClientCertCommonName,
274 Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
275 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
276 },
277 },
278 }
2.4 KubeadmCertFrontProxyCA
280 // KubeadmCertFrontProxyCA is the definition of the CA used for the front end proxy.
281 KubeadmCertFrontProxyCA = KubeadmCert{
282 Name: "front-proxy-ca",
283 LongName: "self-signed CA to provision identities for front proxy",
284 BaseName: kubeadmconstants.FrontProxyCACertAndKeyBaseName,
285 config: pkiutil.CertConfig{
286 Config: certutil.Config{
287 CommonName: "front-proxy-ca",
288 },
289 },
290 }
2.5 KubeadmCertFrontProxyClient
293 KubeadmCertFrontProxyClient = KubeadmCert{
294 Name: "front-proxy-client",
295 BaseName: kubeadmconstants.FrontProxyClientCertAndKeyBaseName,
296 LongName: "certificate for the front proxy client",
297 CAName: "front-proxy-ca",
298 config: pkiutil.CertConfig{
299 Config: certutil.Config{
300 CommonName: kubeadmconstants.FrontProxyClientCertCommonName,
301 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
302 },
303 },
304 }
2.6 KubeadmCertEtcdCA
06 // KubeadmCertEtcdCA is the definition of the root CA used by the hosted etcd server.
307 KubeadmCertEtcdCA = KubeadmCert{
308 Name: "etcd-ca",
309 LongName: "self-signed CA to provision identities for etcd",
310 BaseName: kubeadmconstants.EtcdCACertAndKeyBaseName,
311 config: pkiutil.CertConfig{
312 Config: certutil.Config{
313 CommonName: "etcd-ca",
314 },
315 },
316 }
2.7 KubeadmCertEtcdServer
317 // KubeadmCertEtcdServer is the definition of the cert used to serve etcd to clients.
318 KubeadmCertEtcdServer = KubeadmCert{
319 Name: "etcd-server",
320 LongName: "certificate for serving etcd",
321 BaseName: kubeadmconstants.EtcdServerCertAndKeyBaseName,
322 CAName: "etcd-ca",
323 config: pkiutil.CertConfig{
324 Config: certutil.Config{
325 // TODO: etcd 3.2 introduced an undocumented requirement for ClientAuth usage on the
326 // server cert: https://github.com/coreos/etcd/issues/9785#issuecomment-396715692
327 // Once the upstream issue is resolved, this should be returned to only allowing
328 // ServerAuth usage.
329 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
330 },
331 },
332 configMutators: []configMutatorsFunc{
333 makeAltNamesMutator(pkiutil.GetEtcdAltNames),
334 setCommonNameToNodeName(),
335 },
336 }
2.8 KubeadmCertEtcdPeer
337 // KubeadmCertEtcdPeer is the definition of the cert used by etcd peers to access each other.
338 KubeadmCertEtcdPeer = KubeadmCert{
339 Name: "etcd-peer",
340 LongName: "certificate for etcd nodes to communicate with each other",
341 BaseName: kubeadmconstants.EtcdPeerCertAndKeyBaseName,
342 CAName: "etcd-ca",
343 config: pkiutil.CertConfig{
344 Config: certutil.Config{
345 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
346 },
347 },
348 configMutators: []configMutatorsFunc{
349 makeAltNamesMutator(pkiutil.GetEtcdPeerAltNames),
350 setCommonNameToNodeName(),
351 },
352 }
2.9 KubeadmCertEtcdHealthcheck
353 // KubeadmCertEtcdHealthcheck is the definition of the cert used by Kubernetes to check the health of the etcd server.
354 KubeadmCertEtcdHealthcheck = KubeadmCert{
355 Name: "etcd-healthcheck-client",
356 LongName: "certificate for liveness probes to healthcheck etcd",
357 BaseName: kubeadmconstants.EtcdHealthcheckClientCertAndKeyBaseName,
358 CAName: "etcd-ca",
359 config: pkiutil.CertConfig{
360 Config: certutil.Config{
361 CommonName: kubeadmconstants.EtcdHealthcheckClientCertCommonName,
362 Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
363 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
364 },
365 },
366 }
2.10 KubeadmCertEtcdAPIClient
367 // KubeadmCertEtcdAPIClient is the definition of the cert used by the API server to access etcd.
368 KubeadmCertEtcdAPIClient = KubeadmCert{
369 Name: "apiserver-etcd-client",
370 LongName: "certificate the apiserver uses to access etcd",
371 BaseName: kubeadmconstants.APIServerEtcdClientCertAndKeyBaseName,
372 CAName: "etcd-ca",
373 config: pkiutil.CertConfig{
374 Config: certutil.Config{
375 CommonName: kubeadmconstants.APIServerEtcdClientCertCommonName,
376 Organization: []string{kubeadmconstants.SystemPrivilegedGroup},
377 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
378 },
379 },
380 }
三、生成证书的实现函数
3.1 runCAPhase 生成CA证书
216 func runCAPhase(ca *certsphase.KubeadmCert) func(c workflow.RunData) error {
217 return func(c workflow.RunData) error {
218 data, ok := c.(InitData)
219 if !ok {
220 return errors.New("certs phase invoked with an invalid data struct")
221 }
222
223 // if using external etcd, skips etcd certificate authority generation
224 if data.Cfg().Etcd.External != nil && ca.Name == "etcd-ca" {
225 fmt.Printf("[certs] External etcd mode: Skipping %s certificate authority generation\n", ca.BaseName)
226 return nil
227 }
228
229 if _, err := pkiutil.TryLoadCertFromDisk(data.CertificateDir(), ca.BaseName); err == nil {
230 if _, err := pkiutil.TryLoadKeyFromDisk(data.CertificateDir(), ca.BaseName); err == nil {
231 fmt.Printf("[certs] Using existing %s certificate authority\n", ca.BaseName)
232 return nil
233 }
234 fmt.Printf("[certs] Using existing %s keyless certificate authority\n", ca.BaseName)
235 return nil
236 }
237
238 // if dryrunning, write certificates authority to a temporary folder (and defer restore to the path originally specified by the user)
239 cfg := data.Cfg()
240 cfg.CertificatesDir = data.CertificateWriteDir()
241 defer func() { cfg.CertificatesDir = data.CertificateDir() }()
242
243 // create the new certificate authority (or use existing)
244 return certsphase.CreateCACertAndKeyFiles(ca, cfg)
245 }
246 }
3.2 runCertPhase 生成其他证书
248 func runCertPhase(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert) func(c workflow.RunData) error {
249 return func(c workflow.RunData) error {
250 data, ok := c.(InitData)
251 if !ok {
252 return errors.New("certs phase invoked with an invalid data struct")
253 }
254
255 // if using external etcd, skips etcd certificates generation
256 if data.Cfg().Etcd.External != nil && cert.CAName == "etcd-ca" {
257 fmt.Printf("[certs] External etcd mode: Skipping %s certificate generation\n", cert.BaseName)
258 return nil
259 }
260
261 if certData, _, err := pkiutil.TryLoadCertAndKeyFromDisk(data.CertificateDir(), cert.BaseName); err == nil {
262 caCertData, err := pkiutil.TryLoadCertFromDisk(data.CertificateDir(), caCert.BaseName)
263 if err != nil {
264 return errors.Wrapf(err, "couldn't load CA certificate %s", caCert.Name)
265 }
266
267 if err := certData.CheckSignatureFrom(caCertData); err != nil {
268 return errors.Wrapf(err, "[certs] certificate %s not signed by CA certificate %s", cert.BaseName, caCert.BaseName)
269 }
270
271 fmt.Printf("[certs] Using existing %s certificate and key on disk\n", cert.BaseName)
272 return nil
273 }
274
275 if csrOnly {
276 fmt.Printf("[certs] Generating CSR for %s instead of certificate\n", cert.BaseName)
277 if csrDir == "" {
278 csrDir = data.CertificateWriteDir()
279 }
280
281 return certsphase.CreateCSR(cert, data.Cfg(), csrDir)
282 }
283
284 // if dryrunning, write certificates to a temporary folder (and defer restore to the path originally specified by the user)
285 cfg := data.Cfg()
286 cfg.CertificatesDir = data.CertificateWriteDir()
287 defer func() { cfg.CertificatesDir = data.CertificateDir() }()
288
289 // create the new certificate (or use existing)
290 return certsphase.CreateCertAndKeyFilesWithCA(cert, caCert, cfg)
291 }
292 }