三节点 K8s + 本地大模型 + AMD GPU 毕设全记录

一个毕业生如何用一台 Fedora 笔记本,给 Linux 娘搭出一套"企业内网私有化 AI 知识库"


缘起

去年选题的时候,、我就在想

"现在大模型这么火,能不能做一个能在企业内部用的 AI 知识库?数据不上公有云,全得跑在局域网里。"

我琢磨了一下——这不就是让三台服务器、跑个本地模型、再挂个网页的事儿吗?

行,整了。

后来那几个月,我几乎崩溃了,把一台 AMD 笔记本(16 核 22GB 内存,RX 6700S 独显)硬生生折腾成了三节点的 Kubernetes 集群。我们在上面架了 Ollama 本地小模型,写了一套 RAG 检索增强生成的知识库,还顺手配了 Prometheus 和 Grafana 监控。最后完整闭环跑通:上传文档 → 向量检索 → 大模型回答。

这篇日记,就是那段日子的全记录。


先一句话说清楚这是个啥

在公司局域网里搭一个三节点的 AI 知识库——员工上传文档,AI 从文档里找答案,全程数据不出公司,Linux 娘替你守门。


整体架构:三姐妹各司其职

┌─────────────────────────────────────────────────────────┐
│                   企业内网 10.10.10.0/24                  │
│                                                         │
│  ┌──────────────────┐  ┌──────────────────┐            │
│  │  k8s-master      │  │  k8s-rag          │            │
│  │  Ubuntu 22.04 VM │  │  Ubuntu 22.04 VM  │            │
│  │  4GB / 2 vCPU    │  │  6GB / 2 vCPU     │            │
│  │  k3s server      │  │  k3s agent        │            │
│  │  集群控制平面     │  │  Flask RAG :8080  │            │
│  │                  │  │  FAISS + SQLite   │            │
│  └────────┬─────────┘  └────────┬─────────┘            │
│           │                     │                       │
│  ┌────────┴─────────────────────┴─────────┐            │
│  │         k8sbr0 网桥                    │            │
│  │                                        │            │
│  │  ┌──────────────────────────────────┐  │            │
│  │  │  fedora (物理机, 22GB / 16核)     │  │            │
│  │  │  Ollama 本地大模型 :11434        │  │            │
│  │  │  RX 6700S GPU (8GB) · ROCm      │  │            │
│  │  │  Prometheus :9090 · Grafana :3000│  │            │
│  │  └──────────────────────────────────┘  │            │
│  └────────────────────────────────────────┘            │
│                                                         │
│  用户浏览器 ──→ RAG Web :8080 ──→ Ollama :11434        │
└─────────────────────────────────────────────────────────┘

三台机器的分工很清楚,就像 我手下的三个女仆:

节点类型内存职责
k8s-master虚拟机4GB集群大管家,指挥整个 K8s 的运转
k8s-rag虚拟机6GB知识库本体,管 Flask 网页、FAISS 向量库、SQLite 数据库
fedora物理机22GB真正干重活的,跑 Ollama 大模型 + AMD 显卡 + 监控系统

RAG 知识库是怎么工作的

RAG 全称 Retrieval Augmented Generation(检索增强生成),名字听着唬人,但理解就三步:

第一步:文档向量化

把上传的文档切成小段 → 每段交给 Ollama 变成一个长串数字(向量) → 存进 FAISS 向量数据库

第二步:语义检索

用户的提问也同样变成向量 → 去 FAISS 里搜出内容最接近的几个文档片段

第三步:生成回答

把搜到的文档片段 + 用户问题拼成一段提示词 → 发给 Ollama → 大模型基于文档内容生成答案 → 返回给用户

打个通俗的比方:

你把公司制度文档扔给它,然后问"请假要几天?"——Linux 娘不会让 AI 瞎编,她会先去文档里老老实实把相关内容翻出来,再让 AI 帮你总结成一段通顺的话。答案后面还会标注"根据哪几段文档",防止 AI 张口就来。

技术栈一览

用了什么
前端原生 HTML/CSS/JS(没用框架,Flask 直接渲染)
后端 APIFlask + Python
向量数据库FAISS(Facebook 开源,轻量,够用)
向量化Ollama /api/embeddings
大模型推理Ollama /api/chat + qwen2:1.5b
业务数据库SQLite(存用户、会话、聊天记录)
GPU 加速AMD ROCm 7.1.1 + RX 6700S
容器编排k3s(轻量级 Kubernetes)
监控Prometheus + Grafana + node_exporter + rocm_exporter

为什么要用 K8s?答辩时这么答

这个问题导师一定会问。

说实话,这个项目就三个节点,裸跑 docker 完全够用。架构不是为了现在,是为了以后不返工

K8s 给了三个关键能力:

  1. 资源隔离:创建 namespace + ResourceQuota,不同业务用不同配额,谁也别抢谁的口粮。
  2. 声明式管理kubectl create role 一条命令就配好权限,不用挨台机器手改配置文件。
  3. 可扩展:将来公司再加五台服务器,kubeadm join 一条命令直接入伙,不用推倒重来。

