From d22beacb253ebadf1d67cd124d7120ec79abd161 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Sat, 25 Jun 2022 14:33:34 +0800 Subject: [PATCH] [zh-cn] Rresync manual rotation of CA --- .../tls/manual-rotation-of-ca-certificates.md | 212 +++++++++++------- 1 file changed, 131 insertions(+), 81 deletions(-) diff --git a/content/zh-cn/docs/tasks/tls/manual-rotation-of-ca-certificates.md b/content/zh-cn/docs/tasks/tls/manual-rotation-of-ca-certificates.md index fcf9f7fab1..f0b950d3db 100644 --- a/content/zh-cn/docs/tasks/tls/manual-rotation-of-ca-certificates.md +++ b/content/zh-cn/docs/tasks/tls/manual-rotation-of-ca-certificates.md @@ -1,13 +1,12 @@ --- title: 手动轮换 CA 证书 -min-kubernetes-server-version: v1.13 content_type: task --- + - 要了解 Kubernetes 中用户认证的更多信息,参阅 [认证](/zh-cn/docs/reference/access-authn-authz/authentication); -- 要了解与 CA 证书最佳实践有关的更多信息,参阅[单根 CA](/zh-cn/docs/setup/best-practices/certificates/#single-root-ca)。 +- 要了解与 CA 证书最佳实践有关的更多信息, + 参阅[单根 CA](/zh-cn/docs/setup/best-practices/certificates/#single-root-ca)。 @@ -34,6 +36,7 @@ This page shows how to manually rotate the certificate authority (CA) certificat --> ## 手动轮换 CA 证书 {#rotate-the-ca-certificates-manually} +{{< caution >}} -{{< caution >}} 确保备份你的证书目录、配置文件以及其他必要文件。 这里的方法假定 Kubernetes 的控制面通过运行多个 API 服务器以高可用配置模式运行。 @@ -54,48 +56,59 @@ Configurations with a single API server will experience unavailability while the 1. 将新的 CA 证书和私钥(例如:`ca.crt`、`ca.key`、`front-proxy-ca.crt` 和 `front-proxy-client.key`)分发到所有控制面节点,放在其 Kubernetes 证书目录下。 +2. 更新 {{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}} + 的 `--root-ca-file` 标志,使之同时包含老的和新的 CA,之后重启组件。 + + 自此刻起,所创建的所有{{< glossary_tooltip text="ServiceAccount" term_id="service-account" >}} + 都会获得同时包含老的 CA 和新的 CA 的 Secret。 - Any service account created after this point will get secrets that include both old and new CAs. - {{< note >}} + -2. 更新 {{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}} 的 - `--root-ca-file` 标志,使之同时包含老的和新的 CA,之后重启组件。 + --> + kube-controller-manager 标志 `--client-ca-file` 和 `--cluster-signing-cert-file` + 所引用的文件不能是 CA 证书包。如果这些标志和 `--root-ca-file` 指向同一个 `ca.crt` 包文件 + (包含老的和新的 CA 证书),你将会收到出错信息。 + 要解决这个问题,可以将新的 CA 证书复制到单独的文件中,并将 `--client-ca-file` 和 + `--cluster-signing-cert-file` 标志指向该副本。一旦 `ca.crt` 不再是证书包文件, + 就可以恢复有问题的标志指向 `ca.crt` 并删除该副本。 - 自此刻起,所创建的所有服务账号都会获得同时包含老的 CA 和新的 CA 的 Secret。 - - {{< note >}} - kube-controller-manager 标志 `--client-ca-file` 和 `--cluster-signing-cert-file` 所引用的文件 - 不能是 CA 证书包。如果这些标志和 `--root-ca-file` 指向同一个 `ca.crt` 包文件(包含老的和新的 CA 证书), - 你将会收到出错信息。 - 要解决这个问题,可以将新的 CA 证书复制到单独的文件中,并将 `--client-ca-file` 和 `--cluster-signing-cert-file` - 标志指向该副本。一旦 `ca.crt` 不再是证书包文件,就可以恢复有问题的标志指向 `ca.crt` 并删除该副本。 + + kubeadm 的 [Issue 1350](https://github.com/kubernetes/kubeadm/issues/1350) + 在跟踪一个导致 kube-controller-manager 无法接收 CA 证书包的问题。 {{< /note >}} -3. 更新所有服务账号令牌,使之同时包含老的和新的 CA 证书。 +3. 更新所有的保存服务账号令牌的 Secret,使之同时包含老的和新的 CA 证书。 - 如果在 API 服务器使用新的 CA 之前启动了新的 Pod,这些 Pod + 如果在 API 服务器使用新的 CA 之前启动了新的 Pod,这些新的 Pod 也会获得此更新并且同时信任老的和新的 CA 证书。 + - ```shell - base64_encoded_ca="$(base64 -w0 )" + base64_encoded_ca="$(base64 -w0 <同时包含老的和新的 CA 的文件路径>)" for namespace in $(kubectl get ns --no-headers | awk '{print $1}'); do for token in $(kubectl get secrets --namespace "$namespace" --field-selector type=kubernetes.io/service-account-token -o name); do @@ -121,21 +133,25 @@ Configurations with a single API server will experience unavailability while the done done ``` + -4. 重启所有使用集群内配置的 Pods(例如:`kube-proxy`、`coredns` 等),以便这些 Pod 能够使用 - 来自 *ServiceAccount* Secret 中的、已更新的证书机构数据。 +4. 重启所有使用集群内配置的 Pod(例如:kube-proxy、CoreDNS 等),以便这些 Pod + 能够使用与 ServiceAccount 相关联的 Secret 中的、已更新的证书机构数据。 - * 确保 `coredns`、`kube-proxy` 和其他使用集群内配置的 Pod 都正按预期方式工作。 + * 确保 CoreDNS、kube-proxy 和其他使用集群内配置的 Pod 都正按预期方式工作。 -5. 将老的和新的 CA 都追加到 `kube-apiserver` 配置的 `--client-ca-file` 和 `--kubelet-certificate-authority` 标志所指的文件。 +5. 将老的和新的 CA 都追加到 `kube-apiserver` 配置的 `--client-ca-file` 和 + `--kubelet-certificate-authority` 标志所指的文件。 6. 将老的和新的 CA 都追加到 `kube-scheduler` 配置的 `--client-ca-file` 标志所指的文件。 @@ -148,19 +164,34 @@ Configurations with a single API server will experience unavailability while the Additionally, update the `certificate-authority-data` section in the kubeconfig files, respectively with Base64-encoded old and new certificate authority data --> -7. 通过替换 `client-certificate-data` 和 `client-key-data` - 中的内容,更新用户账号的证书。 +7. 通过替换 `client-certificate-data` 和 `client-key-data` 中的内容,更新用户账号的证书。 有关为独立用户账号创建证书的更多信息,可参阅 [为用户帐号配置证书](/zh-cn/docs/setup/best-practices/certificates/#configure-certificates-for-user-accounts)。 - 另外,还要更新 kubeconfig 文件中的 `certificate-authority-data` - 节,使之包含 Base64 编码的老的和新的证书机构数据。 + 另外,还要更新 kubeconfig 文件中的 `certificate-authority-data` 节, + 使之包含 Base64 编码的老的和新的证书机构数据。 + + +8. 更新 {{< glossary_tooltip term_id="cloud-controller-manager" >}} 的 `--root-ca-file` + 标志值,使之同时包含老的和新的 CA,之后重新启动 cloud-controller-manager。 + + {{< note >}} + + 如果你的集群中不包含 cloud-controller-manager,你可以略过这一步。 + {{< /note >}} + -8. 遵循下列步骤执行滚动更新 +9. 遵循下列步骤执行滚动更新 - 1. 重新启动所有其他 *[被聚合的 API 服务器](/zh-cn/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)* - 或者 *Webhook 处理程序*,使之信任新的 CA 证书。 + 1. 重新启动所有其他[被聚合的 API 服务器](/zh-cn/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) + 或者 Webhook 处理程序,使之信任新的 CA 证书。 - 2. 在所有节点上更新 kubelet 配置中的 `clientCAFile` 所指文件以及 kubelet.conf 中的 + 1. 在所有节点上更新 kubelet 配置中的 `clientCAFile` 所指文件以及 kubelet.conf 中的 `certificate-authority-data` 并重启 kubelet 以同时使用老的和新的 CA 证书。 如果你的 kubelet 并未使用客户端证书轮换,则在所有节点上更新 kubelet.conf 中 @@ -193,36 +224,39 @@ Configurations with a single API server will experience unavailability while the 你可以使用现有的私钥,也可以使用新的私钥。 如果你改变了私钥,则要将更新的私钥也放到 Kubernetes 证书目录下。 - 由于 Pod 既信任老的 CA 也信任新的 CA,Pod 中的客户端会经历短暂的连接断开状态, - 之后再连接到使用新的 CA 所签名的证书的新的 API 服务器。 + + 由于集群中的 Pod 既信任老的 CA 也信任新的 CA,Pod 中的客户端会经历短暂的连接断开状态, + 之后再使用新的 CA 所签名的证书连接到新的 API 服务器。 - * 重启调度器以使用新的 CA 证书。 + * 重启 {{< glossary_tooltip term_id="kube-scheduler" text="kube-scheduler" >}} 以使用并信任新的 + CA 证书。 * 确保控制面组件的日志中没有 TLS 相关的错误信息。 + {{< note >}} - {{< note >}} 要使用 `openssl` 命令行为集群生成新的证书和私钥,可参阅 [证书(`openssl`)](/zh-cn/docs/tasks/administer-cluster/certificates/#openssl)。 你也可以使用[`cfssl`](/zh-cn/docs/tasks/administer-cluster/certificates/#cfssl). {{< /note >}} 4. 为 Daemonset 和 Deployment 添加注解,从而触发较安全的滚动更新,替换 Pod。 - 示例: - ```shell for namespace in $(kubectl get namespace -o jsonpath='{.items[*].metadata.name}'); do for name in $(kubectl get deployments -n $namespace -o jsonpath='{.items[*].metadata.name}'); do @@ -234,41 +268,47 @@ Configurations with a single API server will experience unavailability while the done ``` + {{< note >}} - {{< note >}} - 要限制应用可能受到的并发干扰数量,可以参阅 - [配置 Pod 干扰预算](/zh-cn/docs/tasks/run-application/configure-pdb/). + 要限制应用可能受到的并发干扰数量, + 可以参阅[配置 Pod 干扰预算](/zh-cn/docs/tasks/run-application/configure-pdb/)。 {{< /note >}} + + + 取决于你在如何使用 StatefulSet,你可能需要对其执行类似的滚动替换操作。 + -9. 如果你的集群使用启动引导令牌来添加节点,则需要更新 `kube-public` 名字空间下的 - ConfigMap `cluster-info`,使之包含新的 CA 证书。 +10. 如果你的集群使用启动引导令牌来添加节点,则需要更新 `kube-public` 名字空间下的 + ConfigMap `cluster-info`,使之包含新的 CA 证书。 - ```shell - base64_encoded_ca="$(base64 -w0 /etc/kubernetes/pki/ca.crt)" + ```shell + base64_encoded_ca="$(base64 -w0 /etc/kubernetes/pki/ca.crt)" - kubectl get cm/cluster-info --namespace kube-public -o yaml | \ + kubectl get cm/cluster-info --namespace kube-public -o yaml | \ /bin/sed "s/\(certificate-authority-data:\).*/\1 ${base64_encoded_ca}/" | \ kubectl apply -f - - ``` + ``` -10. 验证集群的功能正常 +11. 验证集群的功能正常。 - 1. 验证控制面组件的日志,以及 `kubelet` 和 `kube-proxy` 的日志,确保其中没有 - 抛出 TLS 错误,参阅 - [查看日志](/zh-cn/docs/tasks/debug/debug-cluster/#looking-at-logs). + 1. 检查控制面组件以及 `kubelet` 和 `kube-proxy` 的日志,确保其中没有抛出 TLS 错误, + 参阅[查看日志](/zh-cn/docs/tasks/debug/debug-cluster/#looking-at-logs)。 2. 验证被聚合的 API 服务器的日志,以及所有使用集群内配置的 Pod 的日志。 @@ -277,21 +317,31 @@ Configurations with a single API server will experience unavailability while the 1. Update all service account tokens to include new CA certificate only. - * 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. + * All pods using an in-cluster kubeconfig will eventually need to be restarted to pick up the new secret, + so that no Pods are relying on the old cluster CA. 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. - 1. Restart kubelet by removing the old CA from file against the `clientCAFile` flag and kubelet kubeconfig file. + 1. On each node, restart the kubelet by removing the old CA from file against the `clientCAFile` flag + and from the kubelet kubeconfig file. You should carry this out as a rolling update. + + If your cluster lets you make this change, you can also roll it out by replacing nodes rather than + reconfiguring them. --> -11. 完成集群功能的检查之后: +12. 完成集群功能的检查之后: 1. 更新所有的服务账号令牌,使之仅包含新的 CA 证书。 * 使用集群内 kubeconfig 的 Pod 最终也需要被重启,以获得新的服务账号 Secret - 数据,进而不再信任老的 CA 证书。 + 数据,这样就不会有 Pod 再依赖老的集群 CA。 1. 从 kubeconfig 文件和 `--client-ca-file` 以及 `--root-ca-file` 标志所指向的文件 中去除老的 CA 数据,之后重启控制面组件。 - 1. 重启 kubelet,移除 `clientCAFile` 标志所指向的文件以及 kubelet kubeconfig 文件中 - 的老的 CA 数据。 + 1. 在每个节点上,移除 `clientCAFile` 标志所指向的文件,以删除老的 CA 数据,并从 + kubelet kubeconfig 文件中去掉老的 CA,重启 kubelet。 + 你应该用滚动更新的方式来执行这一步骤的操作。 + + 如果你的集群允许你执行这一变更,你也可以通过替换节点而不是重新配置节点的方式来将其上线。 + +