自托管校园剖析:三节点 k3s 集群上的 openEDU
部署现状: 三个裸金属节点(72 vCPU、约 1 TB 内存)承载完整的高教数字工作空间,GitOps 全程管理,云支出仅为一个域名。
在 home.openedu.graphwiz.ai 的 OIDC 登录页背后,是一套可自托管的完整工作空间:文档协作、群件、聊天、视频教学、学习管理系统、协作写作与本地 AI——数据不出机构。
核心架构
- 系统:Ubuntu 24.04 LTS,三个节点(1 控制平面 + 2 工作节点),k3s v1.36
- 入口:MetalLB L2 VIP + HAProxy Ingress,一个稳定入口 IP
- 证书:cert-manager 签发一张 Let's Encrypt 通配符证书,所有 Ingress 共享
- 身份:Keycloak (OIDC) + OAuth2 Proxy,所有服务一次登录
- GitOps:Argo CD 管理六个 Application,集群状态即 Git 状态
- 存储与备份:本地 RWO 卷 + S3 兼容备份(SeaweedFS)
- AI:双 Ollama 实例 + Open WebUI,推理不出内网
服务套件按域部署在独立命名空间(openedu、llm、home、monitoring、backup):Nextcloud + Collabora 与 CryptPad(文档)、Matrix/Synapse 与 SOGo(沟通)、Ilias/BigBlueButton/Jitsi/JupyterHub/Overleaf(教学)、n8n 与 Grafana(自动化与运维)。
生产环境中学到的两课
- 说谎的存活探针:kubelet 的
httpGet探针无法可靠覆盖自定义Host:头,Nextcloud 对每次探测返回 400 并陷入重启循环。改用容器内执行确定性curl的exec探针解决。 - 仅安装期生效的环境变量:
NEXTCLOUD_TRUSTED_DOMAINS只在全新安装时起作用;装后的域名变更必须走occ config:system:set。环境变量配置的是安装器,不是应用——每个有状态镜像都值得记住这一点。
调试 RWO 有状态卷时,kubectl debug 无法直接挂载:把临时 Pod 固定到持有卷附件的节点,再挂载 PVC 操作。
运行成本
- 硬件:三节点,已折旧完毕,容量富余
- 人力:真正的成本——一名具备平台思维者即可运转
- 许可与云支出:全部组件开源,费用仅为域名与 DNS
代价同样真实:补丁、容量规划与灾备都归你所有。备份按计划写入 SeaweedFS,恢复定期演练——包括多数人会跳过的一步:用与备份同等的严格程度测试恢复路径。
要点
可信的教育开源数字工作空间不需要超大规模云、托管 Kubernetes 或平台工程部门。它需要:一个小型 k3s 集群、从第一天起的 GitOps、一个身份提供方、通配符 TLS,以及把整个栈留在 Git 里的纪律。
本文所述架构即 openEDU 的底层基础设施。生态交互式总览见 landscape.openedu.graphwiz.ai。