|
| 1 | +--- |
| 2 | +title: 手动轮换 CA 证书 |
| 3 | +min-kubernetes-server-version: v1.13 |
| 4 | +content_type: task |
| 5 | +--- |
| 6 | +<!-- |
| 7 | +title: Manual Rotation of CA Certificates |
| 8 | +min-kubernetes-server-version: v1.13 |
| 9 | +content_type: task |
| 10 | +--> |
| 11 | +<!-- overview --> |
| 12 | + |
| 13 | +<!-- |
| 14 | +This page shows how to manually rotate the certificate authority (CA) certificates. |
| 15 | +--> |
| 16 | +本页展示如何手动轮换证书机构(CA)证书。 |
| 17 | + |
| 18 | +## {{% heading "prerequisites" %}} |
| 19 | + |
| 20 | +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} |
| 21 | + |
| 22 | +<!-- |
| 23 | +- For more information about authentication in Kubernetes, see [Authenticating](/docs/reference/access-authn-authz/authentication). |
| 24 | +- For more information about best practices for CA certificates, see [Single root CA](/docs/setup/best-practices/certificates/#single-root-ca). |
| 25 | +--> |
| 26 | +- 要了解 Kubernetes 中用户认证的更多信息,参阅 |
| 27 | + [认证](/zh/docs/reference/access-authn-authz/authentication); |
| 28 | +- 要了解与 CA 证书最佳实践有关的更多信息,参阅[单根 CA](/zh/docs/setup/best-practices/certificates/#single-root-ca)。 |
| 29 | + |
| 30 | +<!-- steps --> |
| 31 | + |
| 32 | +<!-- |
| 33 | +## Rotate the CA certificates manually |
| 34 | +--> |
| 35 | +## 手动轮换 CA 证书 {#rotate-the-ca-certificates-manually} |
| 36 | + |
| 37 | +<!-- |
| 38 | +Make sure to back up your certificate directory along with configuration files and any other necessary files. |
| 39 | +
|
| 40 | +This approach assumes operation of the Kubernetes control plane in a HA configuration with multiple API servers. |
| 41 | +Graceful termination of the API server is also assumed so clients can cleanly disconnect from one API server and reconnect to another. |
| 42 | +
|
| 43 | +Configurations with a single API server will experience unavailability while the API server is being restarted. |
| 44 | +--> |
| 45 | +{{< caution >}} |
| 46 | +确保备份你的证书目录、配置文件以及其他必要文件。 |
| 47 | + |
| 48 | +这里的方法假定 Kubernetes 的控制面通过运行多个 API 服务器以高可用配置模式运行。 |
| 49 | +另一假定是 API 服务器可体面地终止,因而客户端可以彻底地与一个 API 服务器断开 |
| 50 | +连接并连接到另一个 API 服务器。 |
| 51 | + |
| 52 | +如果集群中只有一个 API 服务器,则在 API 服务器重启期间会经历服务中断期。 |
| 53 | +{{< /caution >}} |
| 54 | + |
| 55 | +<!-- |
| 56 | +1. Distribute the new CA certificates and private keys |
| 57 | + (ex: `ca.crt`, `ca.key`, `front-proxy-ca.crt`, and `front-proxy-ca.key`) |
| 58 | + to all your control plane nodes in the Kubernetes certificates directory. |
| 59 | +--> |
| 60 | +1. 将新的 CA 证书和私钥(例如:`ca.crt`、`ca.key`、`front-proxy-ca.crt` 和 |
| 61 | + `front-proxy-client.key`)分发到所有控制面节点,放在其 Kubernetes 证书目录下。 |
| 62 | + |
| 63 | +<!-- |
| 64 | +1. Update *Kubernetes controller manager's* `-root-ca-file` to include both old and new CA and restart controller manager. |
| 65 | +
|
| 66 | + Any service account created after this point will get secrets that include both old and new CAs. |
| 67 | +
|
| 68 | + Remove the flag `-client-ca-file` from the *Kubernetes controller manager* configuration. |
| 69 | + You can also replace the existing client CA file or change this configuration item to reference a new, updated CA. |
| 70 | + [Issue 1350](https://github.com/kubernetes/kubeadm/issues/1350) tracks an issue with *Kubernetes controller manager* being unable to accept a CA bundle. |
| 71 | +--> |
| 72 | +2. 更新控制器管理器的 `--root-ca-file` 标志,使之同时包含老的和新的 CA,之后重启控制器管理器。 |
| 73 | + |
| 74 | + 自此刻起,所创建的所有服务账号都会获得同时包含老的 CA 和新的 CA 的 Secret。 |
| 75 | + |
| 76 | + {{< note >}} |
| 77 | + 去掉控制器管理器的 `-client-ca-file` 标志。 |
| 78 | + 你也可以替换客户端 CA 文件或者将此配置条目指向新的、更新过的 CA。 |
| 79 | + [Issue 1350](https://github.com/kubernetes/kubeadm/issues/1350) 用来跟踪 |
| 80 | + 控制器管理器无法接受 CA 包的问题。 |
| 81 | + {{< /note >}} |
| 82 | + |
| 83 | +<!-- |
| 84 | +1. Update all service account tokens to include both old and new CA certificates. |
| 85 | +
|
| 86 | + 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. |
| 87 | +--> |
| 88 | +3. 更新所有服务账号令牌,使之同时包含老的和新的 CA 证书。 |
| 89 | + |
| 90 | + 如果在 API 服务器使用新的 CA 之前启动了新的 Pod,这些 Pod |
| 91 | + 也会获得此更新并且同时信任老的和新的 CA 证书。 |
| 92 | + |
| 93 | + ```shell |
| 94 | + base64_encoded_ca="$(base64 <path to file containing both old and new CAs>)" |
| 95 | + |
| 96 | + for namespace in $(kubectl get ns --no-headers | awk '{print $1}'); do |
| 97 | + for token in $(kubectl get secrets --namespace "$namespace" --field-selector type=kubernetes.io/service-account-token -o name); do |
| 98 | + kubectl get $token --namespace "$namespace" -o yaml | \ |
| 99 | + /bin/sed "s/\(ca.crt:\).*/\1 ${base64_encoded_ca}" | \ |
| 100 | + kubectl apply -f - |
| 101 | + done |
| 102 | + done |
| 103 | + ``` |
| 104 | +<!-- |
| 105 | +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. |
| 106 | +
|
| 107 | + * Make sure coredns, kube-proxy and other pods using in-cluster configs are working as expected. |
| 108 | +
|
| 109 | +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. |
| 110 | +
|
| 111 | +1. Append the both old and new CA to the file against `-client-ca-file` flag in the `kube-scheduler` configuration. |
| 112 | +--> |
| 113 | +4. 重启所有使用集群内配置的 Pods(例如:`kube-proxy`、`coredns` 等),以便这些 Pod 能够使用 |
| 114 | + 来自服务账号 Secret 中的、已更新的证书机构数据。 |
| 115 | + |
| 116 | + * 确保 `coredns`、`kube-proxy` 和其他使用集群内配置的 Pod 都正按预期方式工作。 |
| 117 | + |
| 118 | +5. 将老的和新的 CA 都追加到 `kube-apiserver` 配置的 `--client-ca-file` 和 `--kubelet-certificate-authority` 标志所指的文件。 |
| 119 | + |
| 120 | +6. 将老的和新的 CA 都追加到 `kube-scheduler` 配置的 `--client-ca-file` 标志所指的文件。 |
| 121 | + |
| 122 | +<!-- |
| 123 | +1. Update certificates for user accounts by replacing the content of `client-certificate-data` and `client-key-data` respectively. |
| 124 | +
|
| 125 | + For information about creating certificates for individual user accounts, see |
| 126 | + [Configure certificates for user accounts](/docs/setup/best-practices/certificates/#configure-certificates-for-user-accounts). |
| 127 | +
|
| 128 | + Additionally, update the `certificate-authority-data` section in the kubeconfig files, |
| 129 | + respectively with Base64-encoded old and new certificate authority data |
| 130 | +--> |
| 131 | +7. 通过替换 `client-certificate-data` 和 `client-key-data` |
| 132 | + 中的内容,更新用户账号的证书。 |
| 133 | + |
| 134 | + 有关为独立用户账号创建证书的更多信息,可参阅 |
| 135 | + [为用户帐号配置证书](/zh/docs/setup/best-practices/certificates/#configure-certificates-for-user-accounts)。 |
| 136 | + |
| 137 | + 另外,还要更新 kubeconfig 文件中的 `certificate-authority-data` |
| 138 | + 节,使之包含 Base64 编码的老的和新的证书机构数据。 |
| 139 | +<!-- |
| 140 | +1. Follow below steps in a rolling fashion. |
| 141 | +
|
| 142 | + 1. Restart any other *[aggregated api servers](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)* |
| 143 | + or *webhook handlers* to trust the new CA certificates. |
| 144 | +
|
| 145 | + 1. Restart the kubelet by update the file against `clientCAFile` in kubelet configuration and |
| 146 | + `certificate-authority-data` in kubelet.conf to use both the old and new CA on all nodes. |
| 147 | +
|
| 148 | + If your kubelet is not using client certificate rotation update `client-certificate-data` and |
| 149 | + `client-key-data` in kubelet.conf on all nodes along with the kubelet client certificate file |
| 150 | + usually found in `/var/lib/kubelet/pki`. |
| 151 | +--> |
| 152 | +8. 遵循下列步骤执行滚动更新 |
| 153 | + |
| 154 | + 1. 重新启动所有其他[被聚合的 API 服务器](/zh/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) |
| 155 | + 或者 *Webhook 处理程序*,使之信任新的 CA 证书。 |
| 156 | + |
| 157 | + 2. 在所有节点上更新 kubelet 配置中的 `clientCAFile` 所指文件以及 kubelet.conf 中的 |
| 158 | + `certificate-authority-data` 并重启 kubelet 以同时使用老的和新的 CA 证书。 |
| 159 | + |
| 160 | + 如果你的 kubelet 并未使用客户端证书轮换,则在所有节点上更新 kubelet.conf 中 |
| 161 | + `client-certificate-data` 和 `client-key-data` 以及 kubelet |
| 162 | + 客户端证书文件(通常位于 `/var/lib/kubelet/pki` 目录下) |
| 163 | + |
| 164 | + <!-- |
| 165 | + 1. Restart API servers with the certificates (`apiserver.crt`, `apiserver-kubelet-client.crt` and |
| 166 | + `front-proxy-client.crt`) signed by new CA. |
| 167 | + You can use the existing private keys or new private keys. |
| 168 | + If you changed the private keys then update these in the Kubernetes certificates directory as well. |
| 169 | + --> |
| 170 | + 3. 使用用新的 CA 签名的证书 |
| 171 | + (`apiserver.crt`、`apiserver-kubelet-client.crt` 和 `front-proxy-client.crt`) |
| 172 | + 来重启 API 服务器。 |
| 173 | + 你可以使用现有的私钥,也可以使用新的私钥。 |
| 174 | + 如果你改变了私钥,则要将更新的私钥也放到 Kubernetes 证书目录下。 |
| 175 | + |
| 176 | + 由于 Pod 既信任老的 CA 也信任新的 CA,Pod 中的客户端会经历短暂的连接断开状态, |
| 177 | + 之后再连接到使用新的 CA 所签名的证书的新的 API 服务器。 |
| 178 | + |
| 179 | + <!-- |
| 180 | + * Restart Scheduler to use the new CAs. |
| 181 | + * Make sure control plane components logs no TLS errors. |
| 182 | + --> |
| 183 | + * 重启调度器以使用新的 CA 证书。 |
| 184 | + * 确保控制面组件的日志中没有 TLS 相关的错误信息。 |
| 185 | + |
| 186 | + <!-- |
| 187 | + To generate certificates and private keys for your cluster using the `openssl` |
| 188 | + command line tool, see [Certificates (`openssl`)](/docs/concepts/cluster-administration/certificates/#openssl). |
| 189 | + You can also use [`cfssl`](/docs/concepts/cluster-administration/certificates/#cfssl). |
| 190 | + --> |
| 191 | + {{< note >}} |
| 192 | + 要使用 `openssl` 命令行为集群生成新的证书和私钥,可参阅 |
| 193 | + [证书(`openssl`)](/zh/docs/concepts/cluster-administration/certificates/#openssl)。 |
| 194 | + 你也可以使用[`cfssl`](/zh/docs/concepts/cluster-administration/certificates/#cfssl). |
| 195 | + {{< /note >}} |
| 196 | + |
| 197 | + <!-- |
| 198 | + 1. Annotate any Daemonsets and Deployments to trigger pod replacement in a safer rolling fashion. |
| 199 | +
|
| 200 | + Example: |
| 201 | + --> |
| 202 | + 4. 为 Daemonset 和 Deployment 添加注解,从而触发较安全的滚动更新,替换 Pod。 |
| 203 | + |
| 204 | + 示例: |
| 205 | + |
| 206 | + ```shell |
| 207 | + for namespace in $(kubectl get namespace -o jsonpath='{.items[*].metadata.name}'); do |
| 208 | + for name in $(kubectl get deployments -n $namespace -o jsonpath='{.items[*].metadata.name}'); do |
| 209 | + kubectl patch deployment -n ${namespace} ${name} -p '{"spec":{"template":{"metadata":{"annotations":{"ca-rotation": "1"}}}}}'; |
| 210 | + done |
| 211 | + for name in $(kubectl get daemonset -n $namespace -o jsonpath='{.items[*].metadata.name}'); do |
| 212 | + kubectl patch daemonset -n ${namespace} ${name} -p '{"spec":{"template":{"metadata":{"annotations":{"ca-rotation": "1"}}}}}'; |
| 213 | + done |
| 214 | + done |
| 215 | + ``` |
| 216 | + |
| 217 | + <!-- |
| 218 | + To limit the number of concurrent disruptions that your application experiences, |
| 219 | + see [configure pod disruption budget](/docs/tasks/run-application/configure-pdb/). |
| 220 | + --> |
| 221 | + {{< note >}} |
| 222 | + 要限制应用可能受到的并发干扰数量,可以参阅 |
| 223 | + [配置 Pod 干扰预算](/zh/docs/tasks/run-application/configure-pdb/). |
| 224 | + {{< /note >}} |
| 225 | +<!-- |
| 226 | +1. If your cluster is using bootstrap tokens to join nodes, update the ConfigMap `cluster-info` in the `kube-public` namespace with new CA. |
| 227 | +--> |
| 228 | +9. 如果你的集群使用启动引导令牌来添加节点,则需要更新 `kube-public` 名字空间下的 |
| 229 | + ConfigMap `cluster-info`,使之包含新的 CA 证书。 |
| 230 | + |
| 231 | + ```shell |
| 232 | + base64_encoded_ca="$(base64 /etc/kubernetes/pki/ca.crt)" |
| 233 | +
|
| 234 | + kubectl get cm/cluster-info --namespace kube-public -o yaml | \ |
| 235 | + /bin/sed "s/\(certificate-authority-data:\).*/\1 ${base64_encoded_ca}" | \ |
| 236 | + kubectl apply -f - |
| 237 | + ``` |
| 238 | +<!-- |
| 239 | +1. Verify the cluster functionality. |
| 240 | + |
| 241 | + 1. Validate the logs from control plane components, along with the kubelet and the |
| 242 | + kube-proxy are not throwing any tls errors, see |
| 243 | + [looking at the logs](/docs/tasks/debug-application-cluster/debug-cluster/#looking-at-logs). |
| 244 | + |
| 245 | + 1. Validate logs from any aggregated api servers and pods using in-cluster config. |
| 246 | +--> |
| 247 | +10. 验证集群的功能正常 |
| 248 | + |
| 249 | + 1. 验证控制面组件的日志,以及 `kubelet` 和 `kube-proxy` 的日志,确保其中没有 |
| 250 | + 抛出 TLS 错误,参阅 |
| 251 | + [查看日志](/zh/docs/tasks/debug-application-cluster/debug-cluster/#looking-at-logs). |
| 252 | + |
| 253 | + 2. 验证被聚合的 API 服务器的日志,以及所有使用集群内配置的 Pod 的日志。 |
| 254 | + |
| 255 | +<!-- |
| 256 | +1. Once the cluster functionality is successfully verified: |
| 257 | + |
| 258 | + 1. Update all service account tokens to include new CA certificate only. |
| 259 | + |
| 260 | + * 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. |
| 261 | + |
| 262 | + 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. |
| 263 | + |
| 264 | + 1. Restart kubelet by removing the old CA from file against the `clientCAFile` flag and kubelet kubeconfig file. |
| 265 | +--> |
| 266 | +11. 完成集群功能的检查之后: |
| 267 | + |
| 268 | + 1. 更新所有的服务账号令牌,使之仅包含新的 CA 证书。 |
| 269 | + |
| 270 | + * 使用集群内 kubeconfig 的 Pod 最终也需要被重启,以获得新的服务账号 Secret |
| 271 | + 数据,进而不再信任老的 CA 证书。 |
| 272 | + |
| 273 | + 1. 从 kubeconfig 文件和 `--client-ca-file` 以及 `--root-ca-file` 标志所指向的文件 |
| 274 | + 中去除老的 CA 数据,之后重启控制面组件。 |
| 275 | + |
| 276 | + 1. 重启 kubelet,移除 `clientCAFile` 标志所指向的文件以及 kubelet kubeconfig 文件中 |
| 277 | + 的老的 CA 数据。 |
| 278 | + |
0 commit comments