K3S实战:5分钟在树莓派上搭建轻量级Kubernetes集群(含避坑指南)
如果你和我一样,手边有几台吃灰的树莓派,总想折腾点新东西,那么把Kubernetes搬到这些小巧的ARM设备上,绝对是个充满乐趣又极具实用价值的项目。想象一下,在客厅角落的几块“小卡片”上,运行着一个功能完整的容器编排平台,管理着你的家庭自动化服务、个人网盘、媒体服务器,甚至是一个小型的开发测试环境。这听起来像是极客的浪漫,但过去,标准Kubernetes那庞大的资源消耗让树莓派望而却步。
直到K3S的出现,它彻底改变了游戏规则。这个由Rancher Labs打造的轻量级发行版,专为资源受限的边缘和物联网环境而生。它剥离了非核心组件,将整个系统打包成一个不足百兆的二进制文件,对ARM架构做了深度优化。这意味着,我们终于可以在树莓派4B甚至更早的型号上,流畅地运行一个真正的Kubernetes集群。这篇文章,我将带你从零开始,在树莓派上快速部署一个K3S集群。我会分享我踩过的坑、验证过的优化技巧,以及如何让这个集群真正为你所用,而不仅仅是一个炫技的摆设。整个过程,我们力求在5分钟内完成核心部署,剩下的时间,用来让它变得更可靠、更实用。
1. 准备工作与环境调优
在按下回车键开始安装之前,充分的准备是成功的一半。树莓派虽然强大,但其SD卡存储、ARM架构和有限的RAM,要求我们必须进行一些针对性的优化,否则后续可能会遇到各种奇怪的问题。
1.1 硬件与系统选择
首先,确认你的硬件。对于K3S,我强烈推荐使用**树莓派4B(4GB或8GB内存版本)**作为起点。树莓派3B+理论上也可以运行,但内存和CPU可能会比较紧张,更适合作为工作节点而非控制平面节点。你需要至少两块树莓派来组成一个集群(一主一从),当然,三台或更多能提供更好的体验和更高的可用性。
- 存储介质:请务必使用一张高质量的A1/A2规格的MicroSD卡,或者直接使用USB 3.0的固态硬盘(SSD)。K3S的数据库(默认是SQLite)和容器镜像的频繁读写对I/O要求不低,廉价的SD卡很容易成为性能瓶颈并提前损坏。使用SSD能极大提升集群的响应速度和稳定性。
- 网络连接:确保所有树莓派处于同一局域网内,最好通过有线网络连接。无线网络在传输稳定性和延迟上可能无法满足集群节点间的心跳和数据同步需求。
- 电源:为每台树莓派配备足额(至少5V/3A)的电源适配器,供电不足会导致设备重启,这是集群节点“失联”的常见原因。
操作系统方面,64位的 Raspberry Pi OS Lite(无桌面环境)是最佳选择。它资源占用极低,且与K3S兼容性最好。在树莓派官网下载镜像后,使用 Raspberry Pi Imager 工具刷入SD卡,记得在刷写前通过该工具的“高级选项”(齿轮图标)预先开启SSH并设置好主机名、用户名和密码,这样开机后无需连接显示器即可直接通过网络访问。
1.2 系统基础配置与优化
系统启动后,通过SSH登录每台设备,进行一系列标准化配置。以下操作在所有节点上都需要执行。
首先,更新系统并安装一些基础工具:
sudo apt update && sudo apt upgrade -y sudo apt install -y curl wget vim git接下来是几个关键的优化步骤,它们能有效避免后续的常见问题:
- 禁用交换空间(Swap):Kubernetes官方建议禁用Swap以确保kubelet正常工作。
sudo dphys-swapfile swapoff sudo dphys-swapfile uninstall sudo systemctl disable dphys-swapfile - 启用cgroups:这是容器资源管理的基石。编辑
/boot/cmdline.txt文件,在行尾添加(注意不要换行):
添加后,整行内容可能类似:cgroup_memory=1 cgroup_enable=memoryconsole=serial0,115200 console=tty1 root=PARTUUID=xxxxxx-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait cgroup_memory=1 cgroup_enable=memory - 设置静态主机名并更新
/etc/hosts:为每台树莓派设置一个独特且易记的主机名,例如k3s-master-01,k3s-worker-01。
在# 设置主机名(以master节点为例) sudo hostnamectl set-hostname k3s-master-01 # 编辑hosts文件,添加所有节点的IP和主机名映射 sudo vim /etc/hosts/etc/hosts中添加类似内容(请替换为你的实际IP):192.168.1.100 k3s-master-01 192.168.1.101 k3s-worker-01 192.168.1.102 k3s-worker-02注意:确保所有节点上的
/etc/hosts文件都包含完整的集群节点映射,这能解决初期节点间通过主机名相互发现的问题。
完成以上步骤后,重启每台树莓派以使所有配置生效。
2. 快速部署K3S主节点
环境准备就绪后,我们就可以开始真正的部署了。K3S的安装过程简洁得令人惊讶。
2.1 一键安装Master节点
在主节点(例如k3s-master-01)上,运行官方的一键安装脚本。这里我们使用国内用户更友好的方式,通过环境变量指定镜像源,以加速下载过程。
# 使用国内镜像源安装,速度更快 curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -这条命令会完成以下几件事:
- 下载K3S二进制文件和相关镜像。
- 将K3S安装为系统服务。
- 启动K3S Server(即Kubernetes的控制平面)。
- 生成一个位于
/etc/rancher/k3s/k3s.yaml的kubeconfig配置文件。
安装完成后,检查服务状态和节点信息:
sudo systemctl status k3s # 查看服务运行状态 sudo k3s kubectl get node # 使用内置的kubectl查看节点,此时应只有master自己你应该能看到主节点状态为Ready。
2.2 获取关键凭证并配置kubectl
为了让你的本地电脑(比如你的笔记本电脑)能够管理这个集群,需要获取集群的访问凭证。
首先,从主节点复制kubeconfig文件到本地,并修改其中的服务器地址:
# 在主节点上,查看配置文件内容 sudo cat /etc/rancher/k3s/k3s.yaml你会看到类似下面的内容,其中server地址是https://127.0.0.1:6443。
apiVersion: v1 clusters: - cluster: certificate-authority-data: <很长的一串证书> server: https://127.0.0.1:6443 name: default ...你需要将server字段的地址改为主节点的局域网IP,例如https://192.168.1.100:6443。然后将这个修改后的文件保存到你本地电脑的~/.kube/config(如果已有其他配置,请小心合并)。
接下来,获取用于添加工作节点的令牌(Token):
sudo cat /var/lib/rancher/k3s/server/node-token复制输出的这一长串字符串(例如K10dfe4b...::server:xxxxxx),它在添加工作节点时需要使用。
提示:出于安全考虑,在生产环境中,你应该更精细地管理这个token和kubeconfig文件,例如为不同用户创建不同权限的token。
3. 添加工作节点与集群验证
有了主节点和令牌,扩展集群就变得非常简单。
3.1 将树莓派加入集群作为Worker
在每一台要作为工作节点的树莓派上,执行以下命令。你需要替换其中的两个变量:
K3S_URL:你的主节点API Server地址,格式为https://<master_ip>:6443K3S_TOKEN:上一步获取的节点令牌
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | K3S_URL=https://192.168.1.100:6443 K3S_TOKEN=K10dfe4b...::server:xxxxxx INSTALL_K3S_MIRROR=cn sh -这个脚本会在工作节点上安装K3S Agent,并将其注册到主节点。稍等片刻,在主节点或配置好kubeconfig的本地机器上运行:
kubectl get nodes -o wide你应该能看到所有节点(包括master和worker)都处于Ready状态,并且显示了它们的内部IP和角色。
3.2 验证集群核心功能
一个健康的Kubernetes集群不仅仅是节点就绪。让我们部署一个最简单的应用来验证核心组件(网络、调度、服务发现)是否正常工作。
创建一个名为test-pod.yaml的文件:
apiVersion: v1 kind: Pod metadata: name: test-nginx spec: nodeSelector: kubernetes.io/arch: arm64 # 指定调度到ARM64节点 containers: - name: nginx image: nginx:alpine ports: - containerPort: 80应用这个配置:
kubectl apply -f test-pod.yaml然后,创建一个Service来暴露这个Pod:
kubectl expose pod test-nginx --port=80 --type=NodePort查看Service详情,获取分配的节点端口(NodePort):
kubectl get svc test-nginx输出中会有一个30000以上的端口号(例如80:32645/TCP, 其中32645就是节点端口)。现在,你可以通过访问集群中任何节点的IP地址加上这个端口号(如http://192.168.1.101:32645)来访问Nginx的欢迎页面。如果成功,说明Pod调度、网络(CNI)和服务暴露功能全部正常。
4. 深度优化与生产级考量
“5分钟搭建”只是一个开始。要让这个运行在树莓派上的集群稳定、可靠地服务于实际应用,我们还需要进行一些深度优化。
4.1 资源限制与调度策略
树莓派资源有限,必须防止单个应用“吃光”所有资源。Kubernetes的Resource Quotas和Limit Ranges是你的好朋友。
- 为命名空间设置默认资源限制:在特定的命名空间(如
default)下,创建一个LimitRange,它会自动为没有声明资源需求的Pod设置默认的请求(request)和限制(limit)。apiVersion: v1 kind: LimitRange metadata: name: default-resource-limits spec: limits: - default: cpu: "200m" memory: "256Mi" defaultRequest: cpu: "50m" memory: "64Mi" type: Container - 使用节点选择器与污点容忍:如果你的集群中有不同性能的节点(比如有的树莓派是4B,有的是3B+),你可以通过标签和污点来控制Pod的调度。
# 给性能较强的节点打上标签 kubectl label node k3s-worker-01 node-type=enhanced # 在Pod的spec中,使用nodeSelector来选择特定节点 # spec: # nodeSelector: # node-type: enhanced
4.2 存储与持久化方案
K3S默认使用local-path-provisioner,它能在节点本地路径上动态创建PV。这对于树莓派单节点测试很方便,但在多节点集群中,Pod漂移到其他节点后,数据就丢失了。对于需要持久化的数据,你有几个选择:
| 方案 | 描述 | 适用场景 | 工具/插件示例 |
|---|---|---|---|
| 网络附加存储 | 使用独立的NAS或文件服务器(如NFS) | 家庭实验室,多节点数据共享 | NFS Subdir External Provisioner |
| 节点本地存储 | 数据存储在特定节点,Pod被固定调度 | 数据不重要或可重建,追求高性能 | Local Path Provisioner (默认) |
| 分布式存储 | 在集群内构建分布式存储系统 | 高可用要求,无外部存储依赖 | Longhorn (Rancher出品,对ARM友好) |
我强烈推荐在树莓派集群中尝试Longhorn。它是一个轻量级、云原生的分布式块存储系统,本身就支持ARM架构。部署后,它能为你提供跨节点的持久卷,即使一个节点宕机,数据也不会丢失。
# 使用kubectl安装Longhorn kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.4.0/deploy/longhorn.yaml安装后,通过kubectl -n longhorn-system get pods检查所有Pod是否运行正常。
4.3 网络与Ingress配置
K3S默认使用Traefik作为Ingress Controller。它已经自动以LoadBalancer服务的形式暴露,并监听了每个节点的80和443端口。这意味着,你只需要创建Ingress资源,就可以通过节点IP直接访问服务。
例如,为之前部署的test-nginxService创建一个Ingress:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress spec: rules: - host: pi-nginx.local # 在本地hosts文件或内网DNS中解析此域名到任意节点IP http: paths: - path: / pathType: Prefix backend: service: name: test-nginx port: number: 80应用后,在你电脑的hosts文件里添加一行192.168.1.100 pi-nginx.local,然后浏览器访问http://pi-nginx.local,就能看到Nginx页面了。
4.4 避坑指南与故障排查
在实际操作中,你可能会遇到以下问题,这里提供我的解决思路:
- 节点状态一直为
NotReady:- 检查网络:确保节点间能互相ping通主机名和IP,防火墙放行了K3S所需端口(6443, 8472/UDP等)。
- 检查cgroups:确认
/boot/cmdline.txt配置已生效,重启后运行cat /proc/cgroups查看cgroup子系统是否已启用。 - 查看日志:在主节点运行
sudo journalctl -u k3s -f,在工作节点运行sudo journalctl -u k3s-agent -f,寻找错误信息。
- Pod一直处于
Pending状态:- 运行
kubectl describe pod <pod-name>,查看事件(Events)。常见原因是资源不足(Insufficient cpu/memory)或没有匹配的节点(node(s) didn‘t match Pod’s node affinity/selector)。
- 运行
- 镜像拉取失败:
- ARM架构需要对应的ARM镜像。很多官方镜像(如
nginx:alpine)是多架构的,但一些特定应用可能没有。可以使用docker.io/arm64v8/前缀的镜像,或在Dockerfile中指定--platform=linux/arm64构建。 - 配置国内镜像加速器。编辑
/etc/rancher/k3s/registries.yaml文件,配置镜像仓库镜像。
- ARM架构需要对应的ARM镜像。很多官方镜像(如
- SD卡寿命问题:
- 这是物理限制。除了换用SSD,可以通过将Docker/Containerd的数据目录挂载到RAM disk(tmpfs)来减少写入,但这会占用宝贵的内存。更根本的方法是选择高耐久度的工业级SD卡或直接使用USB SSD。
最后,记得定期备份你的K3S集群配置。最重要的备份路径是主节点的/etc/rancher/k3s/和/var/lib/rancher/k3s/server/目录。你可以编写一个简单的cron job,定期将这些目录打包并复制到网络存储或其他安全的地方。毕竟,你花时间精心调优的集群配置,其价值远超过硬件本身。