使用 kubeadm 创建集群
使用
kubeadm
,您可以创建一个符合最佳实践的最小可用 Kubernetes 集群。实际上,您可以使用 kubeadm
来设置一个可以通过 Kubernetes 一致性测试的集群。kubeadm
还支持其他集群生命周期功能,例如引导令牌和集群升级。
如果您需要以下功能,那么 kubeadm
工具是一个不错的选择:
- 一种简单的方式来尝试 Kubernetes,可能是第一次。
- 现有用户自动化集群搭建和测试其应用的一种方式。
- 作为范围更广的其他生态系统和/或安装工具中的构建块。
您可以在各种机器上安装和使用 kubeadm
:您的笔记本电脑、一组云服务器、树莓派等等。无论您是部署到云端还是本地,都可以将 kubeadm
集成到 Ansible 或 Terraform 等供应系统中。
开始之前
要遵循本指南,您需要
- 一台或多台运行兼容 deb/rpm 的 Linux 操作系统(例如:Ubuntu 或 CentOS)的机器。
- 每台机器 2 GiB 或更多 RAM——少于此内存将很少有剩余空间给您的应用。
- 用作控制平面节点的机器至少需要 2 个 CPU。
- 集群中所有机器之间的完整网络连接。您可以使用公共网络或私有网络。
您还需要使用能够部署您想在新集群中使用的 Kubernetes 版本的 kubeadm
版本。
Kubernetes 的版本和版本偏差支持策略 适用于 kubeadm
以及整个 Kubernetes。查阅该策略以了解支持哪些版本的 Kubernetes 和 kubeadm
。本页面是针对 Kubernetes v1.33 编写的。
kubeadm
工具的整体功能状态是全面可用 (GA)。一些子功能仍在积极开发中。随着工具的发展,创建集群的实现方式可能会略有变化,但整体实现方式应该相当稳定。
注意
根据定义,kubeadm alpha
下的任何命令都处于 alpha 级别的支持。目标
- 安装一个单控制平面 Kubernetes 集群
- 在集群上安装 Pod 网络,以便您的 Pod 可以相互通信
操作步骤
准备主机
组件安装
在所有主机上安装一个 容器运行时 和 kubeadm。有关详细说明和其他先决条件,请参阅安装 kubeadm。
注意
如果您已经安装了 kubeadm,请参阅升级 Linux 节点文档的前两个步骤,了解如何升级 kubeadm。
升级时,kubelet 每隔几秒重启一次,它会在崩溃循环中等待 kubeadm 告知它需要做什么。这个崩溃循环是预期且正常的。在您初始化控制平面后,kubelet 将正常运行。
网络设置
kubeadm 与其他 Kubernetes 组件类似,尝试在与主机上的默认网关关联的网络接口上查找可用的 IP。然后该 IP 用于组件执行的广播和/或侦听。
要找出 Linux 主机上的此 IP,您可以使用
ip route show # Look for a line starting with "default via"
注意
如果主机上存在两个或多个默认网关,Kubernetes 组件将尝试使用其遇到的第一个具有合适的全局单播 IP 地址的网关。在做出此选择时,不同操作系统和内核版本之间网关的确切顺序可能有所不同。Kubernetes 组件不接受自定义网络接口作为选项,因此对于所有需要此类自定义配置的组件实例,必须将自定义 IP 地址作为标志传递。
注意
如果主机没有默认网关,并且如果没有向 Kubernetes 组件传递自定义 IP 地址,则该组件可能会出错退出。要配置使用 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 Server(kubectl 命令行工具与之通信)。
- (推荐)如果您计划将这个单控制平面
kubeadm
集群升级到高可用性,您应该指定--control-plane-endpoint
来设置所有控制平面节点的共享端点。此端点可以是 DNS 名称或负载均衡器的 IP 地址。 - 选择一个 Pod 网络插件,并验证它是否需要向
kubeadm init
传递任何参数。根据您选择的第三方提供商,您可能需要将--pod-network-cidr
设置为提供商特定的值。请参阅安装 Pod 网络插件。 - (可选)
kubeadm
尝试使用已知端点列表检测容器运行时。要使用不同的容器运行时,或者如果在配置的节点上安装了不止一个容器运行时,请向kubeadm
指定--cri-socket
参数。有关详细信息,请参阅安装运行时。
要初始化控制平面节点,运行
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
是映射到此 IP 的自定义 DNS 名称。这将允许您将 --control-plane-endpoint=cluster-endpoint
传递给 kubeadm init
,并将相同的 DNS 名称传递给 kubeadm join
。稍后,在高可用性场景中,您可以修改 cluster-endpoint
以指向负载均衡器的地址。
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>
为了让 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
文件。建议将该文件移动到安全的位置。
请参阅为其他用户生成 kubeconfig 文件,了解如何使用 kubeadm kubeconfig user
为其他用户生成 kubeconfig 文件。
记录下 kubeadm init
输出的 kubeadm join
命令。您需要此命令将节点加入集群。
令牌用于控制平面节点和待加入节点之间的双向认证。此处包含的令牌是秘密的。请妥善保管,因为任何拥有此令牌的人都可以将已认证的节点添加到您的集群。这些令牌可以使用 kubeadm token
命令进行列出、创建和删除。请参阅 kubeadm 参考指南。
安装 Pod 网络插件
注意
本节包含关于网络设置和部署顺序的重要信息。在继续之前,请仔细阅读所有这些建议。
您必须部署一个基于容器网络接口 (CNI) 的 Pod 网络插件,以便您的 Pod 可以相互通信。在安装网络之前,集群 DNS (CoreDNS) 不会启动。
注意您的 Pod 网络不得与任何主机网络重叠:如果存在任何重叠,您很可能会遇到问题。(如果您发现您的网络插件首选的 Pod 网络与您的某些主机网络发生冲突,您应该考虑使用一个合适的 CIDR 块来代替,然后在使用
--pod-network-cidr
的kubeadm init
期间以及在您的网络插件的 YAML 文件中进行替换时使用该 CIDR 块)。默认情况下,
kubeadm
设置您的集群以使用并强制执行 RBAC(基于角色的访问控制)。确保您的 Pod 网络插件支持 RBAC,并且您用于部署它的任何 Manifest 也支持 RBAC。如果您想为集群使用 IPv6(无论是双栈还是仅 IPv6 单栈网络),请确保您的 Pod 网络插件支持 IPv6。CNI 在 v0.6.0 中添加了 IPv6 支持。
注意
Kubeadm 应该与 CNI 无关,CNI 提供商的验证超出了我们当前 e2e 测试的范围。如果您发现与 CNI 插件相关的问题,您应该在其各自的问题跟踪器中记录问题,而不是在 kubeadm 或 kubernetes 问题跟踪器中。几个外部项目使用 CNI 提供 Kubernetes Pod 网络,其中一些也支持网络策略。
查看实现了Kubernetes 网络模型的插件列表。
请参考安装插件页面,以获取 Kubernetes 支持的网络插件的不完全列表。您可以在控制平面节点或具有 kubeconfig 凭证的节点上使用以下命令安装 Pod 网络插件:
kubectl apply -f <add-on.yaml>
注意
只有少数 CNI 插件支持 Windows。更多详细信息和设置说明可在添加 Windows 工作节点中找到。每个集群只能安装一个 Pod 网络。
安装 Pod 网络后,您可以通过检查 kubectl get pods --all-namespaces
的输出中 CoreDNS Pod 是否处于 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-
添加更多控制平面节点
请参阅使用 kubeadm 创建高可用集群,了解通过添加更多控制平面节点来创建高可用 kubeadm 集群的步骤。
添加工作节点
工作节点是运行您工作负载的地方。
以下页面展示了如何使用 kubeadm join
命令将 Linux 和 Windows 工作节点添加到集群:
(可选)从控制平面节点以外的机器控制集群
为了让另一台计算机(例如笔记本电脑)上的 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 Server 代理到本地主机
如果您想从集群外部连接到 API Server,您可以使用 kubectl proxy
:
scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy
您现在可以在本地通过 http://localhost:8001/api/v1
访问 API Server。
清理
如果您使用了一次性服务器进行集群测试,您可以关闭它们,无需进一步清理。您可以使用 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 版本。此选项将控制 kube-apiserver、kube-controller-manager、kube-scheduler 和 kube-proxy 的版本。
示例:
- kubeadm 版本为 1.33
kubernetesVersion
必须为 1.33 或 1.32
kubeadm 相对于 kubelet 的偏差
与 Kubernetes 版本类似,kubeadm 可以与版本与 kubeadm 相同或旧三个版本的 kubelet 一起使用。
示例:
- kubeadm 版本为 1.33
- 主机上的 kubelet 必须是 1.33、1.32、1.31 或 1.30
kubeadm 自身的版本偏差
kubeadm 命令在由 kubeadm 管理的现有节点或整个集群上操作存在某些限制。
如果有新节点加入集群,用于 kubeadm join
的 kubeadm 二进制文件版本必须与上次用于创建集群(使用 kubeadm init
)或升级同一节点(使用 kubeadm upgrade
)的 kubeadm 版本匹配。类似的规则适用于其余 kubeadm 命令,但 kubeadm upgrade
除外。
kubeadm join 示例:
- 使用 kubeadm version 1.33 通过
kubeadm init
创建了集群 - 待加入节点必须使用版本为 1.33 的 kubeadm 二进制文件
待升级节点必须使用一个 kubeadm 版本,该版本与用于管理该节点的 kubeadm 版本相同的小版本或新一个小版本。
kubeadm upgrade 示例:
- 使用 kubeadm version 1.32 创建或升级了节点
- 用于升级节点的 kubeadm 版本必须为 1.32 或 1.33
要了解有关不同 Kubernetes 组件之间的版本偏差的更多信息,请参阅版本偏差策略。
限制
集群弹性
此处创建的集群只有一个控制平面节点,并在其上运行单个 etcd 数据库。这意味着如果控制平面节点发生故障,您的集群可能会丢失数据,并且可能需要从头重新创建。
应对方法
平台兼容性
kubeadm 的 deb/rpm 包和二进制文件是根据多平台提案为 amd64、arm(32 位)、arm64、ppc64le 和 s390x 构建的。
从 v1.12 起也支持控制平面和插件的多平台容器镜像。
只有部分网络提供商为所有平台提供解决方案。请查阅上面的网络提供商列表或查阅每个提供商的文档,以找出该提供商是否支持您选择的平台。
故障排除
如果您在使用 kubeadm 时遇到困难,请查阅我们的故障排除文档。
接下来
- 使用 Sonobuoy 验证您的集群是否正常运行
- 有关使用
kubeadm
升级集群的详细信息,请参阅升级 kubeadm 集群。 - 在 kubeadm 参考文档中了解关于高级
kubeadm
用法的信息。 - 进一步了解 Kubernetes 概念和
kubectl
。 - 关于更多 Pod 网络 附加组件 列表,请参阅集群网络页面。
- 参阅 附加组件列表以探索其他附加组件,包括用于日志、监控、网络策略、Kubernetes 集群可视化和控制的工具。
- 配置你的集群如何处理集群事件和运行在 Pod 中的应用的日志。请参阅日志架构以概述所涉及的内容。
反馈
- 关于 Bug,请访问 kubeadm GitHub issue tracker
- 关于支持,请访问 #kubeadm Slack channel
- 通用 SIG Cluster Lifecycle 开发 Slack 频道: #sig-cluster-lifecycle
- SIG Cluster Lifecycle SIG 信息
- SIG Cluster Lifecycle 邮件列表: kubernetes-sig-cluster-lifecycle