使用 kubeadm 创建集群
使用
kubeadm
,您可以创建一个符合最佳实践的最小可行 Kubernetes 集群。实际上,您可以使用 kubeadm
设置一个集群,该集群将通过 Kubernetes 符合性测试。kubeadm
还支持其他集群生命周期功能,例如 引导令牌 和集群升级。
如果您需要以下功能,则 kubeadm
工具非常适合您
- 一种简单的方法,让您第一次尝试 Kubernetes。
- 一种方法,让现有用户自动设置集群并测试他们的应用程序。
- 其他生态系统和/或安装工具(具有更大范围)中的构建块。
您可以在各种机器上安装和使用 kubeadm
:您的笔记本电脑、一组云服务器、树莓派等等。无论您是部署到云还是本地,您都可以将 kubeadm
集成到诸如 Ansible 或 Terraform 之类的配置系统中。
开始之前
要遵循本指南,您需要
- 一台或多台运行 deb/rpm 兼容的 Linux 操作系统的机器;例如:Ubuntu 或 CentOS。
- 每台机器至少 2 GiB 的 RAM——任何更少的 RAM 都会给您的应用程序留下很少的空间。
- 在您用作控制平面节点的机器上至少有 2 个 CPU。
- 集群中所有机器之间具有完全的网络连接。您可以使用公共或私有网络。
您还需要使用一个版本的 kubeadm
,该版本可以部署您想要在新集群中使用的 Kubernetes 版本。
Kubernetes 的版本和版本偏差支持策略 也适用于 kubeadm
以及 Kubernetes 本身。查看该策略以了解哪些版本的 Kubernetes 和 kubeadm
受支持。本页面针对 Kubernetes v1.31 编写。
kubeadm
工具的总体功能状态为通用可用性 (GA)。一些子功能仍在积极开发中。创建集群的实现可能会随着工具的演变而略有改变,但总体实现应该相当稳定。
注意
kubeadm alpha
下的任何命令,根据定义,都支持 alpha 级别的功能。目标
- 安装单个控制平面 Kubernetes 集群
- 在集群上安装 Pod 网络,以便您的 Pod 可以相互通信
说明
准备主机
组件安装
在所有主机上安装 容器运行时 和 kubeadm。有关详细说明和其他先决条件,请参阅 安装 kubeadm。
注意
如果您已经安装了 kubeadm,请参阅 升级 Linux 节点 文档的前两个步骤,了解有关如何升级 kubeadm 的说明。
升级时,kubelet 每隔几秒钟就会重启,因为它在崩溃循环中等待 kubeadm 告知它该做什么。此崩溃循环是预期行为且正常的。在您初始化控制平面后,kubelet 将正常运行。
网络设置
与其他 Kubernetes 组件类似,kubeadm 会尝试在与主机上的默认网关相关联的网络接口上找到一个可用的 IP。然后,该 IP 将用于组件执行的广告和/或侦听。
要在 Linux 主机上找出此 IP 是什么,您可以使用
ip route show # Look for a line starting with "default via"
注意
如果主机上存在两个或多个默认网关,Kubernetes 组件将尝试使用它遇到的第一个具有合适的全局单播 IP 地址的网关。在进行此选择时,网关的确切顺序可能会因不同的操作系统和内核版本而异。Kubernetes 组件不接受自定义网络接口作为选项,因此必须将自定义 IP 地址作为标志传递给需要此类自定义配置的所有组件实例。
注意
如果主机没有默认网关,并且没有将自定义 IP 地址传递给 Kubernetes 组件,该组件可能会退出并显示错误。要为使用 init
和 join
创建的控制平面节点配置 API 服务器广告地址,可以使用标志 --apiserver-advertise-address
。最好在 kubeadm API 中将其设置为 InitConfiguration.localAPIEndpoint
和 JoinConfiguration.controlPlane.localAPIEndpoint
。
对于所有节点上的 kubelet,可以在 kubeadm 配置文件(InitConfiguration
或 JoinConfiguration
)中的 .nodeRegistration.kubeletExtraArgs
中传递 --node-ip
选项。
对于双栈,请参阅 使用 kubeadm 的双栈支持。
分配给控制平面组件的 IP 地址将成为其 X.509 证书的主题备用名称字段的一部分。更改这些 IP 地址需要签名新的证书并重新启动受影响的组件,以便证书文件的更改得到反映。有关此主题的更多详细信息,请参阅 手动证书续订。
警告
Kubernetes 项目不建议使用这种方法(使用自定义 IP 地址配置所有组件实例)。相反,Kubernetes 维护人员建议设置主机网络,以便默认网关 IP 是 Kubernetes 组件自动检测和使用的 IP。在 Linux 节点上,您可以使用诸如ip route
之类的命令来配置网络;您的操作系统也可能提供更高级的网络管理工具。如果您的节点的默认网关是公用 IP 地址,您应该配置数据包过滤或其他安全措施来保护节点和您的集群。准备所需的容器镜像
此步骤是可选的,仅在您希望 kubeadm init
和 kubeadm join
不下载托管在 registry.k8s.io
上的默认容器镜像时才适用。
Kubeadm 具有可以帮助您在创建集群时预先拉取所需镜像的命令,而无需其节点上的互联网连接。有关更多详细信息,请参阅 在没有互联网连接的情况下运行 kubeadm。
Kubeadm 允许您为所需的镜像使用自定义镜像仓库。有关更多详细信息,请参阅 使用自定义镜像。
初始化您的控制平面节点
控制平面节点是运行控制平面组件的机器,包括 etcd(集群数据库)和 API 服务器(kubectl 命令行工具与其通信)。
- (推荐)如果您计划将此单个控制平面
kubeadm
集群升级到高可用性,您应该指定--control-plane-endpoint
来设置所有控制平面节点的共享端点。此类端点可以是 DNS 名称或负载均衡器的 IP 地址。 - 选择一个 Pod 网络插件,并验证它是否需要向
kubeadm init
传递任何参数。根据您选择的第三方提供商,您可能需要将--pod-network-cidr
设置为特定于提供商的值。请参阅 安装 Pod 网络插件。 - (可选)
kubeadm
会尝试使用一系列众所周知的端点来检测容器运行时。要使用不同的容器运行时,或者如果在预配的节点上安装了多个容器运行时,请将--cri-socket
参数指定给kubeadm
。请参阅 安装运行时。
要初始化控制平面节点,请运行
kubeadm init <args>
有关 apiserver-advertise-address 和 ControlPlaneEndpoint 的注意事项
--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
是一个自定义 DNS 名称,它映射到此 IP。这将允许您将 --control-plane-endpoint=cluster-endpoint
传递给 kubeadm init
并将相同的 DNS 名称传递给 kubeadm join
。稍后,您可以修改 cluster-endpoint
以指向高可用性方案中负载均衡器的地址。
将没有 --control-plane-endpoint
创建的单个控制平面集群转换为高可用性集群不受 kubeadm 支持。
更多信息
有关 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>
要使 kubectl 对您的非 root 用户有效,请运行以下命令,这些命令也是 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
生成的 kubeconfig 文件 admin.conf
包含一个证书,其 Subject: O = kubeadm:cluster-admins, CN = kubernetes-admin
。组 kubeadm:cluster-admins
绑定到内置的 cluster-admin
ClusterRole。不要与任何人共享 admin.conf
文件。
kubeadm init
生成另一个 kubeconfig 文件 super-admin.conf
,其中包含一个证书,其 Subject: O = system:masters, CN = kubernetes-super-admin
。system:masters
是一个破坏性超级用户组,它绕过授权层(例如 RBAC)。不要与任何人共享 super-admin.conf
文件。建议将该文件移动到安全位置。
有关如何使用 kubeadm kubeconfig user
为其他用户生成 kubeconfig 文件,请参阅 为其他用户生成 kubeconfig 文件.
记录 kubeadm init
输出的 kubeadm join
命令。您需要此命令来 将节点加入集群.
令牌用于控制平面节点和加入节点之间的相互身份验证。这里包含的令牌是机密的。请妥善保管,因为任何拥有此令牌的人都可以将经过身份验证的节点添加到您的集群中。这些令牌可以使用 kubeadm token
命令列出、创建和删除。请参阅 kubeadm 参考指南.
安装 Pod 网络插件
注意
本节包含有关网络设置和部署顺序的重要信息。在继续之前,请仔细阅读所有这些建议。
您必须部署基于 容器网络接口 (CNI) 的 Pod 网络插件,以便您的 Pod 能够相互通信。集群 DNS (CoreDNS) 只有在安装网络后才会启动。
请注意,您的 Pod 网络不能与任何主机网络重叠:如果存在任何重叠,您可能会遇到问题。(如果您发现网络插件首选的 Pod 网络与您的一些主机网络之间存在冲突,您应该考虑使用合适的 CIDR 块,然后在
kubeadm init
中使用--pod-network-cidr
使用它,并将其替换为网络插件的 YAML 文件中)。默认情况下,
kubeadm
会将您的集群设置为使用并强制使用 RBAC(基于角色的访问控制)。请确保您的 Pod 网络插件支持 RBAC,并且您用于部署它的任何清单也支持 RBAC。如果您想对集群使用 IPv6(双栈或单栈 IPv6 网络),请确保您的 Pod 网络插件支持 IPv6。IPv6 支持在 v0.6.0 中添加到 CNI。
注意
Kubeadm 应该是与 CNI 无关的,并且 CNI 提供商的验证不在我们当前的 e2e 测试范围之内。如果您发现与 CNI 插件相关的任何问题,您应该在相应的错误跟踪器中记录问题,而不是在 kubeadm 或 Kubernetes 错误跟踪器中记录问题。许多外部项目使用 CNI 提供 Kubernetes Pod 网络,其中一些项目还支持 网络策略.
请参阅实施 Kubernetes 网络模型 的插件列表。
请参阅 安装插件 页面,了解 Kubernetes 支持的网络插件的非详尽列表。您可以在控制平面节点或具有 kubeconfig 凭据的节点上使用以下命令安装 Pod 网络插件
kubectl apply -f <add-on.yaml>
每个集群只能安装一个 Pod 网络。
安装 Pod 网络后,您可以通过检查 CoreDNS Pod 是否在 kubectl get pods --all-namespaces
的输出中处于 Running
状态来确认它是否正常工作。一旦 CoreDNS Pod 运行起来,您就可以继续加入您的节点。
如果您的网络无法正常工作或 CoreDNS 未处于 Running
状态,请查看 kubeadm
的 故障排除指南.
托管节点标签
默认情况下,kubeadm 会启用 NodeRestriction 准入控制器,该控制器限制 kubelet 在节点注册时可以自我应用的标签。准入控制器文档涵盖了允许使用 kubelet --node-labels
选项使用哪些标签。node-role.kubernetes.io/control-plane
标签是这种受限制的标签,kubeadm 在创建节点后使用特权客户端手动应用该标签。要手动执行此操作,您可以使用 kubectl label
执行相同的操作,并确保它使用特权 kubeconfig(例如 kubeadm 托管的 /etc/kubernetes/admin.conf
)。
控制平面节点隔离
默认情况下,出于安全原因,您的集群不会在控制平面节点上调度 Pod。如果您想能够在控制平面节点上调度 Pod,例如对于单机 Kubernetes 集群,请运行
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
输出将类似于
node "test-01" untainted
...
这将从任何带有该标签的节点(包括控制平面节点)中删除 node-role.kubernetes.io/control-plane:NoSchedule
污点,这意味着调度程序将能够在任何地方调度 Pod。
此外,您可以执行以下命令以从控制平面节点中删除 node.kubernetes.io/exclude-from-external-load-balancers
标签,该标签将其从后端服务器列表中排除
kubectl label nodes --all node.kubernetes.io/exclude-from-external-load-balancers-
加入您的节点
节点是您的工作负载(容器和 Pod 等)运行的地方。要将新节点添加到集群中,请对每台机器执行以下操作
SSH 到机器
成为 root(例如
sudo su -
)如果需要,安装运行时
运行
kubeadm init
输出的命令。例如kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
如果您没有令牌,可以通过在控制平面节点上运行以下命令获取它
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
注意
要为<control-plane-host>:<control-plane-port>
指定 IPv6 元组,IPv6 地址必须用方括号括起来,例如:[2001:db8::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 kubeconfig user --client-name <CN>
命令来完成此操作。该命令将打印一个 KubeConfig 文件到 STDOUT,您应该将该文件保存到一个文件中并分发给您的用户。之后,使用 kubectl create (cluster)rolebinding
授予权限。
(可选)将 API 服务器代理到本地主机
如果您想从集群外部连接到 API 服务器,可以使用 kubectl proxy
scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy
您现在可以在 http://localhost:8001/api/v1
上本地访问 API 服务器
清理
如果您在测试中使用了一次性服务器作为您的集群,您可以关闭它们,无需进一步清理。您可以使用 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
来触发尽力而为的清理。
有关此子命令及其选项的更多信息,请参阅 kubeadm reset
参考文档。
版本偏差策略
虽然 kubeadm 允许针对它管理的某些组件进行版本偏差,但建议您将 kubeadm 版本与控制平面组件、kube-proxy 和 kubelet 的版本相匹配。
kubeadm 与 Kubernetes 版本的偏差
kubeadm 可以与与 kubeadm 版本相同或低一个版本的 Kubernetes 组件一起使用。可以使用 kubeadm init
的 --kubernetes-version
标志或使用 --config
时使用 ClusterConfiguration.kubernetesVersion
字段将 Kubernetes 版本指定给 kubeadm。此选项将控制 kube-apiserver、kube-controller-manager、kube-scheduler 和 kube-proxy 的版本。
示例
- kubeadm 版本为 1.31
kubernetesVersion
必须为 1.31 或 1.30
kubeadm 与 kubelet 的版本偏差
与 Kubernetes 版本类似,kubeadm 可以与与 kubeadm 版本相同或低三个版本的 kubelet 版本一起使用。
示例
- kubeadm 版本为 1.31
- 主机上的 kubelet 必须为 1.31、1.30、1.29 或 1.28
kubeadm 与 kubeadm 的版本偏差
kubeadm 命令在由 kubeadm 管理的现有节点或整个集群上进行操作时存在一些限制。
如果将新节点加入集群,则用于 kubeadm join
的 kubeadm 二进制文件必须与用于使用 kubeadm init
创建集群或使用 kubeadm upgrade
升级同一节点的 kubeadm 的最后一个版本匹配。除 kubeadm upgrade
外,其他 kubeadm 命令也适用类似的规则。
kubeadm join
示例
- kubeadm 版本 1.31 用于使用
kubeadm init
创建集群 - 加入节点必须使用版本为 1.31 的 kubeadm 二进制文件
要升级的节点必须使用与用于管理节点的 kubeadm 版本相同或高一个次要版本的 kubeadm 版本。
kubeadm upgrade
示例
- kubeadm 版本 1.30 用于创建或升级节点
- 用于升级节点的 kubeadm 版本必须为 1.30 或 1.31
要详细了解不同 Kubernetes 组件之间的版本偏差,请参阅 版本偏差策略。
限制
集群弹性
此处创建的集群具有一个控制平面节点,以及在该节点上运行的一个 etcd 数据库。这意味着如果控制平面节点出现故障,您的集群可能会丢失数据,并且可能需要从头开始重新创建。
解决方法
定期 备份 etcd。由 kubeadm 配置的 etcd 数据目录位于控制平面节点上的
/var/lib/etcd
。
平台兼容性
kubeadm deb/rpm 软件包和二进制文件是针对 amd64、arm(32 位)、arm64、ppc64le 和 s390x 构建的,遵循 多平台提案。
自 v1.12 开始,还支持用于控制平面和附加组件的多平台容器镜像。
并非所有平台都提供网络提供商的解决方案。请咨询上面的网络提供商列表或每个提供商的文档,以确定提供商是否支持您选择的平台。
故障排除
如果您在使用 kubeadm 时遇到困难,请咨询我们的 故障排除文档。
下一步
- 使用 Sonobuoy 验证您的集群是否正常运行
- 请参阅 升级 kubeadm 集群,了解有关使用
kubeadm
升级集群的详细信息。 - 在 kubeadm 参考文档 中了解高级
kubeadm
用法 - 详细了解 Kubernetes 概念 和
kubectl
。 - 请参阅 集群网络 页面,了解 Pod 网络附加组件的更完整列表。
- 请参阅 附加组件列表,探索其他附加组件,包括用于日志记录、监控、网络策略、可视化和控制 Kubernetes 集群的工具。
- 配置集群如何处理集群事件和 Pod 中运行的应用程序的日志。有关所涉及内容的概述,请参阅 日志记录体系结构。
反馈
- 有关错误,请访问 kubeadm GitHub 问题跟踪器
- 有关支持,请访问 #kubeadm Slack 频道
- 通用 SIG 集群生命周期开发 Slack 频道:#sig-cluster-lifecycle
- SIG 集群生命周期 SIG 信息
- SIG 集群生命周期邮件列表:kubernetes-sig-cluster-lifecycle