@@ -225,28 +225,11 @@ A CSR represents a request to a CA for a signed certificate for a client.
225
225
In kubeadm terms, any certificate that would normally be signed by an on-disk CA can be produced
226
226
as a CSR instead. A CA, however, cannot be produced as a CSR.
227
227
228
- # ## Create certificate signing requests (CSR)
229
-
230
- You can create certificate signing requests with `kubeadm certs renew --csr-only`.
231
-
232
- Both the CSR and the accompanying private key are given in the output.
233
- You can pass in a directory with `--csr-dir` to output the CSRs to the specified location.
234
- If `--csr-dir` is not specified, the default certificate directory (`/etc/kubernetes/pki`) is used.
235
-
236
- Certificates can be renewed with `kubeadm certs renew --csr-only`.
237
- As with `kubeadm init`, an output directory can be specified with the `--csr-dir` flag.
238
-
239
- A CSR contains a certificate's name, domains, and IPs, but it does not specify usages.
240
- It is the responsibility of the CA to specify [the correct cert usages](/docs/setup/best-practices/certificates/#all-certificates)
241
- when issuing a certificate.
228
+ # ## Renewal by using certificate signing requests (CSR)
242
229
243
- * In `openssl` this is done with the
244
- [`openssl ca` command](https://superuser.com/questions/738612/openssl-ca-keyusage-extension).
245
- * In `cfssl` you specify
246
- [usages in the config file](https://github.com/cloudflare/cfssl/blob/master/doc/cmd/cfssl.txt#L170).
247
-
248
- After a certificate is signed using your preferred method, the certificate and the private key
249
- must be copied to the PKI directory (by default `/etc/kubernetes/pki`).
230
+ Renewal of ceritficates is possible by generating new CSRs and signing them with the external CA.
231
+ For more details about working with CSRs generated by kubeadm see the section
232
+ [Signing certificate signing requests (CSR) generated by kubeadm](#signing-csr).
250
233
251
234
# # Certificate authority (CA) rotation {#certificate-authority-rotation}
252
235
@@ -373,3 +356,246 @@ The following example will generate a kubeconfig file with administrator credent
373
356
` ` ` shell
374
357
kubeadm kubeconfig user --config example.yaml --client-name admin --validity-period 168h
375
358
` ` `
359
+
360
+ # # Signing certificate signing requests (CSR) generated by kubeadm {#signing-csr}
361
+
362
+ You can create certificate signing requests with `kubeadm certs generate-csr`.
363
+ Calling this command will generate `.csr` / `.key` file pairs for regular
364
+ certificates. For certificates embedded in kubeconfig files, the command will
365
+ generate a `.csr` / `.conf` pair where the key is already embedded in the `.conf` file.
366
+
367
+ A CSR file contains all relevant information for a CA to sign a certificate.
368
+ kubeadm uses a
369
+ [well defined specification](/docs/setup/best-practices/certificates/#all-certificates)
370
+ for all its certificates and CSRs.
371
+
372
+ The default certificate directory is `/etc/kubernetes/pki`, while the default
373
+ directory for kubeconfig files is `/etc/kubernetes`. These defaults can be
374
+ overridden with the flags `--cert-dir` and `--kubeconfig-dir`, respectively.
375
+
376
+ To pass custom options to `kubeadm certs generate-csr` use the `--config` flag,
377
+ which accepts a [kubeadm configuration](/docs/reference/config-api/kubeadm-config.v1beta3/)
378
+ file, similarly to commands such as `kubeadm init`. Any specification such
379
+ as extra SANs and custom IP addresses must be stored in the same configuration
380
+ file and used for all relevant kubeadm commands by passing it as `--config`.
381
+
382
+ {{< note >}}
383
+ This guide will cover the usage of the `openssl` command for singing the CSRs,
384
+ but you can use your preferred tools.
385
+ {{< /note >}}
386
+
387
+ {{< note >}}
388
+ This guide will use the default Kubernetes directory `/etc/kubernetes`, which requires
389
+ a super user. If you are following this guide with permissive directories
390
+ (by passing `--cert-dir` and `--kubeconfig-dir`) you can omit the `sudo` command).
391
+ But note that the resulted files must be copied to the `/etc/kubernetes` tree,
392
+ so that `kubeadm init` or `kubeadm join` will find them.
393
+ {{< /note >}}
394
+
395
+ # ## Preparing CA and service account files
396
+
397
+ On the primary control plane node, where `kubeadm init` will be executed, call the following
398
+ commands :
399
+
400
+ ` ` ` shell
401
+ sudo kubeadm init phase certs ca
402
+ sudo kubeadm init phase certs etcd-ca
403
+ sudo kubeadm init phase certs front-proxy-ca
404
+ sudo kubeadm init phase certs sa
405
+ ` ` `
406
+
407
+ This will populate the folders `/etc/kubernetes/pki` and `/etc/kubernetes/pki/etcd`
408
+ with all self-signed CA files (certificates and keys) and service account (public and
409
+ private keys) that kubeadm needs for a control plane node.
410
+
411
+ {{< note >}}
412
+ If you are using an external CA, you must generate the same files out of band and manually
413
+ copy them to the primary control plane node in `/etc/kubernetes`. Once all CSRs
414
+ are signed, you can delete the root CA key (`ca.key`) as noted in the
415
+ [External CA mode](#external-ca-mode) section.
416
+ {{< /note >}}
417
+
418
+ For secondary control plane nodes (`kubeadm join --control-plane`) there is no need to call
419
+ the above commands. Depending on how you setup the
420
+ [High Availability](/docs/setup/production-environment/tools/kubeadm/high-availability)
421
+ cluster, you either have to manually copy the same files from the primary
422
+ control plane node, or use the automated `--upload-certs` functionality of `kubeadm init`.
423
+
424
+ # ## Generate CSRs
425
+
426
+ The `kubeadm certs generate-csr` command generates CSRs for all known certificates
427
+ managed by kubeadm. Once the command is done you must manually delete `.csr`, `.conf`
428
+ or `.key` files that you don't need.
429
+
430
+ # ### Considerations for kubelet.conf {#considerations-kubelet-conf}
431
+
432
+ This section applies to both control plane and worker nodes.
433
+
434
+ If you have deleted the `ca.key` file from control plane nodes
435
+ ([External CA mode](#external-ca-mode)), the active kube-controller-manager in
436
+ this cluster will not be able to sign kubelet client certificates. If no external
437
+ method for signing these certificates exists in your setup (such as an
438
+ [external signer](#set-up-a-signer), you could manually sign the `kubelet.conf.csr`
439
+ as explained in this guide.
440
+
441
+ Note that this also means that the automatic
442
+ [kubelet client certificate rotation](/docs/tasks/tls/certificate-rotation/#enabling-client-certificate-rotation)
443
+ will be disabled. If so, close to certificate expiration, you must generate
444
+ a new `kubelet.conf.csr`, sign the certificate, embed it in `kubelet.conf`
445
+ and restart the kubelet.
446
+
447
+ If this does not apply to your setup, you can skip processing the `kubelet.conf.csr`
448
+ on secondary control plane and on workers nodes (all nodes tha call `kubeadm join ...`).
449
+ That is because the active kube-controller-manager will be responsible
450
+ for signing new kubelet client certificates.
451
+
452
+ {{< note >}}
453
+ Processing the `kubelet.conf.csr` on the primary control plane node
454
+ (`kubeadm init`) is required, because that is considered the node that
455
+ bootstraps the cluster and a pre-populated `kubelet.conf` is needed.
456
+ {{< /note >}}
457
+
458
+ # ### Control plane nodes
459
+
460
+ Execute the following command on primary (`kubeadm init`) and secondary
461
+ (`kubeadm join --control-plane`) control plane nodes to generate all CSR files :
462
+
463
+ ` ` ` shell
464
+ sudo kubeadm certs generate-csr
465
+ ` ` `
466
+
467
+ If external etcd is to be used, follow the
468
+ [External etcd with kubeadm](docs/setup/production-environment/tools/kubeadm/high-availability/#external-etcd-nodes)
469
+ guide to understand what CSR files are needed on the kubeadm and etcd nodes. Other
470
+ ` .csr` and `.key` files under `/etc/kubernetes/pki/etcd` can be removed.
471
+
472
+ Based on the explanation in
473
+ [Considerations for kubelet.conf](#considerations-kubelet-conf) keep or delete
474
+ the `kubelet.conf` and `kubelet.conf.csr` files.
475
+
476
+ # ### Worker nodes
477
+
478
+ Based on the explanation in
479
+ [Considerations for kubelet.conf](#considerations-kubelet-conf), optionally call:
480
+
481
+ ` ` ` shell
482
+ sudo kubeadm certs generate-csr
483
+ ` ` `
484
+
485
+ and keep only the `kubelet.conf` and `kubelet.conf.csr` files. Alternatively skip
486
+ the steps for worker nodes entirely.
487
+
488
+ # ## Signing CSRs for all certificates
489
+
490
+ {{< note >}}
491
+ If you are using external CA and already have CA serial number files (`.srl`) for
492
+ ` openssl` you can copy such files to a kubeadm node where CSRs will be processed.
493
+ ` .srl` files to copy are `/etc/kubernetes/pki/ca.srl`,
494
+ ` /etc/kubernetes/pki/front-proxy-ca.srl` and `/etc/kubernetes/pki/etcd/ca.srl`.
495
+ The files can be then moved to a new node where CSR files will be processed.
496
+
497
+ If a `.srl` file is missing for a CA on a node, the script below will generate a new SRL file
498
+ with a random starting serial number.
499
+
500
+ To read more about `.srl` files see the
501
+ [`openssl`](https://www.openssl.org/docs/man3.0/man1/openssl-x509.html)
502
+ documentation for the `--CAserial` flag.
503
+ {{< /note >}}
504
+
505
+ Repeat this step for all nodes that have CSR files.
506
+
507
+ Write the following script in the `/etc/kubernetes` directory, navigate to the directory
508
+ and execute the script. The script will generate certificates for all CSR files that are
509
+ present in the `/etc/kubernetes` tree.
510
+
511
+ ` ` ` bash
512
+ #!/bin/bash
513
+
514
+ # Set certificate expiration time in days
515
+ DAYS=365
516
+
517
+ # Process all CSR files except those for front-proxy and etcd
518
+ find ./ -name "*.csr" | grep -v "pki/etcd" | grep -v "front-proxy" | while read -r FILE;
519
+ do
520
+ echo "* Processing ${FILE} ..."
521
+ FILE=${FILE%.*} # Trim the extension
522
+ if [ -f "./pki/ca.srl" ]; then
523
+ SERIAL_FLAG="-CAserial ./pki/ca.srl"
524
+ else
525
+ SERIAL_FLAG="-CAcreateserial"
526
+ fi
527
+ openssl x509 -req -days "${DAYS}" -CA ./pki/ca.crt -CAkey ./pki/ca.key ${SERIAL_FLAG} \
528
+ -in "${FILE}.csr" -out "${FILE}.crt"
529
+ sleep 2
530
+ done
531
+
532
+ # Process all etcd CSRs
533
+ find ./pki/etcd -name "*.csr" | while read -r FILE;
534
+ do
535
+ echo "* Processing ${FILE} ..."
536
+ FILE=${FILE%.*} # Trim the extension
537
+ if [ -f "./pki/etcd/ca.srl" ]; then
538
+ SERIAL_FLAG=-CAserial ./pki/etcd/ca.srl
539
+ else
540
+ SERIAL_FLAG=-CAcreateserial
541
+ fi
542
+ openssl x509 -req -days "${DAYS}" -CA ./pki/etcd/ca.crt -CAkey ./pki/etcd/ca.key ${SERIAL_FLAG} \
543
+ -in "${FILE}.csr" -out "${FILE}.crt"
544
+ done
545
+
546
+ # Process front-proxy CSRs
547
+ echo "* Processing ./pki/front-proxy-client.csr ..."
548
+ openssl x509 -req -days "${DAYS}" -CA ./pki/front-proxy-ca.crt -CAkey ./pki/front-proxy-ca.key -CAcreateserial \
549
+ -in ./pki/front-proxy-client.csr -out ./pki/front-proxy-client.crt
550
+ ` ` `
551
+
552
+ # ## Embedding certificates in kubeconfig files
553
+
554
+ Repeat this step for all nodes that have CSR files.
555
+
556
+ Write the following script in the `/etc/kubernetes` directory, navigate to the directory
557
+ and execute the script. The script will take the `.crt` files that were signed for
558
+ kubeconfig files from CSRs in the previous step and will embed them in the kubeconfig files.
559
+
560
+ ` ` ` bash
561
+ #!/bin/bash
562
+
563
+ CLUSTER=kubernetes
564
+ find ./ -name "*.conf" | while read -r FILE;
565
+ do
566
+ echo "* Processing ${FILE} ..."
567
+ KUBECONFIG="${FILE}" kubectl config set-cluster "${CLUSTER}" --certificate-authority ./pki/ca.crt --embed-certs
568
+ USER=$(KUBECONFIG="${FILE}" kubectl config view -o jsonpath='{.users[0].name}')
569
+ KUBECONFIG="${FILE}" kubectl config set-credentials "${USER}" --client-certificate "${FILE}.crt" --embed-certs
570
+ done
571
+ ` ` `
572
+
573
+ # ## Performing cleanup {#post-csr-cleanup}
574
+
575
+ Perform this step on all nodes that have CSR files.
576
+
577
+ Write the following script in the `/etc/kubernetes` directory, navigate to the directory
578
+ and execute the script.
579
+
580
+ ` ` ` bash
581
+ #!/bin/bash
582
+
583
+ # Cleanup CSR files
584
+ rm -f ./*.csr ./pki/*.csr ./pki/etcd/*.csr # Clean all CSR files
585
+
586
+ # Cleanup CRT files that were already embedded in kubeconfig files
587
+ rm -f ./*.crt
588
+ ` ` `
589
+
590
+ Optionally, move `.srl` files to the next node to be processed.
591
+
592
+ Optionally, if using external CA remove the `/etc/kubernetes/pki/ca.key` file,
593
+ as explained in the [External CA node](#external-ca-mode) section.
594
+
595
+ # ## kubeadm node initialization
596
+
597
+ Once CSR files have been signed and required certificates are in place on the hosts
598
+ you want to use as nodes, you can use the commands `kubeadm init` and `kubeadm join`
599
+ to create a Kubernetes cluster from these nodes. During `init` and `join`, kubeadm
600
+ uses existing certificates, encryption keys and kubeconfig files that it finds in the
601
+ ` /etc/kubernetes` tree on the host's local filesystem.
0 commit comments