树莓派Kubernetes集群搭建实战:从零到一部署ARM架构容器平台

自2018年初涉容器编排以来,我与Kubernetes便结下了不解之缘。当时刚踏入项目一线,纵使对其充满新奇与向往,终究没能抽出足够的时间深入摸索。一年后挥别团队,那份亲手搭建完整集群的心愿暂时搁浅。直到2020年,再次迎向Kubernetes时,我已带着更扎实的工程直觉、更专注的钻研态度,方向也格外明朗。如今,我已先后拿下CKAD(认证Kubernetes应用开发者)与CKA(认证Kubernetes管理员)两项认证,后者更成为职业生涯的关键转折。作为一个从软件开发起步的技术人,要真正消化Kubernetes就必须沉到逻辑底层——把集群是怎样构建的、控制平面与工作节点如何对话、网络配置及排障原理逐一吃透。为了把知识钉在实处,我决定用手边的几块树莓派,从零起建一个ARM架构的Kubernetes集群。恰恰是这些巴掌大小的单板机,让我得以接触最贴近硬件的层面,用看得见摸得着的方式理解系统的运转。
最初这个实践只是为备考热身,可没过多久,它逐渐演变为一个实实在在的项目:一套能在家持续运行、维护成本极低、全天候可用的开发环境。本文正是这段探索的全记录。我不会在理论上过多铺陈,而是要带你穿过节点引导的迷雾,在ARM上部署功能完整的Kubernetes,重点分享那些绊过脚的坑、文档未明写的空白,以及反复试错沉淀下来的心得。无论你想搭建自己的树莓派Kubernetes实验室,还是想了解从裸机到可用集群的完整路径,这篇文章都为你写就。
关于本系列
这是系列的开篇,我将全程记录在树莓派上搭建并运维Kubernetes集群的每个细节。整个系列会逐层拆解,聚焦真实落地与严峻挑战:
- 集群创建(即本文)—— 节点引导、网络铺设,以及ARM上的Kubernetes安装
- 负载均衡与服务网格 —— 借助MetalLB实现外部可达,用Istio接管流量治理
- 存储建设 —— 为ARM构建可靠的文件服务器
- 监控栈 —— 集成Prometheus与Grafana,让可观测性贯穿系统
- 集群升级 —— 将集群平滑提升至可用的最新版本
如果你对树莓派上的Kubernetes实际应用满怀好奇,或者想深入观察一个从零设计的集群案例,请持续关注——这个系列就是为你打造的。
集群创建
硬件选型
为让配置尽可能简单,我直接使用了手头的设备,具体组合如下:
- 1 × 树莓派4 Model B(8GB内存,128GB SD卡)—— 控制平面(主节点)
- 1 × 树莓派3 Model B(1GB内存,64GB SD卡)—— 工作节点
这样的搭配对轻量级Kubernetes集群来说已绰绰有余,并且有力地印证了一个事实:理解Kubernetes的底层机制,并不需要性能怪物。
开局起步
操作系统方面,我选用Ubuntu Server 24.04 LTS(64位)。它对ARM架构的支持扎实可靠,文档丰富清晰,与各类Kubernetes工具也能无缝协作。最简单的安装方式是通过树莓派镜像生成器( raspberrypi.com/software/ )一步完成镜像烧录和操作系统预配置,免去后续大量手工折腾。

在烧录镜像之前,强烈建议使用高级配置选项完成以下事项:
- 启用SSH访问
- 填入你的Wi-Fi凭据
- 为每个节点设置主机名(例如,k8s-master、k8s-worker)
- 添加你的SSH公钥(可选,但极力推荐)
提前做完这些设置,能极大压缩后续手动干预的时间,让集群搭建效率直线上升。


