Skip to content

Commit 5050bed

Browse files
author
Tim Bannister
authored
Revise manual CA rotation task page (#33874)
* Tweak namespace fetch command * Update CA certificate rotation task * Document when to reconfigure cloud-controller-manager for CA rotation * Assume that Kubernetes is at least v1.13 At the time of writing, the oldest supported version was v1.21 * Wrap page
1 parent cbff0cf commit 5050bed

File tree

1 file changed

+68
-45
lines changed

1 file changed

+68
-45
lines changed
Lines changed: 68 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
---
22
title: Manual Rotation of CA Certificates
3-
min-kubernetes-server-version: v1.13
43
content_type: task
54
---
65

@@ -10,11 +9,13 @@ This page shows how to manually rotate the certificate authority (CA) certificat
109

1110
## {{% heading "prerequisites" %}}
1211

13-
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
12+
{{< include "task-tutorial-prereqs.md" >}}
1413

1514

16-
- For more information about authentication in Kubernetes, see [Authenticating](/docs/reference/access-authn-authz/authentication).
17-
- For more information about best practices for CA certificates, see [Single root CA](/docs/setup/best-practices/certificates/#single-root-ca).
15+
- For more information about authentication in Kubernetes, see
16+
[Authenticating](/docs/reference/access-authn-authz/authentication).
17+
- For more information about best practices for CA certificates, see
18+
[Single root CA](/docs/setup/best-practices/certificates/#single-root-ca).
1819

1920
<!-- steps -->
2021

@@ -24,36 +25,41 @@ This page shows how to manually rotate the certificate authority (CA) certificat
2425
Make sure to back up your certificate directory along with configuration files and any other necessary files.
2526

2627
This approach assumes operation of the Kubernetes control plane in a HA configuration with multiple API servers.
27-
Graceful termination of the API server is also assumed so clients can cleanly disconnect from one API server and reconnect to another.
28+
Graceful termination of the API server is also assumed so clients can cleanly disconnect from one API server and
29+
reconnect to another.
2830

2931
Configurations with a single API server will experience unavailability while the API server is being restarted.
3032
{{< /caution >}}
3133

32-
1. Distribute the new CA certificates and private keys
33-
(ex: `ca.crt`, `ca.key`, `front-proxy-ca.crt`, and `front-proxy-ca.key`)
34-
to all your control plane nodes in the Kubernetes certificates directory.
34+
1. Distribute the new CA certificates and private keys (for example: `ca.crt`, `ca.key`, `front-proxy-ca.crt`,
35+
and `front-proxy-ca.key`) to all your control plane nodes in the Kubernetes certificates directory.
3536

36-
1. Update {{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}}'s `--root-ca-file` to
37-
include both old and new CA. Then restart the component.
37+
1. Update the `--root-ca-file` flag for the {{< glossary_tooltip term_id="kube-controller-manager" >}} to include
38+
both old and new CA, then restart the kube-controller-manager.
3839

39-
Any service account created after this point will get secrets that include both old and new CAs.
40+
Any {{< glossary_tooltip text="ServiceAccount" term_id="service-account" >}} created after this point will get
41+
Secrets that include both old and new CAs.
4042

4143
{{< note >}}
4244
The files specified by the kube-controller-manager flags `--client-ca-file` and `--cluster-signing-cert-file`
4345
cannot be CA bundles. If these flags and `--root-ca-file` point to the same `ca.crt` file which is now a
44-
bundle (includes both old and new CA) you will face an error. To workaround this problem you can copy the new CA to a separate
45-
file and make the flags `--client-ca-file` and `--cluster-signing-cert-file` point to the copy. Once `ca.crt` is no longer
46-
a bundle you can restore the problem flags to point to `ca.crt` and delete the copy.
46+
bundle (includes both old and new CA) you will face an error. To workaround this problem you can copy the new CA
47+
to a separate file and make the flags `--client-ca-file` and `--cluster-signing-cert-file` point to the copy.
48+
Once `ca.crt` is no longer a bundle you can restore the problem flags to point to `ca.crt` and delete the copy.
49+
50+
[Issue 1350](https://github.com/kubernetes/kubeadm/issues/1350) for kubeadm tracks an bug with the
51+
kube-controller-manager being unable to accept a CA bundle.
4752
{{< /note >}}
4853

49-
1. Update all service account tokens to include both old and new CA certificates.
54+
1. Update all Secrets that hold service account tokens to include both old and new CA certificates.
5055

51-
If any pods are started before new CA is used by API servers, they will get this update and trust both old and new CAs.
56+
If any Pods are started before new CA is used by API servers, the new Pods get this update and will trust both
57+
old and new CAs.
5258

5359
```shell
5460
base64_encoded_ca="$(base64 -w0 <path to file containing both old and new CAs>)"
5561

56-
for namespace in $(kubectl get ns --no-headers | awk '{print $1}'); do
62+
for namespace in $(kubectl get namespace --no-headers -o name | cut -d / -f 2 ); do
5763
for token in $(kubectl get secrets --namespace "$namespace" --field-selector type=kubernetes.io/service-account-token -o name); do
5864
kubectl get $token --namespace "$namespace" -o yaml | \
5965
/bin/sed "s/\(ca.crt:\).*/\1 ${base64_encoded_ca}/" | \
@@ -62,56 +68,65 @@ Configurations with a single API server will experience unavailability while the
6268
done
6369
```
6470

65-
1. Restart all pods using in-cluster configs (ex: kube-proxy, coredns, etc) so they can use the updated certificate authority data from *ServiceAccount* secrets.
71+
1. Restart all pods using in-cluster configurations (for example: kube-proxy, CoreDNS, etc) so they can use the
72+
updated certificate authority data from Secrets that link to ServiceAccounts.
6673

67-
* Make sure coredns, kube-proxy and other pods using in-cluster configs are working as expected.
74+
* Make sure CoreDNS, kube-proxy and other Pods using in-cluster configurations are working as expected.
6875

69-
1. Append the both old and new CA to the file against `--client-ca-file` and `--kubelet-certificate-authority` flag in the `kube-apiserver` configuration.
76+
1. Append the both old and new CA to the file against `--client-ca-file` and `--kubelet-certificate-authority`
77+
flag in the `kube-apiserver` configuration.
7078

7179
1. Append the both old and new CA to the file against `--client-ca-file` flag in the `kube-scheduler` configuration.
7280

73-
1. Update certificates for user accounts by replacing the content of `client-certificate-data` and `client-key-data` respectively.
81+
1. Update certificates for user accounts by replacing the content of `client-certificate-data` and `client-key-data`
82+
respectively.
7483

7584
For information about creating certificates for individual user accounts, see
7685
[Configure certificates for user accounts](/docs/setup/best-practices/certificates/#configure-certificates-for-user-accounts).
7786

7887
Additionally, update the `certificate-authority-data` section in the kubeconfig files,
7988
respectively with Base64-encoded old and new certificate authority data
8089

81-
1. Follow below steps in a rolling fashion.
90+
1. Update the `--root-ca-file` flag for the {{< glossary_tooltip term_id="cloud-controller-manager" >}} to include
91+
both old and new CA, then restart the cloud-controller-manager.
92+
93+
{{< note >}}
94+
If your cluster does not have a cloud-controller-manager, you can skip this step.
95+
{{< /note >}}
96+
97+
1. Follow the steps below in a rolling fashion.
8298

83-
1. Restart any other *[aggregated api servers](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)*
84-
or *webhook handlers* to trust the new CA certificates.
99+
1. Restart any other
100+
[aggregated API servers](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) or
101+
webhook handlers to trust the new CA certificates.
85102

86103
1. Restart the kubelet by update the file against `clientCAFile` in kubelet configuration and
87-
`certificate-authority-data` in kubelet.conf to use both the old and new CA on all nodes.
104+
`certificate-authority-data` in `kubelet.conf` to use both the old and new CA on all nodes.
88105

89-
If your kubelet is not using client certificate rotation update `client-certificate-data` and
90-
`client-key-data` in kubelet.conf on all nodes along with the kubelet client certificate file
106+
If your kubelet is not using client certificate rotation, update `client-certificate-data` and
107+
`client-key-data` in `kubelet.conf` on all nodes along with the kubelet client certificate file
91108
usually found in `/var/lib/kubelet/pki`.
92109

93-
94110
1. Restart API servers with the certificates (`apiserver.crt`, `apiserver-kubelet-client.crt` and
95111
`front-proxy-client.crt`) signed by new CA.
96112
You can use the existing private keys or new private keys.
97113
If you changed the private keys then update these in the Kubernetes certificates directory as well.
98114

99-
Since the pod trusts both old and new CAs, there will be a momentarily disconnection
100-
after which the pod's kube client will reconnect to the new API server
101-
that uses the certificate signed by the new CA.
102-
103-
* Restart Scheduler to use the new CAs.
115+
Since the Pods in your cluster trust both old and new CAs, there will be a momentarily disconnection
116+
after which pods' Kubernetes clients reconnect to the new API server.
117+
The new API server uses a certificate signed by the new CA.
104118

119+
* Restart the {{< glossary_tooltip term_id="kube-scheduler" text="kube-scheduler" >}} to use and
120+
trust the new CAs.
105121
* Make sure control plane components logs no TLS errors.
106122

107123
{{< note >}}
108-
To generate certificates and private keys for your cluster using the `openssl` command line tool, see [Certificates (`openssl`)](/docs/tasks/administer-cluster/certificates/#openssl).
124+
To generate certificates and private keys for your cluster using the `openssl` command line tool,
125+
see [Certificates (`openssl`)](/docs/tasks/administer-cluster/certificates/#openssl).
109126
You can also use [`cfssl`](/docs/tasks/administer-cluster/certificates/#cfssl).
110127
{{< /note >}}
111128

112-
1. Annotate any Daemonsets and Deployments to trigger pod replacement in a safer rolling fashion.
113-
114-
Example:
129+
1. Annotate any DaemonSets and Deployments to trigger pod replacement in a safer rolling fashion.
115130

116131
```shell
117132
for namespace in $(kubectl get namespace -o jsonpath='{.items[*].metadata.name}'); do
@@ -129,7 +144,10 @@ Configurations with a single API server will experience unavailability while the
129144
see [configure pod disruption budget](/docs/tasks/run-application/configure-pdb/).
130145
{{< /note >}}
131146

132-
1. If your cluster is using bootstrap tokens to join nodes, update the ConfigMap `cluster-info` in the `kube-public` namespace with new CA.
147+
Depending on how you use StatefulSets you may also need to perform similar rolling replacement.
148+
149+
1. If your cluster is using bootstrap tokens to join nodes, update the ConfigMap `cluster-info` in the `kube-public`
150+
namespace with new CA.
133151

134152
```shell
135153
base64_encoded_ca="$(base64 -w0 /etc/kubernetes/pki/ca.crt)"
@@ -141,19 +159,24 @@ Configurations with a single API server will experience unavailability while the
141159

142160
1. Verify the cluster functionality.
143161

144-
1. Validate the logs from control plane components, along with the kubelet and the
145-
kube-proxy are not throwing any tls errors, see
146-
[looking at the logs](/docs/tasks/debug/debug-cluster/#looking-at-logs).
162+
1. Check the logs from control plane components, along with the kubelet and the kube-proxy.
163+
Ensure those components are not reporting any TLS errors; see
164+
[looking at the logs](/docs/tasks/debug-application-cluster/debug-cluster/#looking-at-logs) for more details.
147165

148-
1. Validate logs from any aggregated api servers and pods using in-cluster config.
166+
1. Validate logs from any aggregated api servers and pods using in-cluster config.
149167

150168
1. Once the cluster functionality is successfully verified:
151169

152170
1. Update all service account tokens to include new CA certificate only.
153171

154-
* All pods using an in-cluster kubeconfig will eventually need to be restarted to pick up the new SA secret for the old CA to be completely untrusted.
172+
* All pods using an in-cluster kubeconfig will eventually need to be restarted to pick up the new Secret,
173+
so that no Pods are relying on the old cluster CA.
155174

156-
1. Restart the control plane components by removing the old CA from the kubeconfig files and the files against `--client-ca-file`, `--root-ca-file` flags resp.
175+
1. Restart the control plane components by removing the old CA from the kubeconfig files and the files against
176+
`--client-ca-file`, `--root-ca-file` flags resp.
157177

158-
1. Restart kubelet by removing the old CA from file against the `clientCAFile` flag and kubelet kubeconfig file.
178+
1. On each node, restart the kubelet by removing the old CA from file against the `clientCAFile` flag
179+
and from the kubelet kubeconfig file. You should carry this out as a rolling update.
159180

181+
If your cluster lets you make this change, you can also roll it out by replacing nodes rather than
182+
reconfiguring them.

0 commit comments

Comments
 (0)