参考

Kubernetes v1.13 版本的文档已不再维护。您现在看到的版本来自于一份静态的快照。如需查阅最新文档,请点击 最新版本。

Edit This Page

kubeadm init

此命令初始化一个 Kubernetes 主节点

简介

运行此命令来搭建 Kubernetes 主节点。

kubeadm init [flags]

参数可选项

--apiserver-advertise-address string
API Server 将要广播的监听地址。如指定为 `0.0.0.0` 将使用缺省的网卡地址。
--apiserver-bind-port int32     缺省值: 6443
API Server 绑定的端口
--apiserver-cert-extra-sans stringSlice
可选的额外提供的证书主题别名(SANs)用于指定API Server的服务器证书。可以是IP地址也可以是DNS名称。
--cert-dir string     缺省值: "/etc/kubernetes/pki"
证书的存储路径。
--config string
kubeadm 配置文件的路径。警告:配置文件的功能是实验性的。
--cri-socket string     缺省值: "/var/run/dockershim.sock"
指明要连接的 CRI socket 文件
--dry-run
不会应用任何改变;只会输出将要执行的操作。
--feature-gates string
键值对的集合,用来控制各种功能的开关。可选项有:
Auditing=true|false (当前为 ALPHA 状态 - 缺省值=false)
CoreDNS=true|false (缺省值=true)
DynamicKubeletConfig=true|false (当前为 BETA 状态 - 缺省值=false)
-h, --help
获取 init 命令的帮助信息
--ignore-preflight-errors stringSlice
忽视检查项错误列表,列表中的每一个检查项如发生错误将被展示输出为警告,而非错误。 例如: 'IsPrivilegedUser,Swap'. 如填写为 'all' 则将忽视所有的检查项错误。
--kubernetes-version string     缺省值: "stable-1"
为 control plane 选择一个特定的 Kubernetes 版本。
--node-name string
指定节点的名称。
--pod-network-cidr string
指明 pod 网络可以使用的IP地址段。 如果设置了这个参数,control plane 将会为每一个节点自动分配 CIDRs。
--service-cidr string     缺省值: "10.96.0.0/12"
为 service 的虚拟IP地址另外指定IP地址段
--service-dns-domain string     缺省值: "cluster.local"
为 services 另外指定域名, 例如: "myorg.internal".
--skip-token-print
不打印出由 `kubeadm init` 命令生成的默认令牌。
--token string
这个令牌用于建立主从节点间的双向受信链接。格式为 [a-z0-9]{6}\.[a-z0-9]{16} - 示例: abcdef.0123456789abcdef
--token-ttl duration     缺省值: 24h0m0s
令牌被自动删除前的可用时长 (示例: 1s, 2m, 3h). 如果设置为 '0', 令牌将永不过期。

从父命令继承的选项参数

--rootfs string
[实验性的功能] 相对“真实”宿主机根目录的路径。

Init 命令的工作流程

kubeadm init 命令通过执行下列步骤来启动一个 Kubernetes 主节点。

  1. 在做出变更前运行一系列的预检项来验证系统状态。 一些检查项目仅仅触发警告,其它的则会被视为错误并且退出 kubeadm,除非问题被解决或者用户指定了 --ignore-preflight-errors=<list-of-errors> 参数。
  1. 生成一个自签名的 CA 证书 (或者使用现有的证书,如果提供的话) 来为集群中的每一个组件建立身份标识。如果用户已经通过 --cert-dir 配置的证书目录(缺省值为 /etc/kubernetes/pki)提供了他们自己的 CA证书 以及/或者 密钥, 那么将会跳过这个步骤,正如文档使用自定义证书中所描述的那样。 如果指定了 --apiserver-cert-extra-sans 参数, APIServer 的证书将会有额外的 SAN 条目,如果必要的话,将会被转为小写。
  1. 将 kubeconfig 文件写入 /etc/kubernetes/ 目录以便 kubelet、控制器管理器和调度器用来连接到 API 服务器,它们每一个都有自己的身份标识,同时生成一个名为 admin.conf 的独立的 kubeconfig 文件,用于管理操作。
  1. 如果 kubeadm 被调用时附带了 --feature-gates=DynamicKubeletConfig 参数, 它会将 kubelet 的初始化配置写入 /var/lib/kubelet/config/init/kubelet 文件中。 参阅 通过配置文件设置 Kubelet 参数以及 在一个现有的集群中重新配置节点的 Kubelet 设置来获取更多关于动态配置 Kubelet 的信息。 这个功能现在是默认关闭的,正如你所见它通过一个功能开关控制开闭, 但是在未来的版本中很有可能会默认启用。
  1. 为 API 服务器、控制器管理器和调度器生成静态 Pod 的清单文件。假使没有提供一个外部的 etcd 服务的话,也会为 etcd 生成一份额外的静态 Pod 清单文件。