之所以选 k3s 而不是完整 kubeadm,是因为 Linux 娘也喜欢轻装上阵——k3s 只有一个 50MB 的二进制文件,是 CNCF 官方认证的 K8s 发行版,API 完全兼容,特别适合实验环境。


AMD 显卡跑 AI:和傲娇 GPU 娘斗智斗勇

整个项目最难的部分,不是写代码,是让 AMD 显卡乖乖干活。

Ollama 默认是伺候 NVIDIA CUDA 的,但我的笔记本是 AMD RX 6700S(Navi 23 核心,8GB 显存)。想让 Ollama 看得见这块卡,得装上 ROCm 7.1.1——这个过程,简直是在哄一个闹脾气的硬件娘。

踩过的坑,一个接一个:

1. rocBLAS 没装 → Ollama 只认 CPU → 装上后终于看见 GPU 了
2. HSA_OVERRIDE_GFX_VERSION 不设 → GPU 隐身 → 设为 10.3.0 才现身
3. /opt/rocm/lib 符号链接断了 → Ollama 找不着库文件 → 手动 ln -s 修好
4. 装完 ROCm 没重启 → 内核模块没加载 → reboot 解决一切

当终于看到这条日志的时候,我觉得前面受的罪都值了:

inference compute library=ROCm compute=gfx1030
  name=ROCm0 description="AMD Radeon RX 6700S"
  type=discrete total="8.0 GiB" available="7.9 GiB"

那一刻我真正理解了——环境配置本身就是工程能力。写代码谁都会,把依赖、驱动、内核模块理顺,才是最见功力的部分。


常用命令速查

集群管理

# SSH 到控制节点
ssh ubuntu@10.10.10.138

# 查看全部节点状态
sudo kubectl get nodes -o wide

# 查看命名空间
sudo kubectl get ns

# 创建资源配额(防止某个服务吃光所有资源)
kubectl create quota test-quota -n dify-namespace --hard=cpu=2,pods=10,memory=4Gi

# RBAC 权限验证
kubectl auth can-i get configmaps --as=test-user -n dify-namespace

Ollama 日常

# 查看已安装的模型
ollama list

# 拉取新模型
ollama pull qwen2:7b

# 确认 GPU 被正确识别
journalctl -u ollama -n 30 | grep -E "ROCm|RX 6700S"

# 查看 GPU 实时指标
curl http://127.0.0.1:9400/metrics | grep amd_gpu

系统恢复

# 关机重启后一键拉起所有服务
recover

# 全系统状态仪表盘
status

整个项目的时间线

Day 1   选型调研:K8s 还是 Docker Compose?最后决定都要
Day 2   装 KVM + 创建 2 台 Ubuntu 虚拟机,Linux 娘住进了新机房
Day 3   搭 k3s 集群,三节点全部 Ready,那一刻很有成就感
Day 4   装 Ollama,开始和 AMD GPU 娘漫长拉锯
Day 5   写 RAG 核心:chunk_text → embedding → FAISS → chat
Day 6   写 Flask Web + HTML 前端,能看就行,不卷前端
Day 7   加登录系统、管理员账号管理
Day 8   多会话持久化,聊天记录不再一刷新就消失
Day 9   装 Prometheus + Grafana + 自己写 rocm_exporter
Day 10  反复调试、疯狂截图、写论文到凌晨

我学到了什么

1. 别被"高大上"三个字吓住

刚看题目的时候:K8s + AI + GPU,感觉像一座大山。真正做起来,发现每块拆开都是能啃下来的——K3s 一条命令装好,Ollama 一条命令拉模型,FAISS 两行代码建索引。

关键是先想清楚数据怎么流,再动手。

2. 环境配置比写代码更耗命

这个项目大概 60% 的时间花在了配环境上:

  • KVM 虚拟机网络桥接
  • AMD ROCm 驱动适配
  • Ollama 认 GPU 的种种玄学
  • 各种 systemd 服务文件的编写

这么一看能跑通环境的人,才是项目中真正的稀缺物种。

3. 先吹牛再落地,发现不对劲赶紧改

论文初稿写得很宏大:Dify 平台、kubeadm 集群、3 台 2C2G 虚拟机、GPU 占用率 65%。

然后真正动手,发现根本两码事。

2C2G 虚拟机连 K8s 都颤颤巍巍,Dify 镜像大到根本拉不下来,GPU 调度也比想象中复杂十倍。还好我及时认清了现实,果断调整路线:换成 k3s 轻量 K8s、自己用 Flask + FAISS 从零搞了一个 RAG 引擎、把模型推理搬到物理机上用 ROCm 加速。

改完之后,项目反而更扎实了——因为每一行代码、每一个配置都是亲手调的,不再躲在现成平台后面。 现在回头想,早期那些不切实际的设想反而是必要的——它们让我在落地过程中被迫摸清了每一层的原理。

4. 原型系统的价值在于"跑通了"

这个系统不是能直接上生产的成熟产品,但它证明了一件事:

一个毕业生,一台笔记本,真的可以在内网环境里跑通 K8s + GPU + RAG 的全链路。

这就够了。毕业设计的价值,从来不是"做多大的工程",而是"证明它能走通"。


2026年5月,by 一个即将毕业的计算机系学生,与 Linux 娘并肩奋战的第 N 天