☰
从裸机到双K8s集群:60TB存储与18台服务器的家庭实验室搭建实战
2026/9/25 20:28:47 网站建设 项目流程

1. 缘起:为什么我要在家里塞下60TB和18台服务器

先交个底,这套东西不是一天建成的,也不是一拍脑袋就买的。我从最早一台蜗牛星际矿渣机开始折腾NAS,到后来慢慢添置二手服务器、组K8s集群,前后大概花了三年多时间。目前家里常驻的算力设备是18台,其中真正跑业务的大概12台,剩下的是备用节点和测试机;存储池裸容量60TB出头,可用容量在45TB上下;网络侧是双K8s集群,一个跑生产级自建服务,一个专门用来做破坏性实验。

很多人第一次听到这个规模会问同一个问题:你一个人用得着吗?说实话,纯从“用”的角度,一台四盘位NAS加一台迷你主机就够了。但我做这套东西的核心目的不是“用”,而是“练”和“验证”。K8s集群搭建、服务器虚拟化、对象存储服务、GPU算子调度这些技能,你在公司里能碰到的永远是别人搭好的环境,你只能在外围打转。只有自己从裸机开始,从BIOS、RAID、网络桥接、存储池、容器运行时一层层往上搭,才会真正理解一个分布式系统在出问题的时候,故障是怎么传导的。

所以这篇导览不是炫配置,而是把我这几年踩过的坑、做过的取舍、以及2026年当下这套环境的真实状态,完整地摊开讲一遍。适合谁来读?如果你正在考虑搭自己的家庭实验室,或者你已经在跑K8s但想扩展到多节点、带GPU、带大容量存储,那这篇内容应该能帮你少走至少半年的弯路。如果你只是好奇“60TB到底能装什么”,那也可以当一篇配置参考来看。

先给一个整体轮廓,方便你建立空间感:

类别数量/容量主要用途
计算节点18台K8s工作节点、虚拟化宿主、GPU推理
存储裸容量60TBNAS、对象存储、备份池
K8s集群2套生产集群、实验集群
GPU2块推理、算子验证
网络2.5G+10G混合存储内网、业务外网分离

下面我按“整体设计思路 → 核心细节 → 实操过程 → 问题排查”这个顺序展开,每一块都会讲清楚我为什么这么选,以及你如果照做需要注意什么。

2. 整体设计与思路拆解

2.1 为什么是“双集群”而不是一个大集群

一开始我也想过把所有节点塞进一个K8s集群,用namespace做隔离。但实际跑下来发现两个致命问题。第一,实验性操作会污染生产环境。K8s的很多故障是集群级别的,比如etcd压力过大、CNI插件配置错误、kube-proxy规则异常,这些一旦发生,整个集群的Pod网络都会抖。你不可能在跑着自建服务的集群上随便改CNI配置。第二,资源争抢不可控。实验集群经常要跑一些吃满CPU和内存的压测任务,如果和生产Pod混在一起,QoS再怎么做也会互相影响。

所以最终方案是物理隔离:生产集群3台控制面加5台工作节点,实验集群1台控制面加3台工作节点,剩下的机器做虚拟化宿主和存储。两个集群共用一套物理网络,但VLAN隔离,存储流量走独立的10G内网。这个设计的好处是,实验集群我可以随便折腾,哪怕把etcd搞崩了,生产集群完全不受影响。

提示:如果你预算有限只能搭一个集群,至少要把控制面和etcd单独放,不要和工作负载混部。etcd对磁盘IO延迟极其敏感,一旦和工作负载抢磁盘,整个集群的API响应会变得非常慢。

2.2 存储分层:为什么不用一套存储打天下

60TB听起来很多,但如果全部做成一个池子,性能和管理都会出问题。我的做法是分三层:

第一层是高速池,用NVMe SSD做缓存和热数据,容量大概4TB,跑数据库、etcd、容器镜像仓库。第二层是容量池,用机械盘做RAIDZ2,容量约40TB,跑NAS共享、媒体库、备份。第三层是对象存储池,用MinIO做S3兼容接口,容量约16TB,专门给K8s里的应用做持久化后端。

为什么对象存储要单独一层?因为K8s里的有状态应用如果用PVC挂块存储,迁移和扩容都很麻烦。而S3接口的好处是应用无状态化,Pod漂到哪个节点都能访问同一份数据。MinIO在家庭环境里足够用,单节点多盘模式就能跑出不错的吞吐。如果你考虑替代者,Ceph也能做,但Ceph的运维复杂度在家庭环境里是灾难级的,我试过一轮就放弃了。