静态 Pod 的清单文件被写入到 /etc/kubernetes/manifests 目录; kubelet 会监视这个目录以便在系统启动的时候创建 Pods。

一旦控制平面的 Pods 都运行起来, kubeadm init 的工作流程就继续往下执行。

  1. 如果 kubeadm 被调用时附带了 --feature-gates=DynamicKubeletConfig 参数, 它将创建一份 ConfigMap 和一些便于 kubelet 访问这份 ConfigMap 的 RBAC 规则,并且通过将 Node.spec.configSource 指向到新创建的 ConfigMap 来更新节点设置。这样它就完成了对 Kubelet 的动态配置。 这个功能现在是默认关闭的,正如你所见它通过一个功能开关控制开闭, 但是在未来的版本中很有可能会默认启用。
  1. 对主节点应用标签和污点标记以便不会在它上面运行其它的工作负载。
  1. 生成令牌以便其它节点以后可以使用这个令牌向主节点注册它们自己。 可选的,用户可以通过 --token 提供一个令牌, 正如文档 kubeadm 的令牌 描述的那样。
  1. 为了使得节点能够遵照 Bootstrap TokensTLS Bootstrap这两份文档中描述的机制加入到集群中,kubeadm 会执行所有的必要配置:

    • 创建一份 ConfigMap 提供添加集群节点所需的信息,并为该 ConfigMap 设置相关的 RBAC 访问规则。

    • 使得 Bootstrap Tokens 可以访问 CSR 签名 API。

    • 对新的 CSR 请求配置为自动签发。

查阅 kubeadm join 文档以获取更多信息。

  1. 通过 API 服务器安装一个 DNS 服务器 (CoreDNS) 和 kube-proxy 附加组件。 在 1.11 版本以及更新版本的 Kubernetes 中 CoreDNS 是默认的 DNS 服务器。 如果要安装 kube-dns 而不是 CoreDNS, 你需要在调用 kubeadm 的时候附加 --feature-gates=CoreDNS=false 参数。请注意,尽管 DNS 服务器已经被部署了,它并不会被调度直到你安装好了 CNI 网络插件。
  1. 如果调用 kubeadm init 命令时启用了 alpha 状态的自托管功能(--feature-gates=SelfHosting=true),基于静态 Pod 的控制平面将被转换为 自托管的控制平面

结合一份配置文件来使用 kubeadm init

Caution:

注意: 配置文件的功能仍然处于 alpha 状态并且在将来的版本中可能会改变。

通过一份配置文件而不是使用命令行参数来配置 kubeadm init 命令是可能的,并且一些更加高级的功能只能够通过配置文件设定。 这份配置文件通过 --config 选项参数指定。

在 Kubernetes 1.11 以及之后的版本中,默认的配置可以通过 kubeadm config print-default 命令打印出来。 推荐使用 kubeadm config migrate 命令将你的旧的 v1alpha3 版本的配置迁移到 v1beta1 版本。因为在 Kubernetes 1.14 版本中将会移除对 v1alpha3 这个版本的支持。

如果你想获取 v1beta1 版本配置中每个字段的细节说明,你可以查看我们的 API reference 页面

添加 kube-proxy 参数

kubeadm 配置中有关 kube-proxy 的说明请查看: - kube-proxy

使用 kubeadm 启用 IPVS 模式的说明请查看: - IPVS

向控制平面组件传递自定义的命令行参数

有关向控制平面组件传递命令行参数的说明请查看: - 控制平面命令行参数

使用自定义的镜像

默认情况下, kubeadm 会从 k8s.gcr.io 仓库拉取镜像, 除非请求的 Kubernetes 版本是一个持续集成版本。在这种情况下,则会使用 gcr.io/kubernetes-ci-images 仓库。

你可以通过这份文档里描述的方法 结合一份配置文件来使用 kubeadm 来改变镜像拉取的策略。 允许的自定义功能有:

请注意配置文件中的配置项 kubernetesVersion 或者命令行参数 --kubernetes-version 会影响到镜像的版本。

使用自定义的证书

默认情况下, kubeadm 会生成运行一个集群所需的全部证书。 你可以通过提供你自己的证书来改变这个行为策略。

如果要这样做, 你必须将证书文件放置在通过 --cert-dir 命令行参数或者配置文件里的 CertificatesDir 配置项指明的目录中。默认的值是 /etc/kubernetes/pki

如果给定的证书和密钥对已经存在,kubeadm 将会跳过生成证书的步骤并且直接将已经存在的文件用于规定的案例中。也就是说你可以拷贝一份已存在的 CA 文件到 /etc/kubernetes/pki/ca.crt/etc/kubernetes/pki/ca.key,kubeadm 将会使用这份 CA 来签发其余的证书。

