目录、参考文献
使用 kubeadm
,可以创建一个符合最佳实践的最小可行的 Kubernetes 集群
实际上,可以使用 kubeadm
设置一个能够通过 Kubernetes Conformance tests 的集群
kubeadm
还支持其他集群生命周期功能,例如 bootstrap tokens 和集群升级
kubeadm
工具能够满足以下需求:
可以在各种机器上安装 kubeadm
:笔记本电脑、云服务器、树莓派等等
无论是部署到云端还是本地,都可以将 kubeadm
集成到配置系统中,如 Ansible 或 Terraform
kubeadm
的版本必须有能力部署想要在集群中使用的 Kubernetes 版本
Kubernetes 的版本与版本差异支持策略适用于 kubeadm
以及整个 Kubernetes
本文适用于 Kubernetes v1.24
kubeadm
工具的功能特性在整体上是普遍可用的(General Availability (GA))
一些子特性仍在积极开发中
随着工具的发展,创建集群的实现可能会有一些变化,但整体实现应该是相当稳定的
注意:
任何在kubeadm alpha
下的命令,都是在 alpha 级别下得到支持的
在所有主机上安装一个容器运行时和 kubeadm
有关的详细说明和其它的先决条件,请参阅安装 kubeadm
注意:
如果已安装kubeadm
则运行apt-get update && apt-get upgrade
或yum update
获取kubeadm
的最新版本升级完成之后,
kubelet
每隔几秒钟就会重启一次
kubelet
会在 crashloop 中等待kubeadm
告诉它要做什么,crashloop 是正常的
在初始化控制平面之后,kubelet
就可以正常运行了
这一步是可选的
只有在希望 kubeadm init
与 kubeadm join
不要下载 k8s.gcr.io
上的默认容器镜像时才执行
kubeadm
有命令可以预先拉取必要的镜像,从而可以在没有互联网的节点上创建集群
详见:在没有互联网的情况下运行 kubeadm
kubeadm
允许使用自定义的镜像仓库
详见:使用自定义镜像
控制平面节点是控制平面组件运行的机器
包括:etcd(集群数据库)、API 服务器([kubectl](https://kubernetes.io/docs/reference/kubectl/)
命令行工具与其通信)
--control-plane-endpoint
参数为所有控制平面节点指定共享端点kubeadm init
传参--pod-network-cidr
参数为一个特定于供应商的值kubeadm
会尝试通过一个常见的端点列表来探测容器运行时kubeadm
参数 --cri-socket
,见安装运行时kubeadm
使用与默认网关关联的网络接口来设置此特定控制平面节点的 API 服务器的公布地址kubeadm init
参数 --apiserver-advertise-address=
--apiserver-advertise-address=fd00::101
初始化控制平面节点:
kubeadm init <args>
--apiserver-advertise-address
用来为特定控制平面节点的 API 服务器设置公布地址
--control-plane-endpoint
用来为所有控制平面节点设置共享端点
--control-plane-endpoint
允许使用 IP 地址和能够映射 IP 地址的 DNS 名称
请联系网络管理员来验证这些映射的可能解决方案
映射的例子:
192.168.0.102 cluster-endpoint
192.168.0.102
为节点的 IP 地址,cluster-endpoint
为映射这个 IP 地址的自定义 DNS 名称
可以设置 kubeadm init
参数 --control-plane-endpoint=cluster-endpoint
以及 kubeadm join
参数 cluster-endpoint
今后可以通过修改 cluster-endpoint
映射的 IP 地址,使其在高可用场景下指向负载均衡器
kubeadm
不支持将一个创建时没有使用 --control-plane-endpoint
指定共享端点的单个控制平面集群转换为一个高可用集群
关于 kubeadm init
参数的更多信息见:kubeadm 参考指南
用配置文件配置 kubeadm init
的方法见:通过配置文件使用 kubeadm init
要自定义控制平面组件,需要为每个组件提供额外的参数,见:自定义参数
例如:为控制平面组件与 etcd 服务器的存活状态监测探针分配可选的 IPv6 地址
对一个已经创建好的集群进行配置,见:重新配置一个 kubeadm 集群
要再次运行 kubeadm init,必须先拆除集群
要将具有不同架构的节点加入集群
请确保部署的 DaemonSet 具有该架构的容器映像支持
kubeadm init
首先会运行一系列的预监测,以确保机器准备好运行 Kubernetes
这些预检测会显示警告并在遇到错误时退出
然后 kubeadm init
会下载并安装集群控制平面组件
完成后你应该看到:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following 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 options listed at:
/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
要让非 root 用户也可以使用 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
对admin.conf
中的证书进行签名时
将其配置为Subject: O = system:masters, CN = kubernetes-admin system:masters
是一个例外的超级用户组,可以绕过鉴权层(如 RBAC)
不要将admin.conf
文件与任何人共享
应该通过kubeadm kubeconfig user
命令为其他用户生成kubeconfig
文件,以授予他们自定义权限
详见为其他用户生成 kubeconfig 文件
可以将 kubeadm init
输出的 kubeadm join
命令记录下来
这些命令可以用来向集群添加节点
可以使用令牌(token)手动地在控制平面节点与正在加入的节点之间进行鉴权
这里的令牌是密钥,请确保它的安全,因为拥有令牌的人可以将已鉴权的节点添加到集群中
可以用 kubeadm token
命令列出、创建、删除令牌
见 kubeadm 参考指南
必须部署一个基于容器网络接口(Container Network Interface (CNI))的 Pod 网络插件
这样 Pod 才能互相通信
在网络安装完成之前,容器 DNS(CoreDNS)无法启动
1)Pod 网络不能与任何主机网络重叠,如果有任何重叠,可能会出现问题
如果发现网络插件的首选 Pod 网络与某些主机网络之间存在冲突
应该考虑使用合适的 CIDR 块
在 kubeadm init
上使用 --pod-network-cidr
参数来代替网络插件 YAML 中的配置
2)kubeadm
默认将集群设置为强制使用基于角色的访问控制(role based access conrol (RBAC))
请确保 Pod 网络插件支持 RBAC,任何用来部署 Pod 网络插件的清单也必须支持 RBAC
3)如果要使用 IPv6,无论是双协议栈还是单 IPv6 协议栈
请确保集群的 Pod 网络插件支持 IPv6
CNI 在 v0.6.0 开始支持 IPv6
注意:
kubeadm
应该与 CNI 解耦,对 CNI 供应商的验证目前不在kubeadm
的端到端测试范围之内
如果发现与 CNI 插件相关的问题,应该在插件供应商对应的 issue 跟踪器中记录
而不是在kubeadm
或kubernetes
的 issue 跟踪器中记录
一些外部项目使用 CNI 来提供 Kubernetes Pod 网络,其中一些还支持网络策略
请参阅实现了 Kubernetes 网络模型的插件列表
可以使用以下命令在控制平面节点或具有 kubeconfig
凭据的节点上安装 Pod 网络插件:
kubectl apply -f <add-on.yaml>
可以在每个集群上只安装一个 Pod 网络
安装 Pod 网络后,可以通过检查在 kubectl get pods --all-namespaces
的输出中 CoreDNS Pod 是否为 Running
来确认 Pod 网络是否正常运行
一旦 CoreDNS Pod 启用并运行,就可以继续向集群加入节点
如果网络没有正常工作或 CoreDNS 不在 Running
状态
请查看 kubeadm
的故障排除指南
kubeadm
会默认启用 NodeRestriction 准入控制器来限制 kubelet
在节点注册时可以应用哪些标签
准入控制器文档描述了 kubelet
的 --node-labels
选项可以使用哪些标签
其中 node-role.kubernetes.io/control-plane
标签就是一个受限制的标签
kubeadm
在节点创建后使用特权客户端手动应用此标签
可以使用一个有特权的 kubeconfig
,比如由 kubeadm
管理的 /etc/kubernetes/admin.conf
通过执行 kubectl label
来手动应用标签
默认情况下,出于安全原因,集群不会在控制平面节点上调度 Pod
如果希望能够在控制平面节点上调度 Pod,如单机 Kubernetes 集群,请运行:
kubectl taint nodes --all node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master-
输出:
node "test-01" untainted
...
这将从拥有 node-role.kubernetes.io/control-plane
与 node-role.kubernetes.io/master
污点(taint)的节点上移除它们,包括控制平面节点
这意味着调度程序将能够在任何地方调度 Pod
注意:
node-role.kubernetes.io/master
污点(taint)已弃用
kubeadm
将在 1.25 版本中停止使用它
节点是工作负载(容器与 Pod 等)运行的地方
要添加节点,请对待添加的机器执行以下操作:
SSH 连接机器
成为 root 用户(即:sudo su -
)
必要时安装一个运行时
运行 kubeadm init
输出的命令,如:
kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
如果没有 token,可以通过在控制平面运行以下命令获取:
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
默认情况下,token 24 小时失效
如果在将节点加入到集群时,token 失效了
可以通过在控制平面运行下边的命令创建一个新 token
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
注意:
为指定 IPv6 元组
:
必须将 IPv6 地址括在方括号中,如:[fd00::101]:2073
输出:
[preflight] Running pre-flight checks
... (log output of join workflow) ...
Node join complete:
* Certificate signing request sent to control-plane and response
received.
* Kubelet informed of new secure connection details.
Run 'kubectl get nodes' on control-plane to see this machine join.
几秒钟后,在控制平面节点上执行 kubectl get nodes
时,会注意到该节点出现在输出中
注意:
由于集群节点通常是按顺序初始化的,CoreDNS Pod 很可能都运行在第一个控制平面节点上
为了提供更高的可用性
请在加入新节点后使用kubectl -n kube-system rollout restart deployment coredns
命令
以重新平衡这些 CoreDNS Pod
为了使 kubectl
在其它计算机(如笔记本电脑)上与集群通信
需要将管理员 kubeconfig
文件从控制平面节点复制到工作站:
scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf get nodes
注意:
上面的示例假设为 root 用户启用了 SSH 访问权限
如果没有,可以先将admin.conf
复制一份,让复制可以被其它用户访问
然后scp
命令用这个用户来进行远程复制
admin.conf
文件为用户提供了对集群的超级用户特权,应谨慎使用
对于普通用户,建议生成一个为其授予特权的唯一证书
可以使用kubeadm alpha kubeconfig user --client-name
命令执行此操作
该命令会将 KubeConfig 文件打印到标准输出,应该将其保存到文件并分发给用户
之后,使用kubectl create (cluster)rolebinding
授予特权
想要从集群外部连接到 API 服务器,可以用 kubectl proxy
:
scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy
现在可以在本地访问 API 服务器 http://localhost:8001/api/v1
如果集群中使用了一次性服务器进行测试,可以关闭这些服务器,而无需进一步的清理
可以使用 kubectl config delete-cluster
删除对集群的本地引用
如果要更干净地撤销集群配置, 则应首先清空节点并确保该节点为空, 然后再取消节点配置
用正确的凭证与控制平面通信:
kubectl drain <node name> --delete-emptydir-data --force --ignore-daemonsets
在删除节点前,先重置 kubeadm
安装的状态:
kubeadm reset
重置进程不会重置或清理 iptables 规则或 IPVS 表
如想重置 iptables,必须手动执行:
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
要重置 IPVS 表,必须运行:
ipvsadm -C
删除节点:
kubectl delete node <node name>
如想重新开始,只需运行 kubeadm init
或 kubeadm join
并加上适当的参数
可以在控制平面主机上使用 kubeadm reset
来触发尽力而为的清理
有关 reset
子命令及其选项的更多信息,见 kubeadm reset 参考文献
虽然 kubeadm
允许所管理的组件有一定程度的版本差异
但建议将 kubeadm
的版本与控制平面组件、kube-proxy
和 kubelet
的版本相匹配
kubeadm
可用于与自己相同版本的或旧一个版本的 Kubernetes 组件
Kubernetes 的版本可以通过使用 kubeadm init
的 --kubernetes-version
标志
或使用 --config
时的 [ClusterConfiguration.kubernetesVersion](https://kubernetes.io/docs/reference/config-api/kubeadm-config.v1beta3/)
字段指定给 kubeadm
这个选项将控制 kube-apiserver
、kube-controller-manager
、kube-scheduler
和 kube-proxy
的版本
例如:
kubeadm
的版本为 1.24kubernetesVersion
必须为 1.24 或者 1.23kubeadm
命令如何在现有节点或由 kubeadm
管理的整个集群上运行,存在着一些限制
如果有新的节点要加入集群
用于 kubeadm join
的 kubeadm
二进制文件必须与用 kubeadm init
创建集群时
或用 kubeadm upgrade
升级同一节点时所用的 kubeadm
版本一致
类似的规则也适用于除了 kubeadm upgrade
以外的其他 kubeadm
命令
kubeadm join
的例子:
kubeadm init
创建集群时使用的版本为 1.24 的 kubeadm
kubeadm
二进制文件对于正在升级的节点
使用的 kubeadm
版本必须与管理该节点的 kubeadm
有相同的小版本或新一个小版本
kubeadm upgrade
的例子:
kubeadm
创建的某个节点或升级过该节点kubeadm
版本必须为 1.23 或 1.24要了解更多关于不同 Kubernetes 组件之间的版本差异,见版本差异策略
前边创建的集群只有一个控制平面节点,上边运行了一个 etcd 数据库
如果控制平面节点挂了,集群可能会丢失数据,并且可能需要从头开始重新创建集群
解决方法:
定期备份 etcd
kubeadm
配置的 etcd 数据目录位于控制平面节点上的 /var/lib/etcd
使用多个控制平面节点
请阅读两种高可用拓扑选择一个提供了高可用性的集群拓扑
kubeadm deb/rpm 软件包和二进制文件是为 amd64、arm (32-bit)、arm64、ppc64le 和 s390x 构建的
遵循多平台提案
从 v1.12 开始还支持用于控制平面和插件的多平台容器镜像
只有部分网络提供商为所有平台提供了解决方案
请查阅上方的网络供应商清单或每个供应商的文档以确定供应商是否支持对应的平台
kubeadm
升级集群的详细信息,见升级 kubeadm 集群kubeadm
的进阶用法目录、参考文献