设置

Edit This Page

使用 kubeadm 创建一个单主集群

kubeadm 能帮助您建立一个小型的符合最佳实践的 Kubernetes 集群。通过使用 kubeadm, 您的集群会符合 Kubernetes 合规性测试的要求. Kubeadm 也支持其他的集群生命周期操作,比如升级、降级和管理启动引导令牌

因为您可以在不同类型的机器(比如笔记本、服务器和树莓派等)上安装 kubeadm,因此它非常适合与 Terraform 或 Ansible 这类自动化管理系统集成。

kubeadm 的简单便捷为大家带来了广泛的用户案例:

kubeadm 的设计初衷是为新用户提供一种便捷的方式来首次试用 Kubernetes, 同时也方便老用户搭建集群测试他们的应用。 此外 kubeadm 也可以跟其它生态系统与/或安装工具集成到一起,提供更强大的功能。

您可以很方便地在支持 rpm 或 deb 软件包的操作系统上安装 _kubeadm_。对应 kubeadm 的 SIG, SIG Cluster Lifecycle, 提供了预编译的这类安装包,当然您也可以自己基于源码为其它操作系统来构造安装包。

kubeadm 成熟程度

功能 成熟程度
命令行用户体验 beta
功能实现 beta
配置文件 API alpha
自托管 alpha
kubeadm alpha 子命令 alpha
CoreDNS GA
动态 Kubelet 配置 alpha

kubeadm 的整体功能目前还是 Beta 状态,然而很快在 2018 年就会转换成正式发布 (GA) 状态。 一些子功能,比如自托管或者配置文件 API 还在开发过程当中。 随着工具的发展,创建集群的方法可能会有所变化,但是整体部署方案还是比较稳定的。 在 kubeadm alpha 下面的任何命令都只是 alpha 状态,目前只提供初期阶段的服务。

维护周期

Kubernetes 发现版本的通常只维护支持九个月,在维护周期内,如果发现有比较重大的 bug 或者安全问题的话, 可能会发布一个补丁版本。下面是 Kubernetes 的发布和维护周期,同时也适用于 kubeadm

Kubernetes 版本 发行月份 终止维护月份
v1.6.x 2017 年 3 月 2017 年 12 月
v1.7.x 2017 年 6 月 2018 年 3 月
v1.8.x 2017 年 9 月 2018 年 6 月
v1.9.x 2017 年 12 月 2018 年 9 月
v1.10.x 2018 年 3 月 2018 年 12 月
v1.11.x 2018 年 6 月 2019 年 3 月
v1.12.x 2018 年 9 月 2019 年 6 月

准备开始

目标

步骤

在您的机器上安装 kubeadm

请查阅安装 kubeadm

Note:

注意: 如果您的机器已经安装了 kubeadm, 请运行 apt-get update && apt-get upgrade 或者 yum update 来升级至最新版本的 kubeadm.

升级过程中,kubelet 会每隔几秒钟重启并陷入了不断循环等待 kubeadm 发布指令的状态。 这个死循环的过程是正常的,当升级并初始化完成您的主节点之后,kubelet 才会正常运行。

初始化您的主节点

主节点是集群里运行控制面的机器,包括 etcd (集群的数据库)和 API 服务(kubectl CLI 与之交互)。

  1. 选择一个 Pod 网络插件,并检查是否在 kubeadm 初始化过程中需要传入什么参数。这个取决于 您选择的网络插件,您可能需要设置 --Pod-network-cidr 来指定网络驱动的 CIDR。请参阅安装网络插件
  2. (可选) 除非特别指定,kubeadm 会使用默认网关所在的网络接口广播其主节点的 IP 地址。若需使用其他网络接口,请 给 kubeadm init 设置 --apiserver-advertise-address=<ip-address> 参数。如果需要部署 IPv6 的集群,则需要指定一个 IPv6 地址,比如 --apiserver-advertise-address=fd00::101
  3. (可选) 在运行 kubeadm init 之前请先执行 kubeadm config images pull 来测试与 gcr.io 的连接。

