基于 Kubernetes 的云原生博客系统与联邦学习模型训练/推理平台
具体可以查看github项目:项目链接
一、项目整体概述
本项目构建了一个运行于 Kubernetes 集群之上的高度自动化的多工作负载云原生系统,核心目标不仅是功能实现本身,更强调 从模型训练、参数聚合、模型部署到在线推理与业务服务的全流程自动化。
系统以 Kubernetes 作为统一调度与控制平面,将模型训练、联邦参数聚合、在线推理服务与 Web 应用服务全部纳入容器编排体系,实现:
- 训练任务的自动调度与生命周期管理
- 模型参数聚合流程的自动触发与执行
- 推理服务的自动部署、自动恢复与自动扩展
- 博客业务服务与模型服务之间的自动解耦与协同运行
在算法层面,项目采用 PyTorch 框架,基于 LSTM 神经网络结构 实现中文文本情感分类任务,并引入 联邦学习(Federated Learning) 训练范式,训练结束后自动开启相关聚合任务,通过多训练节点协同优化模型参数,同时使用轮次聚合和基于样本权重的的平均,实现对训练过程的优化,在不共享原始数据的前提下完成模型训练,为分布式、自动化训练流程提供算法基础。
在系统层面,项目采用 前后端分离架构 + 微服务化设计,并通过 Kubernetes 对各组件进行容器编排、状态管理与弹性伸缩,使整个系统能够在最少人工干预的情况下完成部署、运行与演化。
二、系统架构与 Pod 级划分
pv和pvc配置展示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| apiVersion: v1 kind: PersistentVolume metadata: name: blog-pv labels: app: blog spec: capacity: storage: 7Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain hostPath: path: /root/final_hw type: DirectoryOrCreate --- apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv labels: app: mysql spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain hostPath: path: /root/sql_data type: DirectoryOrCreate
|
Service配置展示:
1 2 3 4 5 6 7 8 9 10 11 12 13
| --- apiVersion: v1 kind: Service metadata: name: mysql namespace: bloginfer spec: type: ClusterIP ports: - port: 3306 targetPort: 3306 selector: app: mysql
|
系统在 Kubernetes 中被拆分为多类功能明确的 Pod,分别对应不同的工作负载类型:
1. 模型训练 Pod(Training Workers)
- 作为 Batch Job 类型工作负载 存在
- 各 Pod 持有彼此独立的内存数据子集,内存数据在节点之间保持隔离(Data Isolation)
- 使用 PyTorch 完成本地模型训练,仅对外暴露每一个批次的参数信息
模型训练配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: batch/v1 kind: Job metadata: name: train namespace: bloginfer spec: completions: 2 parallelism: 2 backoffLimit: 1 template: metadata: labels: app: train
|
2. 参数聚合 Pod(Federated Aggregator)
- 作为联邦学习中的中心协调节点
- 负责接收各训练 Pod 上传的梯度
- 采用 Gradient Averaging(梯度平均) 而非参数平均进行模型更新
- 在非 IID 数据分布条件下,该方式具有更稳定的收敛特性
3. 模型推理 Pod(Inference Service)
- 基于 FastAPI 构建
- 属于 无状态服务(Stateless Service)
- 可通过增加副本数量进行横向扩展
- 负责对外提供实时情感分析推理接口
4. 博客后端 Pod(Application Backend)
- 使用 C++ 与 Drogon 框架 实现
- 负责用户管理、文章管理、评论系统等核心业务逻辑
- 通过 RESTful API 与前端和数据库交互
后端pod文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| apiVersion: apps/v1 kind: Deployment metadata: name: blog-backend-deployment namespace: bloginfer labels: app: blog-backend spec: replicas: 1 selector: matchLabels: app: blog-backend template: metadata: labels: app: blog-backend spec: containers: - name: blog-backend image: my_repository/blog-backend:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8080 env: - name: LISTEN_PORT value: "8080"
|
5. Nginx Pod(Frontend & Gateway)
- 用于前端静态资源托管
- 负责请求反向代理与路由转发
- 使用NodePort对外暴露端口
1 2 3 4 5 6 7
| location /api/ { proxy_pass http://blog-backend-service.bloginfer.svc.cluster.local:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| { "listeners": [ { "address": "0.0.0.0", "port": 8080 } ], "log": { "log_path": "./logs", "log_level": "INFO", "logfile_base_name": "blog_backend" }, "db_clients": [ { "name": "default", "rdbms": "mysql", "host": "@MYSQL_IP@", "port": 3306, "dbname": "blog", "user": "root", "password": "123456", "is_fast": false, "connection_number": 5 } ], "redis_clients": [ { "name": "default", "host": "@REDIS_IP@", "port": 6379, "db": 0 } ] }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| FROM drogonframework/drogon:latest AS builder
ENV MYSQL_HOST=mysql ENV REDIS_HOST=redis
WORKDIR /app
COPY . /app
RUN mkdir -p build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release && cmake --build . --config Release
FROM drogonframework/drogon:latest
WORKDIR /app
COPY --from=builder /app/build/blog_backend /app/blog_backend
COPY --from=builder /app/build/config.json /app/config.json COPY sql /app/sql
RUN mkdir -p /app/logs /app/uploads
EXPOSE 8080
WORKDIR /app
CMD ["./blog_backend"]
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: bloginfer spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.25 volumeMounts: - name: nginx-conf mountPath: /etc/nginx/nginx.conf subPath: nginx.conf - name: dist-storage mountPath: /usr/share/nginx/html subPath: dist readOnly: true
|
6. 数据库与缓存 Pod
MySQL Pod:
- 有状态服务
- 通过 PV / PVC 绑定持久化存储
- 确保 Pod 重建后的数据一致性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| apiVersion: v1 kind: Secret metadata: name: mysql-secret namespace: bloginfer type: Opaque data: MYSQL_ROOT_PASSWORD: MTIzNDU2
--- apiVersion: apps/v1 kind: StatefulSet metadata: name: mysql namespace: bloginfer spec: replicas: 1 serviceName: mysql selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:9.2 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: MYSQL_ROOT_PASSWORD ports: - containerPort: 3306 volumeMounts: - name: data mountPath: /var/lib/mysql - name: mysql-init mountPath: /docker-entrypoint-initdb.d readOnly: true resources: requests: cpu: "500m" memory: "1Gi" limits: cpu: "1" memory: "2Gi" - name: mysqld-exporter image: prom/mysqld-exporter:latest command: ["sh", "-c"] args: - | until mysqladmin ping -h 127.0.0.1 -u root -p$MYSQL_ROOT_PASSWORD; do sleep 2 done /bin/mysqld_exporter env: - name: DATA_SOURCE_NAME value: "root:123456@(localhost:3306)/"
|
Redis Pod:
- In-Memory Key-Value 存储
- 用于 Session 管理与高频访问数据缓存
- 减轻后端服务对关系型数据库的访问压力
7. 训练守护进程 Pod(Training Daemon)
- 以 长生命周期 Pod(或 Deployment) 形式常驻运行
- 暴露简单的 HTTP 接口,用于接收“启动训练任务”的触发请求
- 接收到请求后,通过调用 Kubernetes API 或执行脚本,动态创建训练 Job/Pod,完成一次完整的模型训练流程
- 与模型存储目录挂载在同一个PVC,用于写入最新模型文件
- 内置定时任务(例如基于定时循环 + Shell/Python 脚本),定期扫描模型目录,只保留最近的若干个模型版本,自动清理更早的历史模型文件
- 通过这种方式,将“训练触发 + 历史模型清理”封装到统一的守护进程中,减少人工干预
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| apiVersion: v1 kind: ServiceAccount metadata: name: train-daemon-sa namespace: bloginfer --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: train-daemon-role namespace: bloginfer rules: - apiGroups: ["batch"] resources: ["jobs"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: train-daemon-rb namespace: bloginfer subjects: - kind: ServiceAccount name: train-daemon-sa namespace: bloginfer roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: train-daemon-role --- apiVersion: apps/v1 kind: Deployment metadata: name: train-daemon namespace: bloginfer labels: app: train-daemon spec: replicas: 1 selector: matchLabels: app: train-daemon template: metadata: labels: app: train-daemon spec: serviceAccountName: train-daemon-sa containers: - name: train-daemon image: my_repository/train-daemon:latest imagePullPolicy: IfNotPresent env: - name: NAMESPACE value: "bloginfer" - name: MODEL_DIR value: "/blog/models" - name: MIN_TRAIN_INTERVAL_SECONDS value: "600" - name: TRAIN_POLL_INTERVAL_SECONDS value: "5" - name: CLEAN_INTERVAL_SECONDS value: "3600" - name: MAX_CLIENT_MODEL_AGE_SECONDS value: "86400" - name: TRAIN_JOB_YAML value: "/blog/configs/train.yaml" - name: AGG_JOB_YAML value: "/blog/configs/Integrajob.yaml" - name: INFERENCE_DEPLOYMENT_NAME value: "inference" - name: PORT value: "8000"
|
这是系统的架构图:

三、联邦学习训练流程设计(自动化训练流水线)
模型训练采用典型的 Federated Data-Parallel Training 流程,并被设计为一条可重复、可自动执行的训练流水线:
- Kubernetes 自动调度多个训练 Pod 作为 Batch Job 启动
- 各训练 Pod 在本地数据集上独立完成模型训练
- 每一轮训练结束后,训练 Pod 自动将梯度信息上传至参数聚合 Pod
- 聚合 Pod 自动执行梯度平均(Gradient Averaging)并更新全局模型参数
- 更新后的模型参数被自动分发回各训练 Pod,进入下一轮训练或结束训练任务
整个过程无需人工手动干预训练节点或参数同步,训练任务的启动、执行、结束均由 Kubernetes 与程序逻辑协同完成。
该自动化训练流程模拟了真实跨组织、跨节点的分布式协同训练场景,在不共享原始数据的前提下完成模型优化,同时体现了云计算环境中“任务驱动 + 自动调度”的核心思想。
四、模型推理与在线服务(自动部署与弹性运行)
训练完成的模型被自动导出并封装为 FastAPI 推理服务镜像,随后由 Kubernetes 负责部署与运行,对外提供在线预测能力。
推理服务在集群中具备如下自动化特性:
- 推理服务与训练流程完全解耦,模型更新后可自动替换服务版本
- 推理 Pod 属于无状态服务,可通过副本数调整实现自动横向扩展
- 当 Pod 异常终止或节点不可用时,Kubernetes 会自动拉起新的 Pod 以恢复服务
通过将推理过程纳入统一的编排与调度体系,系统实现了模型从“训练完成”到“对外服务”的自动过渡。
1 2 3 4 5 6 7
| @asynccontextmanager async def lifespan(app: FastAPI): app.state.infer = SentimentInferencer( ckpt_path="models/sentiment_zh_final.pt", device="cpu", ) yield
|
五、博客系统与数据管理
博客系统作为模型能力的应用载体,完整运行在云端:
- 前端基于 Vue.js 构建,通过 Nginx 对外提供访问
- 后端基于 Drogon 框架实现高性能 C++ Web 服务
- 业务数据持久化存储于 MySQL 中
- 用户登录状态与热点评论数据缓存在 Redis 中
该架构在保证数据一致性的同时,有效提升了系统响应性能。
六、用户行为驱动的模型迭代机制(自动数据闭环)
系统在博客评论功能中引入模型能力,构建了一条 自动化的 Online Inference + Human Feedback 数据闭环:
- 用户发表评论后,评论内容被自动发送至推理服务进行情感分析
- 系统调用大模型接口对评论进行情感与语义自动标注,生成弱监督标签
- 标注后的数据被自动结构化存储,作为新增训练样本
- 在后续训练周期中,新数据被自动纳入联邦学习训练流程
通过该机制,系统实现了用户行为、在线推理与离线训练之间的自动联动,使模型能够在云端环境中持续迭代与演化。
七、实验结果与系统验证
- Kubernetes 集群中多 Pod 协同运行效果
- 推理服务的水平扩展能力验证
- Drogon 后端镜像构建与自动部署结果
- 自动化构建与推送流程展示
- 模型训练过程中的损失变化
- 模型测试集上的分类性能评估
八、总结
本项目以云计算与大数据相关技术为核心,综合运用了容器化部署、微服务架构、联邦学习训练、在线推理与弹性伸缩机制,构建了一个具备工程复杂度与学术背景的完整云端系统,较为全面地体现了云计算环境下模型与应用协同运行的典型模式。