首次登录
当镜像烧录完毕、树莓派通电启动后,使用SSH即可接入:
ssh <节点IP>
登录后,切换到root用户以简化后续设置步骤:
sudo -i
从此刻起,所有命令均以root身份执行,避开初始集群配置期间可能出现的权限问题。
安装集群组件与容器运行时
这一步必须在两台树莓派上执行,因为控制平面和工作节点都需要核心Kubernetes组件:
• kubelet —— 在各节点上运行并管理Pod
• kubeadm —— 引导集群
• kubectl —— 与集群交互的命令行工具
禁用交换分区(关键步骤)
默认情况下,若启用了交换内存,kubelet会拒绝启动,这是初次搭建时常见的绊脚石。Kubernetes追求可预测的资源分配,而交换分区会引入延迟和意外的调度行为,从而干扰这种可预测性。为避免隐患,需要彻底禁用交换分区:
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
内核模块与版本考量
在继续之前,强烈建议查阅与你所选版本对应的官方Kubernetes文档,尤其是关于必需内核模块和系统配置的部分。Kubernetes的安装要求一直在演进,一些曾经强制性的配置——特别是有关内核模块和网络的设置——在新版(自v1.29起尤为明显)已不再必要。这点很重要,因为大量教程和博客仍然包含过时的步骤,可能造成困惑或引入不必要的配置。参考:
https://kubernetes.io/docs/setup/production-environment/container-runtimes/#install-and-configure-prerequisites
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
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 --system
安装容器运行时(主节点与工作节点)
为了让Pod内的容器运行起来,Kubernetes需要一个容器运行时。默认情况下,Kubernetes通过容器运行时接口(CRI)与所选运行时进行交互。如果不显式指定运行时,kubeadm会尝试通过扫描已知端点列表自动探测已安装的容器运行时。一旦探测到多个运行时或者一个都没找到,kubeadm会抛出错误并要求你明确指定。我的实验环境选用了containerd作为CRI。
Containerd
我依照cri-tools仓库的步骤安装了containerd,下面列出操作过程,但遇阻时请务必查阅官方文档:
VERSION="v1.30.0" # 在 releases 页面查看最新版本
curl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-${VERSION}-linux-amd64.tar.gz --output crictl-${VERSION}-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
rm -f crictl-$VERSION-linux-amd64.tar.gz
参考:https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md
设置Docker的apt仓库:
# 添加 Docker 官方 GPG 密钥:
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gpg
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# 将仓库添加至 apt 源列表:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
安装containerd:
sudo apt-get install containerd.io
运行以下命令配置containerd:
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
确认配置是否正确,尤其注意plugins."io.containerd.grpc.v1.cri"部分。确保sandbox_image设置无误:
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
编辑配置文件时,执行以下命令,然后按需修改上述行:
sudo vi /etc/containerd/config.toml
重启containerd:
sudo systemctl restart containerd
sudo systemctl enable containerd
systemctl status containerd
启用IP转发:
sudo sh -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf"
sudo sysctl -p
用crictl验证containerd状态:
sudo crictl info
安装Kubernetes组件(v1.29)
containerd就绪、节点准备妥帖之后,下一步便是安装核心Kubernetes组件:kubelet、kubeadm和kubectl。本环境采用Kubernetes v1.29,我强烈建议遵循最新版本中引入的官方打包方式(使用全新的pkgs.k8s.io仓库)。
添加Kubernetes仓库(v1.29)
在两个节点上执行以下命令:
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gpg
添加Kubernetes签名密钥:
mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key \
| 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.29/deb/ /" \
> /etc/apt/sources.list.d/kubernetes.list
安装kubelet、kubeadm和kubectl:
apt-get update
apt-get install -y kubelet kubeadm kubectl
为集群稳定性考虑,禁止这些组件被自动升级:
apt-mark hold kubelet kubeadm kubectl
启用kubelet:
systemctl enable kubelet
此时kubelet可能处于运行状态但尚未完全就绪——这是预期行为。一旦用kubeadm引导集群,它便会正确初始化。
引导控制平面
所有组件安装完毕后,便要通过初始化控制平面让集群真正运转起来。该步骤仅在主节点(本设置中的树莓派4)上执行。
kubeadm init \
--pod-network-cidr=192.168.0.0/16
如果一切顺利,kubeadm将完成:控制平面引导、kubelet启动、证书生成,并输出类似下面的kubeadm join命令:
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
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.156:6443 --token token \
--discovery-token-ca-cert-hash sha256:hash
重要:复制下kubeadm join命令——后续添加工作节点全靠它。
使用Weave Net安装Pod网络(CNI)
控制平面初始化之后,Kubernetes需要一个CNI插件来打通Pod之间的通信。本环境选择了Weave Net——一个简单可靠、在ARM环境中表现良好的方案。在主节点上运行:
kubectl apply -f https://reweave.azurewebsites.net/k8s/v1.29/net.yaml
验证安装:
kubectl get pods -n kube-system
待CNI安装完成,Kubernetes会完成节点网络配置。
kubectl get nodes
节点状态必须为Ready。
加入工作节点
控制平面跑起来后,最后一步就是将工作节点并入集群。在工作树莓派上,重复与前面相同的组件安装步骤,包括kubeadm、kubelet、kubectl。节点准备就绪后,使用控制平面初始化时生成的kubeadm join命令:
kubeadm join <控制平面IP>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
运行加入命令后,回到控制平面节点检查情况:
kubectl get nodes
你应该看到两个节点均已列出且处于Ready状态:
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane ... v1.29.x
k8s-worker Ready <none> ... v1.29.x
如果节点未就绪
工作节点需要一段时间才能变为Ready是正常现象,尤其在树莓派这样的硬件上。如果它长时间停留在NotReady状态,常见原因包括:
- CNI插件尚未完全初始化(Weave仍在启动)
- 节点间网络不通
- kubelet未正确运行
可用以下命令进行诊断:
kubectl describe node <工作节点名称>
合理性检验
集群尽在掌控后,让我们部署一个简单应用来验证一切是否按预期协作。选用NGINX——一个轻量级Web服务器,作为快速测试负载。
创建部署:
kubectl create deployment nginx --image=nginx
查看Pod是否正在运行:
kubectl get pods
应看到类似输出:
nginx-xxxxxxxxxx-xxxxx 1/1 Running ...
总结
在树莓派上搭建这个Kubernetes集群,远不止一次朴素的家庭实验室练习。起初,它只是备考时的理想靶场,可转眼间它已进化成一个实用、全天候可用的开发环境——我可以随意实验、部署应用、积累真刀真枪的经验,恍若拥有自己的微型数据中心。这段搭建旅程,让我有机会逐层剖析Kubernetes的底层机制:弄清每个组件的职责,理清网络成形的脉络,目睹控制平面与工作节点在真实集群中的通信细节。同时,ARM架构还抛来一些在标准x86环境中罕见的挑战,这些独特的经历使整个实践变得弥足珍贵,也让理解更深了一层。
此刻,集群已全量运转:
- 树莓派上运行的控制平面
- 成功并入集群的工作节点
- 通过Weave Net完成配置的网络
- 为工作负载和探索实验备好的基础
后续展望
系列下一篇,我将引入更多核心模块,把这个基础环境扩展为更完善的平台,包括:
- 存储 —— 在ARM上为持久化工作负载搭建可靠的文件服务器
- 监控 —— 集成Prometheus与Grafana,实现集群和应用指标的全方位观测
- 负载均衡与暴露 —— 使用MetalLB将服务对外发布
- 服务网格 —— 引入Istio来精细管理服务间流量
- 集群维护 —— 升级策略、稳定性考量与长期管理
每一层都会为环境增添更多现实质感,让集群逐步蜕变为你日常开发真正可以依赖的利器。如果你正在搭建自己的树莓派Kubernetes集群,或跟随本系列深入学习,那么目标绝不止步于复制步骤——而是要对系统足够理解,直到能够根据自身需求灵活调整。