外部 CA 模式

如果只提供了 ca.crt 文件但是没有提供 ca.key 文件也是可以的 (这只对 CA 根证书可用,其它证书不可用)。 如果所有的其它证书和 kubeconfig 文件已就位, kubeadm 检测到满足以上条件就会激活 “外部 CA” 模式。 kubeadm 将会在没有 CA 密钥文件的情况下继续执行。

否则, kubeadm 将独立运行 controller-manager,附加一个 --controllers=csrsigner 的参数,并且指明 CA 证书和密钥。

管理 kubeadm 为 kubelet 提供的 systemd 配置文件

kubeadm 包自带了关于 kubelet 应该如何运行的配置文件。请注意 kubeadm 客户端命令行工具永远不会修改这份 systemd 配置文件。这份 systemd 配置文件属于 kubeadm deb/rpm 包。

这份文件应该看起来像这样:

[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true"
Environment="KUBELET_NETWORK_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local"
Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook --client-ca-file=/etc/kubernetes/pki/ca.crt"
Environment="KUBELET_CADVISOR_ARGS="
Environment="KUBELET_CERTIFICATE_ARGS=--rotate-certificates=true --cert-dir=/var/lib/kubelet/pki"
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_AUTHZ_ARGS $KUBELET_CADVISOR_ARGS $KUBELET_CERTIFICATE_ARGS $KUBELET_EXTRA_ARGS

以下是这份文件的详解:

结合 CRI 运行时使用 kubeadm

从 v1.6.0 版本开始, Kubernetes 默认启用了 CRI, 容器运行时接口。 默认使用的容器运行时是 Docker, 这通过 kubelet 内置的 dockershim CRI 实现支持。

其它的基于 CRI 的运行时包括:

查阅 CRI 安装指南 获取更多信息。

在你成功安装了 kubeadmkubelet 工具后, 执行这两个额外的步骤:

  1. 遵照以上列出的 runtime shim 项目中的安装文档,在每一个节点上安装 runtime shim。
  1. 配置 kubelet 使用远程 CRI 运行时。对应你自己环境,请记得改变 RUNTIME_ENDPOINT 的值,这个值类似 /var/run/{your_runtime}.sock:
cat > /etc/systemd/system/kubelet.service.d/20-cri.conf <<EOF
[Service]
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=$RUNTIME_ENDPOINT"
EOF
systemctl daemon-reload

现在 kubelet 已经准备好使用指定的 CRI 运行时了, 你可以继续使用 kubeadm initkubeadm join 工作流来部署你的 Kubernetes 集群。

当使用一个外部的 CRI 实现时, 你也许也想为 kubeadm initkubeadm reset 设置 --cri-socket

在你的集群中使用内网 IP

为了配置一个主节点与工作节点间使用内网 IP 地址通信的集群(而不是使用公网地址),执行以下操作。

  1. 当运行 init 命令的时候, 你必须为 API 服务器指定一个内网 IP 作为监听地址,像这样:

kubeadm init --apiserver-advertise-address=<private-master-ip>

  1. 当一个主节点或者工作节点可供使用时,向 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 文件添加一个标记指明工作节点的私有 IP。

--node-ip=<private-node-ip>

  1. 最后, 当你运行 kubeadm join 的时候, 确保你提供了正确的 API 服务器所在的、步骤 1 中定义的私有 IP。

设置节点的名称

默认情况下, kubeadm 基于机器的 host 地址分配一个节点名称。你可以使用 --node-name 参数覆盖这个设置。 这个参数会向 kubelet 传递相应的 --hostname-override 参数。

注意覆盖主机名称可能会 干扰到云服务提供商

自托管的 Kubernetes 控制平面

从1.8开始, 你可以试验性地创建一个 self-hosted Kubernetes 控制平面。 这意味着诸如 API 服务器、控制器管理器、 以及调度器这些关键组件将作为通过 Kubernetes API 配置的 DaemonSet pods 运行,而不是在 kubelet 中通过静态文件配置的 static pods

若要创建一个 self-hosted 的集群, 向 kubeadm init 命令传递 --feature-gates=SelfHosting=true 参数。

Caution:

小心: SelfHosting 还是一个 alpha 功能。它在 1.12 版本中被标记为废弃,并且将在 1.13 版本中移除。

Warning:

警告: 查看有关 self-hosted 的注意事项和限制。

注意事项

1.8 版本中的自托管功能有一些重要的限制。特别的, 一个自托管的集群如果不手动介入的话 不能够从主节点的重新启动中恢复 。 这个以及其它的一些限制被期望在自托管功能从 alpha 状态毕业前解决。

默认情况下, self-hosted 控制平面 Pods 依赖位于 hostPath 数据卷中的证书。除了初始化创建证书的过程, 这些证书不被 kubeadm 管理。你可以使用 --feature-gates=StoreCertsInSecrets=true 参数来启用一个试验性的模式,在这个模式中控制平面证书从 Secrets 加载。 这要求对你的集群进行非常小心的对鉴权和授权配置的控制, 并且可能并不适合你的环境。

Caution:

小心: StoreCertsInSecrets 是一个 alpha 功能。 它在 1.12 版本中被标记为废弃,并且将在 1.13 版本中移除。

在 kubeadm 1.8 版本中, 控制平面的 self-hosted 的组件并不包含 etcd,它仍然是作为静态 Pod 运行的。

流程

自托管集群的启动过程写在了这份 kubeadm 设计文档 文档中。

总的说来, kubeadm init --feature-gates=SelfHosting=true 是按照以下步骤工作的:

1. 等待控制平面的相关组件成功运行起来。这与没有启用自托管的 kubeadm init 指令的流程是一致的。

1. 使用静态的控制平面 Pod 清单文件构建一个 DaemonSet 清单文件用来运行自托管的控制平面。有时也会在必要的时候修改这些清单文件,比如为 secrets 添加新的数据卷。

3. 在 kube-system 命名空间下创建 DaemonSets 并且等待相应的 Pods 运行起来。

4. 一旦 self-hosted Pods 可供使用了, 它们相关的静态 Pods 就会被删除并且 kubeadm 继续安装下一个组件。这将触发 kubelet 停止这些静态 Pods。

5. 当原始的基于静态 Pod 的控制平面停止的时候, 新创建的自托管的控制平面就能够绑定到端口并且可供使用。

这个过程 (3-6步) 也可以通过 kubeadm phase selfhosting convert-from-staticpods 指令触发。

在没有互联网连接的情况下运行 kubeadm

如果要在没有网络的情况下运行 kubeadm,你需要预先拉取所选版本的主要镜像:

Image Name v1.10 release branch version
k8s.gcr.io/kube-apiserver-${ARCH} v1.10.x
k8s.gcr.io/kube-controller-manager-${ARCH} v1.10.x
k8s.gcr.io/kube-scheduler-${ARCH} v1.10.x
k8s.gcr.io/kube-proxy-${ARCH} v1.10.x
k8s.gcr.io/etcd-${ARCH} 3.1.12
k8s.gcr.io/pause-${ARCH} 3.1
k8s.gcr.io/k8s-dns-sidecar-${ARCH} 1.14.8
k8s.gcr.io/k8s-dns-kube-dns-${ARCH} 1.14.8
k8s.gcr.io/k8s-dns-dnsmasq-nanny-${ARCH} 1.14.8
coredns/coredns 1.0.6

此处 v1.10.x 意为 “v1.10 分支上的最新的 patch release”。

${ARCH} 可以是以下的值: amd64, arm, arm64, ppc64le 或者 s390x

如果你运行1.10或者更早版本的 Kubernetes,并且你设置了 --feature-gates=CoreDNS=true, 你必须也使用 coredns/coredns 镜像, 而不是使用三个 k8s-dns-* 镜像。

在 Kubernetes 1.11版本以及之后的版本中,你可以使用 kubeadm config images 的子命令来列出和拉取相关镜像:

kubeadm config images list
kubeadm config images pull

从 Kubernetes 1.12 版本开始, k8s.gcr.io/kube-*k8s.gcr.io/etcdk8s.gcr.io/pause 镜像不再要求 -${ARCH} 后缀。

kubeadm 自动化

与其如文档 kubeadm 基础教程 所述,将从 kubeadm init 取得的令牌拷贝到每一个节点, 倒不如你可以使用更加简单的自动化的方式将令牌并行地分发出去。如果要实现这个自动化,你必须要知道主节点启动后的 IP 地址。

  1. 生成一个令牌. 这个令牌必须具有以下格式:<6个字符的字符串>.<16字符的字符串>。更加正式地说法是,它必须符合以下正则表达式: [a-z0-9]{6}\.[a-z0-9]{16}

    kubeadm 可以为你生成一个令牌:

    kubeadm token generate
  1. 使用这个令牌同时启动主节点和工作节点。它们一旦运行起来应该就会互相寻找对方并且建立集群。同样的 --token 参数可以同时用于 kubeadm initkubeadm join 命令。

一旦集群启动起来,你就可以从主节点的 /etc/kubernetes/admin.conf 文件获取管理凭证,然后你就可以使用这个凭证同集群通信了。

注意这种搭建集群的方式在安全保证上会有一些宽松,因为这种方式不允许使用 --discovery-token-ca-cert-hash 来验证根 CA 的哈希值(因为当配置节点的时候,它还没有被生成)。如需更多信息,请参阅 kubeadm join 文档。

接下来

反馈