从零搭建 K3s 混合集群:云服务器+NAS+PC 的踩坑实录
前言
最近想把我的零刻 NAS、PC 和腾讯云服务器组成一个 Kubernetes 集群,实现算力和存储的最优组合。经过一番折腾,终于成功搭起来了。本文记录完整的搭建过程和踩过的坑。
架构设计
设备清单
| 设备 | 角色 | 配置 | 说明 |
|---|---|---|---|
| 腾讯云服务器 | Control Plane | 4GB 内存 / CentOS 7 | 24h 在线,公网 IP:vpc.nnnnzs.cn |
| 零刻 NAS (linke-me-mini) | Worker Node | Debian 12 (飞牛OS) | 持久化存储,ZeroTier IP:192.168.193.194 |
| PC | Worker Node | 可用性较低,算力强 | 临时加入用于重计算任务 |
角色分配原则
-
控制平面(Server):选择腾讯云服务器,因为:
- 24h 在线,稳定性高
- 有公网 IP,方便跨地域节点接入
- 资源隔离,不会影响本地服务
-
工作节点(Agent):NAS 和 PC 作为工作节点
- NAS 提供持久化存储(NFS/Local Path)
- PC 提供强劲算力(编译、AI 推理等)
踩坑实录
坑一:版本兼容性问题
现象:
NAS 先安装了 K3s v1.35.4,服务器安装了 v1.28.10,导致 NAS 无法加入集群。
原因:
Kubernetes 要求 master 版本 ≥ worker 版本。
解决方案:
bash
# 在 NAS 上降级到与服务端匹配的版本
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_VERSION=v1.28.10+k3s1 \
INSTALL_K3S_MIRROR=cn \
sh -
坑二:内存不足导致服务频繁重启
现象:
服务器上 K3s 启动后立即崩溃,systemctl status k3s 显示 activating (auto-restart),日志里全是 context canceled 和 Closing database connections。
原因:
- 内存压力:服务器同时运行了 Java 后端服务(
scm-backend,JVM 堆内存 1GB),可用内存仅剩 900MB - 无 Swap:没有交换空间,系统内存不足时直接杀进程
- 组件启动开销:K3s 启动时需要约 500MB-1GB 内存初始化 Traefik、Metrics Server 等组件
解决方案:
-
开启 Swap(必须有!)
bash# 分配 2GB Swap sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # 永久生效 echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab -
暂时停掉内存大户
bashdocker compose down # 停止 scm-backend -
精简启动参数(禁用非必要组件)
bashcurl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \ INSTALL_K3S_MIRROR=cn \ INSTALL_K3S_EXEC="server \ --disable traefik \ --disable servicelb \ --write-kubeconfig-mode 644" \ sh -
坑三:cgroup v1/v2 冲突
现象:
日志报错:
Error: failed to validate kubelet configuration, error: kubelet is configured to not run on a host using cgroup v1. cgroup v1 support is unsupported and will be removed in a future release
原因:
K3s 新版本默认要求 cgroup v2,但 CentOS 7 内核只支持 cgroup v1。
解决方案:
bash
# 添加兼容参数
INSTALL_K3S_EXEC="server \
--disable traefik \
--disable servicelb \
--write-kubeconfig-mode 644 \
--kubelet-arg=config-confusable-cgroup-v1-with-v2=true"
坑四:systemd 配置不生效
现象:
修改了 /etc/systemd/system/k3s.service,但 ps -ef | grep k3s 显示进程完全没有加载任何参数。
原因:
systemd 的 ExecStart 多行书写格式极其敏感,反斜杠 \ 后面如果有空格会导致后续行被忽略。
解决方案:
方法一:使用环境变量(推荐)
创建 /etc/systemd/system/k3s.service.env:
K3S_EXEC="server --disable=traefik --disable=servicelb --write-kubeconfig-mode=644 --kubelet-arg=config-confusable-cgroup-v1-with-v2=true"
然后在 k3s.service 中:
ini
ExecStart=/usr/local/bin/k3s $K3S_EXEC
方法二:一行写法
ini
ExecStart=/usr/local/bin/k3s server --disable=traefik --disable=servicelb --write-kubeconfig-mode=644 --kubelet-arg=config-confusable-cgroup-v1-with-v2=true
坑五:节点地址被服务器覆盖
现象:
NAS 配置了 K3S_URL=https://192.168.80.100:6443(服务器 ZeroTier IP),但日志显示一直在尝试连接 10.0.4.2:6443(服务器内网 IP)。
原因:
K3s 的服务发现机制会自动广播服务器的「最佳 IP」。服务器有两个网卡:
- 公网/ZeroTier:
192.168.80.100 - 腾讯云内网:
10.0.4.2
服务器默认会告诉 Agent:「用 10.0.4.2 连我」,而 NAS 根本访问不到这个地址。
解决方案:
在服务器启动时强制指定对外通告地址:
bash
# 修改 /etc/systemd/system/k3s.service
INSTALL_K3S_EXEC="server \
--node-ip=192.168.80.100 \
--advertise-address=192.168.80.100 \
--disable traefik \
--disable servicelb \
--write-kubeconfig-mode 644"
参数说明:
--node-ip:绑定指定网卡--advertise-address:向其他节点通告这个 IP
重启后验证:
bash
kubectl get nodes -o wide
# 应该看到 INTERNAL-IP 变成 192.168.80.100
坑六:国内网络环境问题
现象:
- GitHub 下载极慢,经常超时
- 容器镜像拉取失败(
ErrImagePull、ImagePullBackOff)
解决方案:
-
使用国内镜像
bashINSTALL_K3S_MIRROR=cn -
配置容器镜像加速器
创建
/etc/rancher/k3s/registries.yaml:yamlmirrors: docker.io: endpoint: - "https://mirror.ccs.tencentyun.com" - "https://hub-mirror.c.163.com"
最终成功的安装流程
服务器端(Control Plane)
bash
# 1. 清理旧环境
sudo systemctl stop k3s
sudo rm -rf /var/lib/rancher/k3s
# 2. 开启 Swap(如果还没开)
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 3. 安装(带所有优化参数)
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
INSTALL_K3S_EXEC="server \
--node-ip=192.168.80.100 \
--advertise-address=192.168.80.100 \
--disable traefik \
--disable servicelb \
--write-kubeconfig-mode 644" \
sh -
# 4. 验证
sudo systemctl status k3s
kubectl get nodes -o wide
NAS 端(Worker Node)
bash
# 1. 获取服务器 Token
# 在服务器上执行:
# cat /var/lib/rancher/k3s/server/node-token
# 2. 加入集群
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_VERSION=v1.28.10+k3s1 \
INSTALL_K3S_MIRROR=cn \
K3S_URL=https://192.168.80.100:6443 \
K3S_TOKEN=K105fb7352c16cdee39f39043da59ab9dccfa257660ce36b2bd4cf32737de0a7dfc::server:3c659f37c48a02c9a14caaa70f9dbc41 \
INSTALL_K3S_EXEC="--node-name nas-worker" \
sh -
# 3. 验证
kubectl get nodes -o wide
# 应该看到两个节点:
# NAME STATUS ROLES AGE VERSION
# vm-4-2-centos Ready control-plane 10m v1.28.10+k3s1
# nas-worker Ready <none> 8m v1.28.10+k3s1
验证集群
bash
# 查看节点状态
kubectl get nodes -o wide
# 查看系统组件
kubectl get pods -A
# 部署测试应用
kubectl create deployment nginx --image=nginx:alpine --replicas=2
kubectl get pods -o wide
常用命令参考
集群管理
bash
# 查看节点
kubectl get nodes -o wide
# 查看组件
kubectl get pods -A
# 查看服务
kubectl get svc -A
# 查看事件(排查神器)
kubectl get events -A --sort-by='.lastTimestamp'
故障排查
bash
# 查看服务状态
systemctl status k3s # 服务器端
systemctl status k3s-agent # 工作节点端
# 查看实时日志(错误和警告)
journalctl -u k3s -p err..warn -f
journalctl -u k3s-agent -p err..warn -f
# 手动启动(前台运行,直接看报错)
/usr/local/bin/k3s server --disable traefik
/usr/local/bin/k3s agent -s https://192.168.80.100:6443 -t $TOKEN
彻底卸载
bash
# 服务器端
sudo /usr/local/bin/k3s-uninstall.sh
# 工作节点端
sudo /usr/local/bin/k3s-agent-uninstall.sh
# 手动清理残留(如果卸载脚本找不到)
sudo rm -rf /var/lib/rancher/k3s /etc/rancher/k3s
sudo systemctl daemon-reload
总结
搭建 K3s 集群看似简单,但在国内环境和资源受限的服务器上,踩坑几乎是不可避免的。本文记录的 6 个主要坑点,涵盖了版本兼容性、资源管理、网络配置、内核参数等多个维度。
关键经验:
- 版本对齐:master 版本必须 ≥ worker 版本
- 内存是第一生产力:小内存服务器务必开启 Swap,精简启动参数
- 地址强制:多网卡环境下务必用
--node-ip和--advertise-address固定集群通信地址 - systemd 很挑剔:多行配置用环境变量或一行写法,避免反斜杠陷阱
- 国内加速:镜像源和容器注册表都要配置国内镜像
- 验证 > 猜测:每次改动后用
kubectl get nodes验证,不要假设配置生效
现在这个混合集群已经稳定运行,接下来可以在上面部署一些有用的服务,比如:
- 存储类:NFS Provisioner 实现 NAS 存储共享
- Ingress:安装 Traefik 或 Nginx Ingress Controller
- 监控:安装 Prometheus + Grafana 监控集群状态
- CI/CD:部署 GitLab Runner 或 Jenkins 实现 CI/CD
如果你也想搭建类似的集群,希望本文能帮你少走弯路!有问题欢迎交流。