现在运行:

kubeadm init <args> 

补充信息

想了解更多关于 kubeadm init 的参数, 请参阅kubeadm 参考指南

想了解完整的配置选项,请参阅配置文件

如果想定制控制面组件,包括为活跃性探测和 etcd 服务提供 IPv6 支持以及为各组件提供额外参数,请参阅定制参数

如果需要再次运行 kubeadm init,您必须先卸载集群

如果您需要将不同架构的节点加入您的集群,请单独在这类节点上为 kube-proxykube-dns 创建 Deployment 或 DaemonSet。 这是因为这些组件的 Docker 镜像并不支持多架构。

kubeadm init 首先会执行一系列的运行前检查来确保机器满足运行 Kubernetes 的条件。 这些检查会抛出警告并在发现错误的时候终止整个初始化进程。 然后 kubeadm init 会下载并安装集群的控制面组件,这可能会花费几分钟时间,其输出如下所示:

[init] Using Kubernetes version: vX.Y.Z
[preflight] Running pre-flight checks
[kubeadm] WARNING: starting in 1.8, tokens expire after 24 hours by default (if you require a non-expiring token use --token-ttl 0)
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [kubeadm-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.138.0.4]
[certificates] Generated apiserver-kubelet-client certificate and key.
[certificates] Generated sa key and public key.
[certificates] Generated front-proxy-ca certificate and key.
[certificates] Generated front-proxy-client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "admin.conf"
[kubeconfig] Wrote KubeConfig file to disk: "kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "scheduler.conf"
[controlplane] Wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
[controlplane] Wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
[controlplane] Wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"
[init] Waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests"
[init] This often takes around a minute; or longer if the control plane images have to be pulled.
[apiclient] All control plane components are healthy after 39.511972 seconds
[uploadconfig] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[markmaster] Will mark node master as master by adding a label and a taint
[markmaster] Master master tainted and labelled with key/value: node-role.kubernetes.io/master=""
[bootstraptoken] Using token: <token>
[bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run (as a regular user):

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a Pod network to the cluster.
Run "kubectl apply -f [Podnetwork].yaml" with one of the addon options listed at:
  http://kubernetes.io/docs/admin/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>

如果需要让普通用户可以运行 kubectl,请运行如下命令,其实这也是 kubeadm init 输出的一部分:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

或者,如果您是 root 用户,则可以运行:

export KUBECONFIG=/etc/kubernetes/admin.conf

请备份好 kubeadm init 输出中的 kubeadm join 命令,因为您会需要这个命令来给集群添加节点

令牌是主节点和新添加的节点之间进行相互身份验证的,因此请确保其安全。任何人只要知道了这些令牌,就可以随便给您的集群添加节点。 可以使用 kubeadm token 命令来列出、创建和删除这类令牌。 请参阅kubeadm 参考指南

安装 Pod 网络插件

Caution: 注意: 这一节包含了安装和部署顺序的重要信息,执行之前请仔细阅读。

您必须先安装 Pod 网络插件,以便您的 Pod 可以互相通信。

网络必须在部署任何应用之前部署好。此外,在网络安装之前是 CoreDNS 不会启用的。 kubeadm 只支持基于容器网络接口(CNI)的网络而且不支持 kubenet 。

有一些项目为 Kubernetes 提供使用 CNI 的 Pod 网络,其中一些也支持网络策略. 请参阅插件页面了解可用网络插件的完整列表。 - CNI v0.6.0 也提供了 IPv6 的支持。 - CNI 网桥local-ipam 是 Kubernetes 1.9 版本里提供的唯一支持 IPv6 的网络插件。

注意 kubeadm 默认会创建一个比较安全的集群并强制启用RBAC。 请确保您的网络方案支持 RBAC。

您可以使用下列命令安装网络插件:

kubectl apply -f <add-on.yaml>

您仅可以给任何一个集群安装一个网络插件。

请选择一个选项来查看对应的第三方网络插件驱动的安装向导。

想了解关于 Calico 的使用的更多信息, 请参阅Kubernetes上的Calico快速实践安装 Calico 实现网络策略和其他相关资源。

为了 Calico 可以正确工作,您需要给 kubeadm init 传递 --Pod-network-cidr=192.168.0.0/16 这样的选项, 或者根据您的网络方案更新 calico.yml 。注意 Calico 只适用于 amd64 架构。

kubectl apply -f https://docs.projectcalico.org/v3.7/manifests/calico.yaml

Canal 使用 Calico 提供的网络策略和 Flannel 提供的网络功能。请查阅 Calico 的官方文档 入门指引

为了 Canal 可以正确运行,kubeadm init 运行时需要设置--Pod-network-cidr=10.244.0.0/16,同时注意它只适用于 amd64 架构。

kubectl apply -f https://docs.projectcalico.org/v3.7/manifests/canal.yaml

想了解 Kubernetes 上使用 Cilium 的更多相关信息,请查参阅Kubernetes 上 Cilium 的快速指南Kubernetes 上 Cilium 的安装向导

尽管这里并不要求给 kubeadm init 设置 --Pod-network-cidr 参数,但是这是一个高度推荐操作的步骤。

这些命令会部署 Cilium 和它自己受 etcd 操作者管理的 etcd。

# 从 Cilium 库下载所需清单文件
wget https://github.com/cilium/cilium/archive/v1.2.0.zip
unzip v1.2.0.zip
cd cilium-1.2.0/examples/kubernetes/addons/etcd-operator

# 生成并部署 etcd 证书
export CLUSTER_DOMAIN=$(kubectl get ConfigMap --namespace kube-system coredns -o yaml | awk '/kubernetes/ {print $2}')
tls/certs/gen-cert.sh $CLUSTER_DOMAIN
tls/deploy-certs.sh

# 为 kube-dns 设置固定的标识标签
kubectl label -n kube-system Pod $(kubectl -n kube-system get Pods -l k8s-app=kube-dns -o jsonpath='{range .items[]}{.metadata.name}{" "}{end}') io.cilium.fixed-identity=kube-dns

kubectl create -f ./

# 等待几分钟,Cilium、coredns 和 etcd 的 Pods 会收敛到工作状态

为了让 flannel 能正确工作,您必须在运行 kubeadm init 时设置 --Pod-network-cidr=10.244.0.0/16

通过运行 sysctl net.bridge.bridge-nf-call-iptables=1/proc/sys/net/bridge/bridge-nf-call-iptables 设置成 1, 进而确保桥接的 IPv4 流量会传递给 iptables。 这是一部分 CNI 插件运行的要求条件,请查看这篇文档获取更详细信息。

注意 flannel 适用于 amd64armarm64ppc64le 架构平台。

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml

想了解更多关于 flannel 的信息,请查阅 GitHub 上的 CoreOS flannel 仓库

通过运行 sysctl net.bridge.bridge-nf-call-iptables=1/proc/sys/net/bridge/bridge-nf-call-iptables 设置成 1, 确保桥接的 IPv4 流量会传递给 iptables。 这是一部分 CNI 插件的运行条件。请查看这篇文档了解更详细的信息。

Kube-router 依赖于 kube-controller-manager 来给节点分配 CIDR, 因此需要设置 kubeadm init--Pod-network-cidr 参数。

Kube-router 提供 Pod 间联网、网络策略和和高效的基于 IPVS/LVS 的服务代理功能。

想了解关于使用 kubeadm 搭建 Kubernetes 和 Kube-router 的更多信息。请查看官方的安装指引

通过运行 sysctl net.bridge.bridge-nf-call-iptables=1/proc/sys/net/bridge/bridge-nf-call-iptables 设置成 1, 确保桥接的 IPv4 流量会传递给 iptables。这是一部分 CNI 插件的运行条件。 请查看这篇文档 获取更详细的信息。

官方的 Romana 安装指引在这里

注意,Romana 只适用于 amd64 架构。

kubectl apply -f https://raw.githubusercontent.com/romana/romana/master/containerize/specs/romana-kubeadm.yml

通过运行 sysctl net.bridge.bridge-nf-call-iptables=1/proc/sys/net/bridge/bridge-nf-call-iptables 设置成 1, 将桥接的 IPv4 流量传递给 iptables。这是一部分 CNI 插件的运行条件。 请查看这篇文档 获取更详细的信息。

官方的 Weave Net 配置向导在这里

Weave Net 适用于amd64armarm64ppc64le 而不需要其它额外的配置。 Weave Net 默认启用 hairpin 模式,可以让 Pod 在不知道他们自己的 PodIP 的时候仍可以使用服务的 IP 地址来访问他们自己。

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

提供了支持 overlay 的 SDN 解决方案,支持多云环境和混合云环境的网络方案,同时支持 overlay 和 underlay、网络策略、 网络隔离、服务链和灵活的负载均衡。

安装 JuniperContrail/TungstenFabric CNI 有很多灵活的方式。

请查阅这个安装指引

一旦 Pod 网络安装完成,您就可以通过 kubectl get Pods --all-namespaces 的输出来验证 CoreDNS Pod 是否正常运行。 只要确认了 CoreDNS 正常运行,您就可以向集群中添加节点了。

如果您的网络不能工作或者 CoreDNS 不在运行状态,请查阅查错方案

主节点隔离

出于安全原因,默认您的主节点不会被调度运行任何 Pod。 如果您需要在主节点上运行 Pod,比如说部署环境是一个单机器集群,运行:

kubectl taint nodes --all node-role.kubernetes.io/master-

输出类似这样:

node "test-01" untainted
taint "node-role.kubernetes.io/master:" not found
taint "node-role.kubernetes.io/master:" not found

这个操作会从任何有 node-role.kubernetes.io/master 这种标签的节点移除该标签,包括主节点, 标签的移除意味着集群调度器可以将 Pod 调度到任何节点。

添加节点

节点就是工作负载(容器和 Pod 等)运行的地方。如需向集群添加新节点,可以在每台机器上面执行如下操作:

如果您没有保存令牌的话,可以通过在主节点上执行下面的命令来获取:

kubeadm token list

输出类似这样:

TOKEN                    TTL  EXPIRES              USAGES           DESCRIPTION            EXTRA GROUPS
8ewj1p.9r9hcjoqgajrj4gi  23h  2018-06-12T02:51:28Z authentication,  The default bootstrap  system:
                                                   signing          token generated by     bootstrappers:
                                                                    'kubeadm init'.        kubeadm:
                                                                                           default-node-token

默认情况下,令牌会在 24 小时内过期。如果在令牌过期之后添加节点,您可以在主节点上执行下面的命令创建一个新令牌:

kubeadm token create

输出类似这样:

5didvk.d09sbcov8ph2amjw

如果您也不知道这个 --discovery-token-ca-cert-hash 的值,您也可以在主节点上运行下面的命令来获取:

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
   openssl dgst -sha256 -hex | sed 's/^.* //'

输出类似这样:

8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78
Note: 注意: 若需为 <master-ip>:<master-port> 参数设定一个 IPv6 的元组,地址必须写在一对方括号里面,比如: [fd00::101]:2073

输出类似这样:

[preflight] Running pre-flight checks

... (log output of join workflow) ...

Node join complete:
* Certificate signing request sent to master and response
  received.
* Kubelet informed of new secure connection details.

Run 'kubectl get nodes' on the master to see this machine join.

几秒钟之后,您将能在主节点上的 kubectl get nodes 的输出里发现新添加的节点。

(可选) 在非主节点上控制集群

为了能在其他机器(比如,笔记本)上使用 kubectl 来控制您的集群,您可以从主节点上复制管理员的 kubeconfig 到您的机器上,像下面这样操作:

scp root@<master ip>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf get nodes
Note:

注意: 上面的例子生效的前提是 SSH 允许 root 用户连接登录。 如果root 用户不能连接的话,您可以将 admin.conf 复制到允许其他用户访问的其他地方并将 scp 命令里的用户改成相对应的用户再复制。

这个 admin.conf 文件给予了用户整个集群的超级用户权限,因此这个操作必须小心谨慎。对于普通用户来说, 更建议创建一个适用于白名单某些权限的验证文件。您可以通过这个命令来生成 kubeadm alpha phase kubeconfig user --client-name <CN>。 这个命令会打印 KubeConfig 的内容到标准输出,然后您需要将它保存到一个文件里并分发给您的用户。然后再创建权限的白名单列表, 命令如下: kubectl create (cluster)rolebinding

(可选) 将 API 服务代理到本地

如果您需要从集群外部连接到您的 API 服务器,请运行kubectl proxy:

scp root@<master ip>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy

现在您就可以在本地访问 http://localhost:8001/api/v1 来连接 API 服务器了。

卸载集群

想要回退 kubeadm 做出的修改,您需要首先腾空节点 而且必须确保在关闭节点之前没有任何工作负载在运行。

使用正确的登录凭据来连接到主节点:

kubectl drain <node name> --delete-local-data --force --ignore-daemonsets
kubectl delete node <node name>

然后在待移除的节点上,重置所有 kubeadm 的安装状态:

kubeadm reset

如果您只是想重新运行 kubeadm init 或者 kubeadm joinkubeadm reset页面有更多的信息可供参考.

集群维护

维护集群(比如升级,降级)的详细指令,可参考这里

探索其他插件

查看插件列表来发现其他插件,包括日志、监控、网络策略、 可视化和集群管理工具等等。

后续

反馈

版本偏差策略

vX.Y 版本的 kubeadm 命令行工具可能会部署一个控制面版本为 vX.Y 或者 vX.(Y-1) 的集群,也可以用于升级一个 vX.(Y-1) 的由 kubeadm 创建的集群。 因为我们无法预见未来,版本为 vX.Y 的 kubeadm 可能可以也可能无法用于部署 vX.(Y+1) 版本的集群。 例子: kubeadm v1.8 可以用于部署 v1.7 和 v1.8 的集群,也可以升级 v1.7 的由 kubeadm 创建的集群到 1.8 版本。 请查看我们的安装向导,其中提供了关于 kubelet 和控制面版本偏差的更多信息。

跨多平台上使用 kubeadm

kubeadm 的 deb/rpm 包和可执行文件都是适用于 amd64、arm (32位)、arm64、ppc64le 和 s390x等架构平台的, 请查阅多平台方案

只有一部分的网络驱动提供了所有平台的网络解决方案,请查询上面的网络驱动列表或者对应的官方文档来确定是否支持您的平台。

局限

请注意,kubeadm 还处于正在开发的状态中,这些局限将会在适当的时间修正。

  1. 这篇文档介绍的创建的集群只能有单一的主节点和单一的 etcd 数据库,这表示如果主节点宕机,您的集群将会丢失数据 而且可能无法重新创建。目前给 kubeadm 添加高可用支持(比如多 etcd 多 API服务等等)的功能还在开发当中,因此可先参照下面的 临时解决方案: 经常性地备份 etcd。 由 kubeadm 配置的 etcd 数据位于主节点上的 /var/lib/etcd 目录。

查错

如果您在使用 kubeadm 发现任何问题,请查阅我们的纠错文档

反馈