2.3 网络设计:2.5G和10G怎么分配

网络这块我走过最大的弯路就是一开始全用千兆。千兆跑NAS勉强够,但一旦涉及K8s节点间的etcd同步、镜像拉取、存储复制,立刻成为瓶颈。后来我改成混合方案:管理网和业务网走2.5G,存储内网走10G。存储内网用一台二手万兆交换机单独组网,不经过主路由。

这样做的理由是,存储流量是东西向流量,特点是突发大、持续时间长,如果和上网流量混在一起,家里其他人看视频都会卡。独立组网之后,存储复制可以跑满万兆,同时不影响外网访问。DDNS配合动态公网地址访问NAS的需求,也通过主路由的端口转发单独处理,和存储内网完全隔离。

3. 核心细节解析与实操要点

3.1 服务器选型:二手企业级还是全新迷你主机

这是每个搭家庭实验室的人都会纠结的问题。我的答案是:混合使用。核心存储和虚拟化宿主用二手企业级服务器,比如Dell R730、HP DL380 G9这类,优点是内存槽多、盘位多、带IPMI远程管理,缺点是噪音大、功耗高。边缘计算节点和实验节点用迷你主机,比如N100、N305的小机器,优点是安静省电,缺点是扩展性差。

具体到我的18台:4台企业级2U做虚拟化和存储,8台迷你主机做K8s工作节点,3台做控制面,剩下3台是各种测试机。这个配比是经过多次调整的。早期我全是企业级,结果电费一个月多出好几百,后来把轻负载全部迁到迷你主机,电费直接降了一半。

注意:买二手服务器一定要检查RAID卡电池和硬盘背板。我遇到过RAID卡电池失效导致写缓存被禁用,存储性能直接掉到十分之一。另外IPMI固件要升级到最新,老版本有安全漏洞。

3.2 K8s集群搭建:kubeadm还是二进制

网上关于K8s安装部署的教程很多,k8s权威指南第五版pdf下载也是热搜词,但真正动手的时候,第一个选择就是安装方式。我的建议是:生产集群用kubeadm,实验集群用二进制或者k3s。

kubeadm的好处是标准化,升级路径清晰,社区支持好。缺点是隐藏了很多细节,出问题的时候你不知道底层发生了什么。所以我建议你在实验集群里用二进制方式手动装一遍,把etcd、apiserver、controller-manager、scheduler、kubelet、kube-proxy一个个启动起来,理解它们之间的证书和通信关系。装完一遍之后,再用kubeadm装生产集群,这时候你对整个体系的理解完全不一样。

具体到版本选择,2026年当下建议用1.30以上的版本,因为1.29之后很多API已经稳定,比如Gateway API、Pod Scheduling Readiness这些。容器运行时用containerd,不要再用Docker了,K8s 1.24之后已经移除dockershim,继续用Docker只会给自己找麻烦。

3.3 GPU接入:两块显卡怎么分配给K8s

我手上有两块GPU,一块是NVIDIA RTX 4060 Laptop GPU,一块是Intel UHD Graphics。前者跑CUDA推理,后者跑一些轻量级的视频转码和OpenVINO推理。在K8s里接入GPU需要装device plugin,NVIDIA的插件叫k8s-device-plugin,Intel的用intel-device-plugins-operator。

这里有个坑:RTX 4060 Laptop GPU是移动版核心,驱动和桌面版不完全一样。pytorch安装教程gpu里通常讲的是桌面版,你如果照着装可能会遇到驱动版本不匹配。我的做法是先装NVIDIA官方驱动,确认nvidia-smi能正常输出,再装CUDA Toolkit,最后装PyTorch的CUDA版本。顺序不能反,否则会出现各种奇怪的库冲突。

GPU在K8s里的调度单位是整卡,不支持显存切分(除非用MIG,但消费级卡不支持)。所以如果你的推理服务只需要2GB显存,剩下6GB就浪费了。解决办法是用时间片轮转,多个Pod共享一块卡,但这样会有上下文切换开销。我的做法是把大模型推理和轻量推理分开,大模型独占卡,轻量推理走CPU或者Intel核显。

3.4 存储实现:ZFS、MinIO和NAS共享怎么共存

存储这块是家庭实验室里最复杂的部分。我的方案是底层用ZFS做池管理,上层分别导出iSCSI、NFS、SMB和S3。ZFS的好处是数据完整性校验、快照、压缩、去重一应俱全,而且RAIDZ2能容忍两块盘同时故障。

