diff --git a/content/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md b/content/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md index 0ced108885..f9e2e3fb11 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md +++ b/content/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-certs.md @@ -82,16 +82,92 @@ CA key on disk. 否则,kubeadm 将独立运行 controller-manager,附加一个 `--controllers=csrsigner` 的参数,并且指明 CA 证书和密钥。 +使用外部 CA 模式时,有多种方法可以准备组件证书。 + -[PKI 证书和要求](/zh-cn/docs/setup/best-practices/certificates/)包括集群使用外部 -CA 的设置指南。 +### 手动准备组件证书 + +[PKI 证书和要求](/zh-cn/docs/setup/best-practices/certificates/)包含有关如何手动准备 +kubeadm 组件证书所需的所有信息。 + + +### 通过签署 kubeadm 生成的 CSR 来准备证书 + +kubeadm 可以[生成 CSR 文件](#signing-csr),你可以使用 `openssl` 和外部 CA 等工具手动签署这些文件。 +这些 CSR 文件将包含 kubeadm 部署的组件所需的所有证书规范。 + + +### 使用 kubeadm 阶段自动准备组件证书 + +或者,可以使用 kubeadm 阶段命令来自动化此过程。 + + +- 登录到将作为具有外部 CA 的 kubeadm 控制平面节点的主机。 +- 将外部 CA 文件 `ca.crt` 和 `ca.key` 复制到节点上的 `/etc/kubernetes/pki` 目录中。 +- 准备一个名为 `config.yaml` 的临时 [kubeadm 配置文件](/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-init/#config-file), + 该文件可以用在 `kubeadm init` 命令中。确保此文件包含可包含在证书中的集群范围或特定于主机的所有重要信息, + 例如 `ClusterConfiguration.controlPlaneEndpoint`、`ClusterConfiguration.certSANs` 和 `InitConfiguration.APIEndpoint`。 +- 在同一主机上执行命令 `kubeadm init stage kubeconfig all --config config.yaml` 和 + `kubeadm init stage certs all --config config.yaml`。 + 这些操作将在 `/etc/kubernetes/` 及其 `pki` 子目录下生成所有必需的 kubeconfig 文件和证书。 + +- 检查所生成的文件。删除 `/etc/kubernetes/pki/ca.key`,删除或移动 `/etc/kubernetes/super-admin.conf` 文件到安全的位置。 +- 在将执行 `kubeadm join` 的节点上还需要删除 `/etc/kubernetes/kubelet.conf`, + 仅在将执行 `kubeadm init` 的第一个节点上需要此文件。 +- 请注意,一些文件如 `pki/sa.*`、`pki/front-proxy-ca.*` 和 `pki/etc/ca.*` + 在控制平面各节点上是相同的,你可以一次性生成它们并[手动将其分发](/zh-cn/docs/setup/production-environment/tools/kubeadm/high-availability/#manual-certs)到将执行 + `kubeadm join` 的节点,或者你可以使用 `kubeadm init` 的 [`--upload-certs`](/zh-cn/docs/setup/product-environment/tools/kubeadm/high-availability/#stacked-control-plane-and-etcd-nodes) + 和 `kubeadm join` 的 `--certificate-key` 特性来执行自动分发。 + + +在所有节点上准备好证书后,调用 `kubeadm init` 和 `kubeadm join` 命令将这些节点加入集群。 +kubeadm 将使用 `/etc/kubernetes/` 及其 `pki` 子目录下现有的 kubeconfig 和证书文件。 有关使用 Kubernetes API 创建 CSR 的信息, -请参见[创建 CertificateSigningRequest](/zh-cn/docs/reference/access-authn-authz/certificate-signing-requests/#create-certificatesigningrequest)。 +请参见[创建 CertificateSigningRequest](/zh-cn/docs/reference/access-authn-authz/certificate-signing-requests/#create-certificatessigningrequest)。 -### 创建证书签名请求 (CSR) {#create-certificate-signing-requests-csr-1} +### 使用证书签名请求(CSR)续订 -你可以通过 `kubeadm certs renew --csr-only` 命令创建证书签名请求。 - -CSR 和随附的私钥都在输出中给出。 -你可以传入一个带有 `--csr-dir` 的目录,将 CSR 输出到指定位置。 -如果未指定 `--csr-dir`,则使用默认证书目录(`/etc/kubernetes/pki`)。 - - -证书可以通过 `kubeadm certs renew --csr-only` 来续订。 -和 `kubeadm init` 一样,可以使用 `--csr-dir` 标志指定一个输出目录。 - - -CSR 中包含一个证书的名字,域和 IP,但是未指定用法。 -颁发证书时,CA 有责任指定[正确的证书用法](/zh-cn/docs/setup/best-practices/certificates/#all-certificates) - - -* 在 `openssl` 中,这是通过 - [`openssl ca` 命令](https://superuser.com/questions/738612/openssl-ca-keyusage-extension) - 来完成的。 -* 在 `cfssl` 中,这是通过 - [在配置文件中指定用法](https://github.com/cloudflare/cfssl/blob/master/doc/cmd/cfssl.txt#L170) - 来完成的。 - - -使用首选方法对证书签名后,必须将证书和私钥复制到 PKI 目录(默认为 `/etc/kubernetes/pki`)。 +可以通过生成新的 CSR 并使用外部 CA 对其进行签名来对证书进行续约。 +有关使用 kubeadm 生成的 CSR 的更多详细信息,请参阅[对 kubeadm 生成的证书签名请求(CSR)进行签名](#signing-csr)部分。 +## 签署由 kubeadm 生成的证书签名请求(CSR) {#signing-csr} + +`kubeadm certs generate-csr` 命令为 kubeadm 所了解并管理的所有证书生成 CSR。 +调用此命令将为常规证书生成 `.csr` / `.key` 文件对。 +对于嵌入在 kubeconfig 文件中的证书,该命令将生成一个 `.csr` / `.conf` 对, +其中密钥已嵌入在 `.conf` 文件中。 + + +CSR 文件包含 CA 签署证书的所有相关信息。 +kubeadm 对其所有证书和 CSR 使用[明确定义的规约](/zh-cn/docs/setup/best-practices/certificates/#all-certificates)。 + + +默认证书目录是 `/etc/kubernetes/pki`,而 kubeconfig 文件的默认目录是 `/etc/kubernetes`。 +这些默认值可以分别使用标志 `--cert-dir` 和 `--kubeconfig-dir` 覆盖。 + + +`kubeadm certs generate-csr` 命令为 kubeadm 所了解并管理的所有证书生成 CSR。 +该标志接受 [kubeadm 配置](/zh-cn/docs/reference/config-api/kubeadm-config.v1beta3/)文件, +与诸如 `kubeadm init` 这类命令相似。 +所有规约(例如额外的 SAN 和自定义 IP 地址)都必须存储在同一配置文件中, +并通过将其作为 `--config` 传递来用于所有相关的 kubeadm 命令。 + +{{< note >}} + +本指南将介绍如何使用 `openssl` 命令来执行 CSR,但你可以使用你喜欢的工具。 +{{< /note >}} + +{{< note >}} + +本指南将使用默认的 Kubernetes 目录 `/etc/kubernetes`,需要超级用户权限。 +如果你按照本指南使用访问权限较低的目录(通过指定 `--cert-dir` 和 `--kubeconfig-dir`),可以省略 `sudo` 命令。 +但请注意,生成的文件必须被复制到 `/etc/kubernetes` 目录下,以便 `kubeadm init` +或 `kubeadm join` 能够找到它们。 +{{< /note >}} + + +### 准备 CA 和服务帐户文件 + +在将执行` kubeadm init` 的主控制平面节点上,执行以下命令: + +```shell +sudo kubeadm init phase certs ca +sudo kubeadm init phase certs etcd-ca +sudo kubeadm init phase certs front-proxy-ca +sudo kubeadm init phase certs sa +``` + + +这些操作将使用 kubeadm 所需的所有自签名 CA 文件(证书和密钥) +以及服务帐户(公钥和私钥)填充控制平面节点的 `/etc/kubernetes/pki` +和 `/etc/kubernetes/pki/etcd` 目录。 + +{{< note >}} + +如果你使用外部 CA,则必须在带外生成相同的文件,并手动将它们复制到 +主控制平面节点上的 `/etc/kubernetes`。 +所有 CSR 被签名后,你可以删除根 CA 密钥(`ca.key`),如[外部 CA 模式](#external-ca-mode)部分中所述。 +{{< /note >}} + + +对于辅助控制平面节点(`kubeadm join --control-plane`),无需执行前述命令。 +根据你部署[高可用](/zh-cn/docs/setup/production-environment/tools/kubeadm/high-availability)集群的方式, +你要么从主控制平面节点手动复制相同的文件,要么使用 `kubeadm init` 的 `--upload-certs` 特性实现自动化分发。 + + +### 生成 CSR {#generate-csrs} + +`kubeadm certs generate-csr` 命令为 kubeadm 所了解并管理的所有证书生成 CSR。 +命令完成后,你必须手动删除不需要的 `.csr`、`.conf` 或 `.key` 文件。 + + +#### kubelet.conf 的注意事项 {#considerations-kubelet-conf} + +本节适用于控制平面和工作节点。 + +如果你从控制平面节点([外部 CA 模式](#external-ca-mode))上删除了 `ca.key` 文件, +则该集群中的运行的 kube-controller-manager 将无法签署 kubelet 客户端证书。 +如果你的设置中不存在用于签署这些证书的外部方法 +(例如[外部签名者](#set-up-a-signer)),你可以按照本指南中的说明手动签署 `kubelet.conf.csr`。 + + +请注意,这也意味着自动 [kubelet 客户端证书轮换](/zh-cn/docs/tasks/tls/certificate-rotation/#enabling-client-certificate-rotation)将被禁用。 +如果是这样,在证书即将到期时,你必须生成新的 `kubelet.conf.csr`,签署证书, +将其嵌入到 `kubelet.conf` 中并重新启动 kubelet。 + +如果这不适用于你的配置,你可以跳过在辅助控制平面和工作节点 +(调用 `kubeadm join ...` 的所有节点)上处理 `kubelet.conf.csr`。 +这是因为所运行的 kube-controller-manager 将负责签署新的 kubelet 客户端证书。 + +{{< note >}} + +你仍需要在主控制平面节点(`kubeadm init`)上处理 `kubelet.conf.csr`, +因为该节点被视为引导集群的节点,并且需要预先填充的 `kubelet.conf`。 +{{< /note >}} + + +#### 控制平面节点 + +在主(`kubeadm init`)和辅助(`kubeadm join --control-plane`) +控制平面节点上执行以下命令以生成所有 CSR 文件: + +```shell +sudo kubeadm certs generate-csr +``` + + +如果要使用外部 etcd,请阅读 [kubeadm 使用外部 etcd](/zh-cn/docs/setup/production-environment/tools/kubeadm/high-availability/#external-etcd-nodes)指南了解 +kubeadm 和 etcd 节点上需要哪些 CSR 文件。 +你可以删除 `/etc/kubernetes/pki/etcd` 下的其他 `.csr` 和 `.key` 文件。 + +根据 [kubelet.conf 的注意事项](#considerations-kubelet-conf)中的说明, +你可以决定保留或删除 `kubelet.conf` 和 `kubelet.conf.csr` 文件。 + + +#### 工作节点 + +根据 [kubelet.conf 的注意事项](#considerations-kubelet-conf)中的解释,可以选择执行: + +```shell +sudo kubeadm certs generate-csr +``` + + +并仅保留 `kubelet.conf` 和 `kubelet.conf.csr` 文件, +或者完全跳过工作节点的步骤。 + + +### 签署所有证书的 CSR + +{{< note >}} + +如果你使用外部 CA 并且已经拥有 `openssl` 的 CA 序列号文件(`.srl`), +你可以将此类文件复制到将处理 CSR 的 kubeadm 节点。 +要复制的 `.srl` 文件有 `/etc/kubernetes/pki/ca.srl`、`/etc/kubernetes/pki/front-proxy-ca.srl` +和 `/etc/kubernetes/pki/etcd/ca.srl`。 +然后可以将文件移动到将处理 CSR 文件的新节点。 + +如果节点上的 CA 缺少 `.srl` 文件,下面的脚本将生成一个具有随机起始序列号的新 SRL 文件。 + +要了解有关 `.srl` 文件的更多信息,请参阅 `--CAserial` 标志的 +[`openssl`](https://www.openssl.org/docs/man3.0/man1/openssl-x509.html) 文档。 +{{< /note >}} + + +对具有 CSR 文件的所有节点重复此步骤。 + +在 `/etc/kubernetes` 目录中编写以下脚本,进入该目录并执行该脚本。 +该脚本将为 `/etc/kubernetes` 目录下存在的所有 CSR 文件生成证书。 + + +```bash +#!/bin/bash + +# 设置证书过期时间(以天为单位) +DAYS=365 + +# 处理除 front-proxy 和 etcd 之外的所有 CSR 文件 +find ./ -name "*.csr" | grep -v "pki/etcd" | grep -v "front-proxy" | while read -r FILE; +do + echo "* Processing ${FILE} ..." + FILE=${FILE%.*} # 修剪扩展名 + if [ -f "./pki/ca.srl" ]; then + SERIAL_FLAG="-CAserial ./pki/ca.srl" + else + SERIAL_FLAG="-CAcreateserial" + fi + openssl x509 -req -days "${DAYS}" -CA ./pki/ca.crt -CAkey ./pki/ca.key ${SERIAL_FLAG} \ + -in "${FILE}.csr" -out "${FILE}.crt" + sleep 2 +done + +# 处理所有 etcd CSR +find ./pki/etcd -name "*.csr" | while read -r FILE; +do + echo "* Processing ${FILE} ..." + FILE=${FILE%.*} # 修剪扩展名 + if [ -f "./pki/etcd/ca.srl" ]; then + SERIAL_FLAG=-CAserial ./pki/etcd/ca.srl + else + SERIAL_FLAG=-CAcreateserial + fi + openssl x509 -req -days "${DAYS}" -CA ./pki/etcd/ca.crt -CAkey ./pki/etcd/ca.key ${SERIAL_FLAG} \ + -in "${FILE}.csr" -out "${FILE}.crt" +done + +# 处理前端代理 CSR +echo "* Processing ./pki/front-proxy-client.csr ..." +openssl x509 -req -days "${DAYS}" -CA ./pki/front-proxy-ca.crt -CAkey ./pki/front-proxy-ca.key -CAcreateserial \ + -in ./pki/front-proxy-client.csr -out ./pki/front-proxy-client.crt +``` + + +### 在 kubeconfig 文件中嵌入证书 + +对具有 CSR 文件的所有节点重复此步骤。 + +在 `/etc/kubernetes` 目录中编写以下脚本,进入该目录并执行脚本。 +此脚本将基于上一步从 CSR 中得到为 kubeconfig 文件签名的 `.crt` 文件, +并将它们嵌入到 kubeconfig 文件中。 + +```bash +#!/bin/bash + +CLUSTER=kubernetes +find ./ -name "*.conf" | while read -r FILE; +do + echo "* Processing ${FILE} ..." + KUBECONFIG="${FILE}" kubectl config set-cluster "${CLUSTER}" --certificate-authority ./pki/ca.crt --embed-certs + USER=$(KUBECONFIG="${FILE}" kubectl config view -o jsonpath='{.users[0].name}') + KUBECONFIG="${FILE}" kubectl config set-credentials "${USER}" --client-certificate "${FILE}.crt" --embed-certs +done +``` + + +### 执行清理 {#post-csr-cleanup} + +在具有 CSR 文件的所有节点上执行此步骤。 + +在 `/etc/kubernetes` 目录中编写以下脚本,进入该目录并执行脚本。 + + +```bash +#!/bin/bash + +# 清理 CSR 文件 +rm -f ./*.csr ./pki/*.csr ./pki/etcd/*.csr # 清理所有 CSR 文件 + +# 清理已嵌入 kubeconfig 文件中的 CRT 文件 +rm -f ./*.crt +``` + + +(可选)将 `.srl` 文件移动到下一个要处理的节点。 + +或者,如果使用外部 CA,请删除 `/etc/kubernetes/pki/ca.key` 文件, +如[外部 CA 节点](#external-ca-mode)部分中所述。 + + +### kubeadm 节点初始化 + +一旦 CSR 文件被签名并且所需的证书在要用作节点的主机上就位,你就可以使用命令 +`kubeadm init` 和 `kubeadm join` 使用这些节点创建 Kubernetes 集群。 +在 `init` 和 `join` 期间,kubeadm 使用在主机本地文件系统的 +`/etc/kubernetes` 目录中找到的现有证书、加密密钥和 kubeconfig 文件。