--- title: kubeadm init content_template: templates/concept weight: 20 --- {{% capture overview %}} 此命令初始化一个 Kubernetes 控制平面节点。 {{% /capture %}} {{% capture body %}} {{< include "generated/kubeadm_init.md" >}} ### Init 命令的工作流程 {#init-workflow} `kubeadm init` 命令通过执行下列步骤来启动一个 Kubernetes 控制平面节点。 1. 在做出变更前运行一系列的预检项来验证系统状态。一些检查项目仅仅触发警告,其它的则会被视为错误并且退出 kubeadm,除非问题得到解决或者用户指定了 `--ignore-preflight-errors=` 参数。 2. 生成一个自签名的 CA 证书 (或者使用现有的证书,如果提供的话) 来为集群中的每一个组件建立身份标识。如果用户已经通过 `--cert-dir` 配置的证书目录(默认为 `/etc/kubernetes/pki`)提供了他们自己的 CA 证书以及/或者密钥, 那么将会跳过这个步骤,正如文档[使用自定义证书](#custom-certificates)所述。如果指定了 `--apiserver-cert-extra-sans` 参数, APIServer 的证书将会有额外的 SAN 条目,如果必要的话,将会被转为小写。 3. 将 kubeconfig 文件写入 `/etc/kubernetes/` 目录以便 kubelet、控制器管理器和调度器用来连接到 API 服务器,它们每一个都有自己的身份标识,同时生成一个名为 `admin.conf` 的独立的 kubeconfig 文件,用于管理操作。 4. 为 API 服务器、控制器管理器和调度器生成静态 Pod 的清单文件。假使没有提供一个外部的 etcd 服务的话,也会为 etcd 生成一份额外的静态 Pod 清单文件。 静态 Pod 的清单文件被写入到 `/etc/kubernetes/manifests` 目录; kubelet 会监视这个目录以便在系统启动的时候创建 Pod。 一旦控制平面的 Pod 都运行起来, `kubeadm init` 的工作流程就继续往下执行。 1. 对控制平面节点应用 labels 和 taints 标记以便不会在它上面运行其它的工作负载。 2. 生成令牌以便其它节点以后可以使用这个令牌向控制平面节点注册它们自己。(可选),用户可以通过 `--token` 提供一个令牌,正如文档 [kubeadm token](/docs/reference/setup-tools/kubeadm/kubeadm-token/) 所述。 3. 为了使得节点能够遵照 [Bootstrap Tokens](/docs/reference/access-authn-authz/bootstrap-tokens/) 和 [TLS Bootstrap](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/) 这两份文档中描述的机制加入到集群中,kubeadm 会执行所有的必要配置: - 创建一份 ConfigMap 提供添加集群节点所需的信息,并为该 ConfigMap 设置相关的 RBAC 访问规则。 - 使得 Bootstrap Tokens 可以访问 CSR 签名 API。 - 对新的 CSR 请求配置为自动签发。 查阅[kubeadm join](/docs/reference/setup-tools/kubeadm/kubeadm-join/)文档以获取更多信息。 1. 通过 API 服务器安装一个 DNS 服务器 (CoreDNS) 和 kube-proxy 附加组件。 在 1.11 版本以及更新版本的 Kubernetes 中 CoreDNS 是默认的 DNS 服务器。 要安装 kube-dns 而不是 CoreDNS,必须在 kubeadm `ClusterConfiguration` 中配置 DNS 插件。有关配置的更多信息,请参见下面的 `Using kubeadm init with a configuration file` 一节。 请注意,尽管已部署 DNS 服务器,但直到安装 CNI 时才调度它。 ### 在 kubeadm 中使用 init phases {#init-phases} Kubeadm 允许您使用 `kubeadm init phase` 命令分阶段创建控制平面节点。 要查看阶段和子阶段的有序列表,可以调用 `kubeadm init --help`。 该列表将位于帮助屏幕的顶部,每个阶段旁边都有一个描述。 注意,通过调用 `kubeadm init`,所有阶段和子阶段都将按照此确切顺序执行。 某些阶段具有唯一的标志,因此,如果要查看可用选项的列表,请添加 `--help`,例如: ```shell sudo kubeadm init phase control-plane controller-manager --help ``` 您也可以使用 `--help` 查看特定父阶段的子阶段列表: ```shell sudo kubeadm init phase control-plane --help ``` `kubeadm init` 还公开了一个名为 `--skip-phases` 的参数,该参数可用于跳过某些阶段。参数接受阶段名称列表,并且这些名称可以从上面的有序列表中获取。 例如: ```shell sudo kubeadm init phase control-plane all --config=configfile.yaml sudo kubeadm init phase etcd local --config=configfile.yaml # 您现在可以修改控制平面和 etcd 清单文件 sudo kubeadm init --skip-phases=control-plane,etcd --config=configfile.yaml ``` 该示例将执行的操作是基于 `configfile.yaml` 中的配置在 `/etc/kubernetes/manifests` 中写入控制平面和 etcd 的清单文件。这允许您修改文件,然后使用 `--skip-phases` 跳过这些阶段。通过调用最后一个命令,您将使用自定义清单文件创建一个控制平面节点。 ### 结合一份配置文件来使用 kubeadm init {#config-file} {{< caution >}} 配置文件的功能仍然处于 alpha 状态并且在将来的版本中可能会改变。 {{< /caution >}} 通过一份配置文件而不是使用命令行参数来配置 `kubeadm init` 命令是可能的,但是一些更加高级的功能只能够通过配置文件设定。这份配置文件通过 `--config` 选项参数指定。 可以使用[kubeadm config print](/docs/reference/setup-tools/kubeadm/kubeadm-config/)命令打印出默认配置。 **推荐**使用[kubeadm config migrate](/docs/reference/setup-tools/kubeadm/kubeadm-config/)命令将旧的 `v1beta1` 版本的配置迁移到 `v1beta2` 版本。 获取 `v1beta2` 版本配置中每个字段的细节说明,查看我们的[API 参考页面](https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2)。 ### 添加 kube-proxy 参数 {#kube-proxy} kubeadm 配置中有关 kube-proxy 的说明请查看: - [kube-proxy](https://godoc.org/k8s.io/kubernetes/pkg/proxy/apis/config#KubeProxyConfiguration) 使用 kubeadm 启用 IPVS 模式的说明请查看: - [IPVS](https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/ipvs/README.md) ### 向控制平面组件传递自定义的命令行参数 {#control-plane-flags} 有关向控制平面组件传递命令行参数的说明请查看: [控制平面命令行参数](/docs/setup/production-environment/tools/kubeadm/control-plane-flags/) ### 使用自定义的镜像 {#custom-images} 默认情况下, kubeadm 会从 `k8s.gcr.io` 仓库拉取镜像。如果请求的 Kubernetes 版本是 CI label (例如 `ci/latest`),则使用 `gcr.io/kubernetes-ci-images`。 您可以通过使用[带有配置文件的 kubeadm](#config-file)来重写此操作。 允许的自定义功能有: * 使用其他的 `imageRepository` 来代替 `k8s.gcr.io`。 * 将 `useHyperKubeImage` 设置为 `true`,使用 HyperKube 镜像。 * 为 etcd 或 DNS 附件提供特定的 `imageRepository` 和 `imageTag`。 请注意配置文件中的配置项 `kubernetesVersion` 或者命令行参数 `--kubernetes-version` 会影响到镜像的版本。 ### 将控制平面证书上传到集群 通过将参数 `--upload-certs` 添加到 `kubeadm init`,您可以将控制平面证书临时上传到集群中的 Secret。请注意,此 Secret 将在 2 小时后自动过期。证书使用 32 字节密钥加密,可以使用 `--certificate-key` 指定。通过将 `--control-plane` 和 `--certificate-key` 传递给 `kubeadm join`,可以在添加其他控制平面节点时使用相同的密钥下载证书。 以下阶段命令可用于证书到期后重新上传证书: ``` kubeadm init phase upload-certs --upload-certs --certificate-key=SOME_VALUE ``` 如果未将参数 `--certificate-key` 传递给 `kubeadm init` 和 `kubeadm init phase upload-certs`,则会自动生成一个新密钥。 以下命令可用于按需生成新密钥: ``` kubeadm alpha certs certificate-key ``` ### 使用自定义的证书 {#custom-certificates} 默认情况下, kubeadm 会生成运行一个集群所需的全部证书。 你可以通过提供你自己的证书来改变这个行为策略。 如果要这样做, 你必须将证书文件放置在通过 `--cert-dir` 命令行参数或者配置文件里的 `CertificatesDir` 配置项指明的目录中。默认的值是 `/etc/kubernetes/pki`。 如果在运行 `kubeadm init` 之前存在给定的证书和私钥对,则 kubeadm 将不会重写它们。例如,这意味着您可以将现有的 CA 复制到 `/etc/kubernetes/pki/ca.crt` 和 `/etc/kubernetes/pki/ca.key` 中,而 kubeadm 将使用此 CA 对其余证书进行签名。 #### 外部 CA 模式 {#external-ca-mode} 如果只提供了 `ca.crt` 文件但是没有提供 `ca.key` 文件也是可以的 (这只对 CA 根证书可用,其它证书不可用)。 如果所有的其它证书和 kubeconfig 文件已就绪, kubeadm 检测到满足以上条件就会激活 "外部 CA" 模式。kubeadm 将会在没有 CA 密钥文件的情况下继续执行。 否则, kubeadm 将独立运行 controller-manager,附加一个 `--controllers=csrsigner` 的参数,并且指明 CA 证书和密钥。 ### 管理 kubeadm 为 kubelet 提供的 systemd 配置文件 {#kubelet-drop-in} `kubeadm` 包自带了关于 `systemd` 如何运行 `kubelet` 的配置文件。请注意 `kubeadm` 客户端命令行工具永远不会修改这份 `systemd` 配置文件。这份 `systemd` 配置文件属于 kubeadm DEB/RPM 包。 有关更多信息,请阅读[管理 systemd 的 kubeadm 内嵌文件](/docs/setup/production-environment/tools/kubeadm/kubelet-integration/#the-kubelet-drop-in-file-for-systemd)。 ### 结合 CRI 运行时使用 kubeadm 默认情况下,kubeadm 尝试检测您的容器运行环境。有关此检测的更多详细信息,请参见[kubeadm CRI 安装指南](/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-runtime)。 ### 设置节点的名称 默认情况下, `kubeadm` 基于机器的主机地址分配一个节点名称。你可以使用 `--node-name` 参数覆盖此设置。 注意覆盖主机名称可能会[干扰到云服务提供商](https://github.com/kubernetes/website/pull/8873)。 ### 在没有互联网连接的情况下运行 kubeadm 要在没有互联网连接的情况下运行 kubeadm,您必须提前拉取所需的控制平面镜像。 您可以使用 `kubeadm config images` 子命令列出并拉取镜像: ```shell kubeadm config images list kubeadm config images pull ``` kubeadm 需要的所有镜像,例如 `k8s.gcr.io/kube-*`、`k8s.gcr.io/etcd` 和 `k8s.gcr.io/pause` 都支持多种架构。 ### kubeadm 自动化 不必像文档[kubeadm 基础教程](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/)所述,将从 `kubeadm init` 取得的令牌复制到每个节点,而是简单自动地并行化令牌分发。要实现自动化,您必须知道控制平面节点启动后将拥有的 IP 地址,或使用 DNS 名称或负载均衡器的地址。 1. 生成一个令牌。这个令牌必须具有以下格式:`< 6 个字符的字符串>.< 16 个字符的字符串>`。更加正式的说法是,它必须符合以下正则表达式:`[a-z0-9]{6}\.[a-z0-9]{16}`。 kubeadm 可以为你生成一个令牌: ```shell kubeadm token generate ``` 2. 使用这个令牌同时启动控制平面节点和工作节点。它们一旦运行起来应该就会互相寻找对方并且建立集群。同样的 `--token` 参数可以同时用于 `kubeadm init` 和 `kubeadm join` 命令。 3. 当加入其他控制平面节点时,可以对 `--certificate-key` 执行类似的操作。可以使用以下方式生成密钥: ```shell kubeadm alpha certs certificate-key ``` 一旦集群启动起来,你就可以从控制平面节点的 `/etc/kubernetes/admin.conf` 文件获取管理凭证,然后你就可以使用这个凭证同集群通信。 注意这种搭建集群的方式在安全保证上会有一些宽松,因为这种方式不允许使用 `--discovery-token-ca-cert-hash` 来验证根 CA 的哈希值(因为当配置节点的时候,它还没有被生成)。获取需更多信息请参阅[kubeadm join](/docs/reference/setup-tools/kubeadm/kubeadm-join/)文档。 {{% /capture %}} {{% capture whatsnext %}} * 了解更多有关[kubeadm init phase](/docs/reference/setup-tools/kubeadm/kubeadm-init-phase/) * [kubeadm join](/docs/reference/setup-tools/kubeadm/kubeadm-join/)启动一个 Kubernetes 工作节点并且将其加入到集群 * [kubeadm upgrade](/docs/reference/setup-tools/kubeadm/kubeadm-upgrade/)将 Kubernetes 集群升级到新版本 * [kubeadm reset](/docs/reference/setup-tools/kubeadm/kubeadm-reset/)使用 `kubeadm init` 或 `kubeadm join` 来恢复对节点的变更 {{% /capture %}}