Edit This Page

kubeadm init

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

运行这个命令来搭建Kubernetes master节点

简介

运行这个命令来搭建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 master 节点。

  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、controller-manager 和 scheduler 用来连接到 API server,它们每一个都有自己的身份标识,同时生成一个名为 admin.conf 的独立的 kubeconfig 文件,用于管理操作。
  1. 如果 kubeadm 被调用时附带了 --feature-gates=DynamicKubeletConfig 参数, 它会将 kubelet 的初始化配置写入 /var/lib/kubelet/config/init/kubelet 文件中。 参阅 通过配置文件设置 Kubelet 参数以及 在一个现有的集群中重新配置节点的 Kubelet 设置来获取更多关于动态配置 Kubelet 的信息。 这个功能现在是默认关闭的,正如你所见它通过一个功能开关控制开闭, 但是在未来的版本中很有可能会默认启用。
  1. 为 API server、controller manager 和 scheduler 生成静态 Pod 的清单文件。假使没有提供一个外部的 etcd 服务的话,也会为 etcd 生成一份额外的静态 Pod 清单文件。

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

一旦 control plane 的 Pods 都运行起来, kubeadm init 的工作流程就继续往下执行。

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

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

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

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

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

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

结合一份配置文件来使用 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 页面]。 (https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1)

添加 kube-proxy 参数

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

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

向 control plane 组件传递自定义的 flags

有关向 control plane 组件传递 flags 的说明请查看: - control-plane-flags

使用自定义的镜像

默认情况下, 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

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

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

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

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

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

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

设置节点的名称

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

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

Self-hosting Kubernetes control plane

从1.8开始, 你可以试验性地创建一个 self-hosted Kubernetes control plane. 这意味着诸如 API server、controller manager、 以及 scheduler 这些关键组件将作为通过 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 版本中的 Self-hosting 功能有一些重要的限制。特别的, 一个 self-hosted 的集群如果不手动介入的话 不能够从 master node 的重新启动中恢复 。 这个以及其它的一些限制被期望在 self-hosting 功能从 alpha 状态毕业前解决。

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

Caution:

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

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

流程

self-hosting 集群的启动过程写在了这份 kubeadm 设计文档 文档中。

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

1. 等待 control plane 的相关组件成功运行起来。这与没有启用 self-hosting 的 kubeadm init 指令的流程是一致的。

2. 使用静态的 control plane Pod 清单文件构建一个 DaemonSet 清单文件用来运行 self-hosted control plane。有时也会在必要的时候修改这些清单文件,比如为 secrets 添加新的数据卷。

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

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

5. 当原始的 static control plane 停止的时候, 新创建的 self-hosted control plane 就能够绑定到端口并且可供使用。

这个过程 (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 取得的令牌拷贝到每一个节点, 倒不如你可以使用更加简单的自动化的方式将令牌并行地分发出去。如果要实现这个自动化,你必须要知道 master node 启动后的 IP 地址。

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

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

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

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

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

What's next

Feedback