1.3 Kubernetes 部署
MoAI 官方发布的是容器镜像 whuanle/moai:latest(前后端一体,容器端口 8080),暂未提供 Helm Chart。本章给出可直接使用的参考清单,把 MoAI 以 Deployment 方式部署进集群,依赖的中间件(PostgreSQL、Redis、RabbitMQ、对象存储)建议复用集群内已有服务或托管实例。
部署架构
| 组件 | 部署方式 | 说明 |
|---|---|---|
| MoAI | Deployment + Service + Ingress | 镜像 whuanle/moai:latest,端口 8080 |
| PostgreSQL | 集群内已有实例或云数据库 | 必须带 pgvector 扩展,且已创建 vector、uuid-ossp 扩展 |
| Redis | 集群内已有实例 | 缓存与用户状态 |
| RabbitMQ | 集群内已有实例 | 消息队列 |
| 对象存储 | S3 兼容存储(MinIO / OSS 等) | 地址必须同时被 Pod 和用户浏览器可达 |
| OpenSandbox | 不在 K8s 内部署(可选) | 依赖 Docker,见文末说明 |
1. 准备数据库扩展
MoAI 首次启动会自动建表,但要求数据库已安装 pgvector 的 vector 扩展与 uuid-ossp。用一次性 Job 在目标库执行(数据库地址、账号按实际情况替换):
apiVersion: batch/v1
kind: Job
metadata:
name: moai-db-init
spec:
template:
spec:
restartPolicy: Never
containers:
- name: psql
image: pgvector/pgvector:pg16
command: ["psql"]
args:
- "postgresql://postgres:<密码>@<数据库地址>:5432/moai"
- -c
- 'CREATE EXTENSION IF NOT EXISTS vector; CREATE EXTENSION IF NOT EXISTS "uuid-ossp";'
使用 CloudNativePG 等 Operator 时,也可以把这两条语句配置到
postInitSQL中。
2. 应用配置(Secret)
MoAI 通过环境变量 MAI_FILE(默认 /app/configs/system.json)加载应用配置。配置文件包含数据库密码、AccessKey 等敏感信息,使用 Secret 保存,并挂载为容器内文件:
apiVersion: v1
kind: Secret
metadata:
name: moai-config
type: Opaque
stringData:
system.json: |
{
"MoAI": {
"Name": "MoAI",
"Port": 8080,
"Server": "https://moai.example.com",
"WebUI": "https://moai.example.com",
"AES": "<随机加密密钥>",
"Database": "Database=moai;Host=<数据库地址>;Password=<密码>;Port=5432;Username=postgres;Search Path=public",
"Redis": "<redis地址>:6379",
"RabbitMQ": "amqp://<用户>:<密码>@<mq地址>:5672",
"OpenSandBox": {
"Address": "",
"ApiKey": "",
"Image": "opensandbox/code-interpreter:v1.1.0",
"TimeoutSeconds": 900,
"RenewThresholdSeconds": 300
},
"Storage": {
"Endpoint": "https://oss.example.com",
"ForcePathStyle": true,
"Bucket": "moai",
"AccessKeyId": "<AccessKeyId>",
"AccessKeySecret": "<AccessKeySecret>"
},
"MaxUploadFileSize": 104857600,
"OTLP": { "Trace": "", "Metrics": "", "Protocol": 0 }
},
"Serilog": {
"Using": ["Serilog.Sinks.Console"],
"MinimumLevel": { "Default": "Information" },
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{SourceContext} {Scope} {Timestamp:HH:mm} [{Level}]{NewLine}{Properties:j}{NewLine}{Message:lj} {Exception} {NewLine}"
}
}
]
}
}
各字段含义与取值见 配置。其中 Server、WebUI、Storage.Endpoint 必须是用户浏览器可访问的对外地址,与 Ingress 域名保持一致。配置通过 Secret 整份管理,不要用环境变量零散注入个别字段,避免多环境间遗漏不一致。
3. Deployment 与 Service
apiVersion: apps/v1
kind: Deployment
metadata:
name: moai
labels:
app: moai
spec:
# 后台任务基于数据库调度,未做精细化多副本验证,建议保持 1
replicas: 1
selector:
matchLabels:
app: moai
template:
metadata:
labels:
app: moai
spec:
containers:
- name: moai
image: whuanle/moai:latest
ports:
- containerPort: 8080
env:
- name: TZ
value: Asia/Shanghai
volumeMounts:
- name: config
mountPath: /app/configs/system.json
subPath: system.json
readOnly: true
- name: files
mountPath: /app/files
readinessProbe:
httpGet:
path: /api/common/serverinfo
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
livenessProbe:
httpGet:
path: /api/common/serverinfo
port: 8080
initialDelaySeconds: 60
periodSeconds: 15
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
memory: 2Gi
volumes:
- name: config
secret:
secretName: moai-config
- name: files
persistentVolumeClaim:
claimName: moai-files
---
apiVersion: v1
kind: Service
metadata:
name: moai
spec:
selector:
app: moai
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: moai-files
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
首次启动会自动建表并写入种子数据(root 账号
admin / abcd123456),登录后请立即修改密码。
4. Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: moai
annotations:
# 上传走预签名直传对象存储,不走 Ingress;此处只需覆盖 MoAI 自身默认上传上限
nginx.ingress.kubernetes.io/proxy-body-size: 200m
spec:
ingressClassName: nginx
rules:
- host: moai.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: moai
port:
number: 80
tls:
- hosts:
- moai.example.com
secretName: moai-tls
注意 host 必须与配置中 MoAI:Server 的地址一致,前端会用它拼接静态资源与回调地址。
5. 验证与运维
kubectl get pods -l app=moai
kubectl logs -f deploy/moai
kubectl exec deploy/moai -- curl -fsS http://localhost:8080/api/common/serverinfo
# 升级
kubectl set image deployment/moai moai=whuanle/moai:<新版本tag>
kubectl rollout status deployment/moai
关于 OpenSandbox(沙箱)
OpenSandbox 生命周期服务依赖 Docker(挂载 docker.sock 动态创建沙箱容器),不适合原生 Kubernetes 环境:
- 不配置:
OpenSandBox.Address留空即可,MoAI 主体功能不受影响,仅技能沙箱执行类能力不可用; - 需要使用:在一台独立的 Docker 宿主机上按 Docker Compose 部署 中的方式运行
opensandbox-server,并将其地址填入OpenSandBox.Address,同时保证集群内 Pod 可以直接访问该宿主机返回的沙箱容器端口。
常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
| Pod 启动即退出,日志报找不到配置 | Secret 未挂载或 subPath 写错 | 确认挂载路径为 /app/configs/system.json 且是文件 |
启动报 vector 扩展错误 | 数据库没有 pgvector | 先执行第 1 步的扩展初始化 |
| 页面样式/上传异常 | Server / Storage.Endpoint 与实际访问地址不一致 | 两项都填浏览器可访问的对外地址,与 Ingress 域名一致 |
| 沙箱功能不可用 | K8s 内未部署 OpenSandbox | 属预期,见上文说明 |