如何从零开始手动构建一个 Kubernetes 集群?

来源:网站建设作者:星河头衔:草根站长
导读:本期聚焦于星河创作的《如何从零开始手动构建一个 Kubernetes 集群?》,敬请观看详情。执行kubeadm init反复报错,到底是镜像拉不下来、cgroup驱动不匹配,还是内核模块没加载?手动构建Kubernetes集群的核心不在于把命令背下来,而在于理解每一层依赖的关系。本文以Ubuntu 22.04节点为例,从节点规划、系统参数调整、containerd运行时安装,到控制平面初始化、Calico网络插件部署、工作节点加入,完整走一遍可用集群的落地过程。文中会重点处理swap关闭、IP转发、cgroup驱动统一、镜像预拉取这些容易被忽略但直接影响成败的细节,并给出验证集群是否健康的命令。阅读完可以避开大多数新手第一次搭建时踩的坑。

从零开始手动构建Kubernetes集群,很多人以为只要执行三条命令就能完成,实际操作中却经常卡在镜像拉取超时、kubelet起不来、网络插件一直Pending这些问题上。要稳定地把集群跑起来,必须先理解Kubernetes对操作系统和容器运行时的底层要求。本文不使用云厂商托管服务,也不使用一键脚本,而是从干净的Linux节点开始,逐步完成控制平面和工作节点的配置。整个过程涉及节点规划、运行时准备、Kubernetes组件安装、网络方案部署以及集群可用性验证。

如何从零开始手动构建一个 Kubernetes 集群?

在开始之前,先明确实验环境。测试使用三台Ubuntu 22.04服务器,一台作为控制平面节点,两台作为工作节点。主机名分别为k8s-master、k8s-node1、k8s-node2。控制平面节点建议至少2核CPU和2GB内存,工作节点至少1核CPU和1GB内存。生产环境可以适当提高配置,但学习用途下这些资源足够完成基础部署。

节点规划与基础环境准备

手动构建集群的第一步不是安装Kubernetes,而是把操作系统状态调整到符合kubelet和容器运行时的要求。最重要的一项操作是关闭swap。Kubernetes的调度和资源管理假设节点内存是真实可用的,swap会导致Pod被调度到内存不足的节点后性能急剧下降。执行下面的命令关闭当前会话中的swap,并修改/etc/fstab让重启后依然生效。

# 临时关闭swap
sudo swapoff -a

# 确认swap已经被关闭
free -m

# 永久关闭swap:注释掉/etc/fstab中包含swap的行
sudo sed -i '/ swap / s/^/#/' /etc/fstab

接下来加载内核模块并调整网络参数。Kubernetes需要节点开启IP转发,并且让iptables能够正确处理经过网桥的流量。具体做法是加载overlay和br_netfilter两个模块,然后写入sysctl配置。overlay模块用于容器分层文件系统,br_netfilter用于让内核在网络桥接设备上调用iptables规则。

# 加载内核模块
sudo modprobe overlay
sudo modprobe br_netfilter

# 持久化内核模块配置
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

# 设置网络转发和桥接过滤参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

# 立即应用sysctl配置
sudo sysctl --system

容器运行时选择containerd,这是当前Kubernetes社区使用最广泛的运行时。安装containerd后需要修改它的配置文件,确保cgroup驱动与kubelet保持一致。containerd默认使用systemd作为cgroup驱动,但部分旧版本可能使用cgroupfs。如果两个组件驱动不一致,kubelet无法正确读取容器资源使用情况,节点会出现不可调度或Pod反复重启的问题。

# 安装containerd
sudo apt-get update
sudo apt-get install -y containerd

# 生成默认配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null

# 修改cgroup驱动为systemd
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

# 重启containerd
sudo systemctl restart containerd
sudo systemctl enable containerd

所有基础配置需要在每一台节点上重复执行,包括控制平面和工作节点。做完之后可以用sudo systemctl status containerd确认运行时状态。如果containerd启动失败,优先检查config.toml格式是否被sed命令破坏。另一个容易忽略的点是镜像仓库代理,国内网络环境建议配置registry mirror,但本文不展开,因为不同用户可用的加速地址差异较大。

安装Kubernetes组件并初始化控制平面

基础环境准备好以后,才能安装kubeadm、kubelet和kubectl三个核心包。kubeadm负责初始化集群和加入节点,kubelet是每个节点上运行的代理,kubectl用于与集群交互。安装时需要指定Kubernetes的软件源。这里以1.28版本为例,实际搭建时可以替换成目标版本。

# 添加Kubernetes软件源
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

# 安装组件
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

# 锁定版本,避免意外升级导致集群版本不一致
sudo apt-mark hold kubelet kubeadm kubectl

安装完成后,先不要着急执行kubeadm init。可以先通过kubeadm config images list查看需要的镜像列表,然后使用kubeadm config images pull预拉取镜像。很多用户失败在init阶段,就是因为镜像拉取缓慢或者被阻断。预拉取可以提前暴露网络问题,也方便在控制平面节点上做针对性的镜像导入。

# 查看需要使用的镜像
kubeadm config images list

# 预拉取控制平面所需镜像
sudo kubeadm config images pull