具体配置上,容量池用8块8TB机械盘做RAIDZ2,可用容量约40TB。高速池用4块1TB NVMe做mirror,可用约2TB。对象存储池用4块4TB做RAIDZ1,可用约12TB。ZFS的recordsize根据用途调整:跑数据库的卷用16K,跑媒体库的用1M,跑虚拟机的用64K。

MinIO部署在K8s里,用PVC挂ZFS卷。这里要注意,MinIO官方推荐用本地盘直通,但在家庭环境里用PVC也能跑,只是性能会有损耗。实测下来,单节点MinIO在万兆网络下能跑到600MB/s左右,足够家庭使用。如果你追求更高性能,可以考虑把MinIO直接跑在宿主机上,用hostPath挂载。

NAS共享这块,SMB给Windows设备用,NFS给Linux和K8s用,iSCSI给需要块设备的虚拟机用。群晖NAS和飞牛NAS我都用过,群晖胜在生态成熟,飞牛胜在免费和硬件灵活。如果你要装Dify这类AI应用,飞牛NAS的Docker管理界面比群晖更友好。

4. 实操过程与核心环节实现

4.1 从裸机到K8s节点:完整初始化流程

这一节我按真实操作顺序写,你可以直接照着做。假设你有一台刚装好Ubuntu 22.04的机器,要把它变成K8s工作节点。

第一步,系统初始化。关闭swap,因为K8s要求swap关闭,否则kubelet会报错。执行swapoff -a并注释掉/etc/fstab里的swap行。然后加载内核模块:

cat <<EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter

第二步,配置网络参数。K8s需要iptables能正确转发桥接流量:

cat <<EOF | 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

第三步,安装containerd。不要用apt自带的版本,太老。从官方仓库下载:

wget https://github.com/containerd/containerd/releases/download/v1.7.20/containerd-1.7.20-linux-amd64.tar.gz tar Cxzvf /usr/local containerd-1.7.20-linux-amd64.tar.gz

然后配置containerd使用systemd cgroup驱动,这一步很关键,不配置的话kubelet和containerd的cgroup驱动不一致,Pod会启动失败。

第四步,安装kubelet、kubeadm、kubectl。用阿里云的镜像源,速度会快很多。安装完成后apt-mark hold锁定版本,防止意外升级。

第五步,加入集群。在生产集群的控制面生成token,然后在工作节点执行kubeadm join。加入之后用kubectl get nodes确认状态是Ready。

提示:如果你的节点加入后一直是NotReady,先检查CNI插件是否安装。没有CNI,节点永远不会Ready。Calico和Flannel选一个就行,家庭环境推荐Flannel,简单稳定。

4.2 存储池创建:ZFS命令逐条解析

ZFS池的创建是整个存储环节的基础,命令写错可能导致数据丢失,所以每一步都要确认。

创建容量池:

zpool create -o ashift=12 tank raidz2 /dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh

ashift=12是4K对齐,对现代硬盘是必须的,设错了性能会打折。raidz2是双校验,容忍两块盘故障。

创建高速池:

zpool create -o ashift=12 fast mirror /dev/nvme0n1 /dev/nvme1n1

创建数据集并设置属性:

zfs create tank/media zfs set recordsize=1M tank/media zfs set compression=lz4 tank/media zfs set atime=off tank/media

compression=lz4几乎不消耗CPU,但能省不少空间。atime=off减少不必要的写操作。这些属性看起来小,但累积起来对性能和寿命影响很大。

创建快照和自动快照:

zfs snapshot tank/media@20260101 zfs set com.sun:auto-snapshot=true tank/media

自动快照需要装zfs-auto-snapshot工具,配置好之后每天自动打快照,保留策略可以自定义。

4.3 MinIO部署:K8s里的对象存储

MinIO在K8s里的部署方式有两种:单节点多盘和分布式多节点。家庭环境推荐单节点多盘,简单可靠。

先创建PVC,挂载ZFS数据集。然后写Deployment:

apiVersion: apps/v1 kind: Deployment metadata: name: minio spec: replicas: 1 selector: matchLabels: app: minio template: metadata: labels: app: minio spec: containers: - name: minio image: minio/minio:latest args: - server - /data - --console-address - ":9001" env: - name: MINIO_ROOT_USER value: "admin" - name: MINIO_ROOT_PASSWORD value: "yourpassword" ports: - containerPort: 9000 - containerPort: 9001 volumeMounts: - name: data mountPath: /data volumes: - name: data persistentVolumeClaim: claimName: minio-pvc

部署完成后用NodePort或者Ingress暴露9000端口。然后进控制台创建bucket,配置访问密钥。K8s里的应用用S3 SDK访问,endpoint填MinIO的Service地址。

注意:MinIO的默认密码一定要改,而且不要用简单密码。我遇到过扫描器扫到暴露的MinIO端口,尝试暴力破解。家庭环境虽然风险低,但基本的安全习惯要有。

4.4 GPU算子验证:从驱动到PyTorch

GPU接入K8s之后,怎么验证它真的能用?我的做法是跑一个简单的CUDA算子测试。

先确认节点上GPU被识别:

kubectl describe node <gpu-node> | grep nvidia.com/gpu

应该能看到nvidia.com/gpu: 1。然后部署一个测试Pod:

apiVersion: v1 kind: Pod metadata: name: gpu-test spec: containers: - name: cuda image: nvcr.io/nvidia/pytorch:24.05-py3 command: ["python", "-c"] args: - "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))" resources: limits: nvidia.com/gpu: 1

如果输出True和显卡型号,说明GPU接入成功。这里涉及到一个概念叫cooperative thread array,也就是CUDA里的线程块,和warp的关系是:一个warp是32个线程,一个CTA可以包含多个warp。理解这个层级关系对写高效算子很重要,但如果你只是跑推理,暂时不用深究。

5. 常见问题与排查技巧实录

5.1 K8s节点NotReady的排查顺序

这是最高频的问题。我的排查顺序是:先看kubelet状态,再看CNI,再看证书,最后看资源。

systemctl status kubelet journalctl -u kubelet -n 100

如果kubelet报证书错误,检查/etc/kubernetes/kubelet.conf里的证书是否过期。K8s证书默认一年过期,到期后节点会NotReady。用kubeadm certs renew all续期,然后重启kubelet。

如果kubelet正常但节点还是NotReady,检查CNI Pod是否运行:

kubectl get pods -n kube-system | grep -E "calico|flannel"

CNI Pod起不来通常是镜像拉取失败,手动docker pull或者ctr pull一下。

5.2 存储性能突然下降的几种原因

ZFS池性能下降最常见的原因是碎片和空间占用过高。ZFS在池使用率超过80%之后性能会明显下降,所以建议保留20%以上的空闲空间。另外,如果开了去重,去重表会消耗大量内存,内存不足时性能会崩。家庭环境不建议开去重,压缩就够了。

另一个常见原因是RAIDZ的写放大。RAIDZ2的写性能受限于最慢的那块盘,而且每次写都要计算校验。如果写性能突然下降,检查是否有盘出现坏道:

zpool status -v

如果有盘报错,及时更换。ZFS的热备盘可以自动顶替,但需要提前配置spare。

5.3 GPU崩溃和D3D设备移除的应对

Windows下常见的“GPU发生崩溃或D3D设备已移除”在Linux下对应的是Xid错误。用nvidia-smi -q查看Xid,如果是Xid 13或31,通常是驱动问题,升级驱动。如果是Xid 48,是ECC错误,消费级卡没有ECC,忽略即可。

在K8s里,如果GPU Pod突然失败,先看节点上的dmesg:

dmesg | grep -i nvidia

常见问题是GPU被其他进程占用,比如宿主机上跑了X server。解决办法是宿主机不装桌面环境,纯命令行运行。

5.4 常见问题速查表

问题现象可能原因解决方法
节点NotReady证书过期kubeadm certs renew all
Pod一直Pending资源不足或污点检查节点资源和taints
存储写入慢池使用率过高清理空间或扩容
GPU Pod失败驱动不匹配重装对应版本驱动
网络不通CNI配置错误重装CNI插件
etcd响应慢磁盘IO不足换SSD或独立磁盘

提示:家庭实验室最大的优势是你可以随便重启、随便重装。遇到搞不定的问题,先拍快照,然后大胆重装。我很多经验都是重装十几次之后才总结出来的。

6. 一些个人体会和后续扩展方向

这套环境跑到现在,最深的体会是:瓶颈永远不在硬件,而在你的时间和精力。60TB存储、18台服务器听起来很唬人,但真正每天在用的可能就那几台。大部分机器处于低负载状态,电费和噪音才是日常成本。所以如果你刚开始搭,我的建议是从一台机器开始,跑通一个完整的流程,再逐步扩展。不要一上来就买一堆设备,最后发现大部分在吃灰。

后续我打算往两个方向扩展。一是把部分推理任务迁到边缘节点,用K3s做轻量级集群,减少对中心集群的依赖。二是把备份策略做得更完善,目前是本地快照加异地冷备,未来考虑加一层云上冷存储,但要看成本是否划算。

如果你也在搭类似的环境,欢迎交流。踩过的坑越多,经验越值钱,这句话在家庭实验室里尤其成立。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询