接下来初始化控制平面。--pod-network-cidr参数必须与后续选择的网络插件网段一致。使用Calico时通常设置为10.244.0.0/16,使用Flannel时也是这个网段。如果这个参数和网络插件不匹配,Pod之间无法正常通信,集群虽然启动但实际不可用。--control-plane-endpoint参数在单控制平面场景下可以省略,但生产环境建议设置为主机IP或负载均衡地址。

# 初始化控制平面
sudo kubeadm init \
  --pod-network-cidr=10.244.0.0/16 \
  --kubernetes-version=v1.28.0 \
  --upload-certs

初始化成功后会输出一段包含kubeadm join命令的文本。这段文本需要保存下来,因为工作节点加入时会用到其中的token和discovery-token-ca-cert-hash。如果token过期,可以通过kubeadm token create --print-join-command重新生成。接着管理员需要配置kubectl访问集群。对于普通用户,把admin.conf复制到用户目录并修改权限即可。

# 配置当前用户的kubectl访问权限
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 验证控制平面状态
kubectl get nodes

此时执行kubectl get nodes会看到控制平面节点处于NotReady状态,这是因为还没有部署网络插件。NotReady并不是控制平面组件有问题,而是kubelet发现节点缺少CNI网络插件,无法为Pod分配网络。下一步需要安装Calico或者Flannel来解决这个问题。

部署网络插件并加入工作节点

Kubernetes本身不提供容器网络实现,CNI插件负责Pod IP分配、跨节点路由和网络策略。Calico是生产环境常用的方案,它支持BGP路由和网络策略,性能也比较稳定。部署Calico可以使用官方清单文件,但需要确保清单中的Pod网段与kubeadm init时设置的--pod-network-cidr一致。

# 部署Calico网络插件
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml

# 查看网络插件Pod状态
kubectl get pods -n kube-system

Calico的控制平面组件包括calico-node和calico-kube-controllers。calico-node以DaemonSet方式运行在每个节点上,负责管理路由和网络接口。等待所有calico-node进入Running状态后,控制平面节点会从NotReady变为Ready。如果网络插件Pod一直Pending或CrashLoopBackOff,需要检查节点是否有多余的路由规则,以及kubelet的CNI配置目录/opt/cni/bin是否包含必要的二进制文件。

控制平面就绪后,切换两台工作节点,执行之前保存的kubeadm join命令。加入过程会自动拉取工作节点需要的镜像,并启动kubelet。工作节点不需要安装kubectl,但kubeadm和kubelet必须存在。加入成功后返回控制平面节点执行kubectl get nodes,应该能看到三台节点都在Ready状态。

# 在工作节点执行加入命令,以下为示例
sudo kubeadm join 192.168.1.10:6443 \
  --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:xxxxxx

# 回到控制平面查看节点状态
kubectl get nodes -o wide

如果加入命令提示token错误或证书校验失败,不要重复使用过期的token。在控制平面执行kubeadm token create --print-join-command可以生成新的完整命令。如果工作节点之前加入过其他集群,需要先执行sudo kubeadm reset清理旧配置,否则会发生证书冲突。

集群验证与常见问题排查

所有节点Ready之后,手动部署流程并没有结束,还需要通过实际业务Pod验证集群网络和服务发现是否正常。最简单的方式是创建一个nginx Deployment,并暴露NodePort服务,然后用节点IP加端口访问。如果访问失败,问题可能出在CNI插件、防火墙或者kube-proxy上。

# 创建测试Pod
kubectl create deployment nginx-test --image=nginx

# 扩展为多个副本,验证跨节点Pod通信
kubectl scale deployment nginx-test --replicas=2

# 暴露NodePort服务
kubectl expose deployment nginx-test --port=80 --type=NodePort

# 查看服务端口
kubectl get svc nginx-test

拿到NodePort端口后,在浏览器访问任意节点IP:端口,应该看到nginx欢迎页面。如果Pod一直处于ContainerCreating状态,先执行kubectl describe pod查看事件。常见原因包括镜像拉取失败、CNI插件未就绪、节点资源不足。如果Pod已经Running但服务无法访问,可以检查kube-proxy是否正常运行,以及iptables规则是否被本地防火墙拦截。

手动构建的集群还需要关注证书和升级问题。Kubernetes控制平面证书默认有效期为一年,超过后kubeadm需要执行续期操作。可以通过kubeadm certs check-expiration查看证书到期时间。集群升级时,应先升级控制平面,再升级工作节点,并且不允许跨多个次要版本直接跳级。这些维护操作虽然不在初次构建范围内,但知道它们的存在可以让集群生命周期管理更清晰。

# 查看证书有效期
sudo kubeadm certs check-expiration

# 续期所有证书
sudo kubeadm certs renew all

# 重启控制平面组件使新证书生效
sudo systemctl restart kubelet

整个手动构建过程下来,真正困难的不是执行kubeadm init这一步,而是前期对系统环境、容器运行时和网络插件的统一配置。很多教程只给出三条核心命令,忽略了那些导致失败的环境细节。把swap关闭、内核模块加载、cgroup驱动统一、镜像预拉取这几件事做好,再配合网络插件的正确网段,集群搭建的成功率会大幅提高。完成后可以继续部署Dashboard、Metrics Server或者Ingress Controller,逐步扩展集群的观测和入口能力。

Kubernetes集群手动部署kubeadm修改时间:2026-09-19 03:05:37

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0919/59069.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。