Files
easyai-deploy/README.md
T
2026-07-09 19:29:46 +08:00

422 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EasyAI Kubernetes 部署指南
本仓库用于将 EasyAI 部署到客户自己的 Kubernetes 环境中。客户拿到仓库后,只需要按本文准备外部依赖、修改生产配置并执行 `kubectl apply`,即可完成部署。
生产部署只使用以下目录:
```text
k8s/overlays/production
```
本地部署验证可参考:
```text
k8s/overlays/local/README.md
```
镜像版本默认使用 `latest`。EasyAI 发布新版本后,客户拉取本仓库最新内容并按“更新到最新版本”执行即可升级。
## 部署内容
| 服务 | Kubernetes 资源 | 说明 |
| --- | --- | --- |
| 前端 | `easyai-web` | Web 页面入口 |
| 主服务 | `easyai-server` | API、核心业务服务 |
| WebSocket 网关 | `ws-gateway` | `/socket.io` 长连接入口 |
| 视频编辑 | `video-edit` | 视频编辑能力 |
| 沙箱 | `sandbox` | 代码执行/Notebook 沙箱 |
| Agent 服务治理 | `easyai-asg` | Agent 治理服务 |
| Agent 记忆服务 | `agent-memory` | Agent 记忆与检索服务 |
生产环境建议将 Redis、MongoDB、RabbitMQ、PostgreSQL 等基础组件使用云厂商托管服务,不在本仓库中部署。
## 部署前准备
### Kubernetes 集群
请先确认集群满足以下条件:
| 项目 | 要求 |
| --- | --- |
| Kubernetes | 可正常使用 `kubectl` 连接 |
| Worker 节点 | 建议不少于 3 个节点,生产环境建议跨可用区 |
| Metrics Server | 已启用,用于 HPA 自动扩缩容 |
| Ingress Controller | 已安装,当前配置默认使用 NGINX Ingress |
| 共享存储 | 有支持 `ReadWriteMany` 的 StorageClass |
| 镜像拉取 | 节点可以访问 `registry.cn-shanghai.aliyuncs.com` |
检查命令:
```bash
kubectl config current-context
kubectl get nodes -o wide
kubectl top nodes
kubectl get ingressclass
kubectl get storageclass
```
如果 `kubectl top nodes` 不可用,请先启用 Metrics Server。
### 外部依赖
部署前需要准备以下云服务,并保证 Kubernetes 节点所在 VPC 可以访问:
以下版本为当前生产部署推荐版本。使用云厂商托管服务时,请固定主版本;大版本升级前先在测试环境完成回归验证。
| 依赖 | 推荐版本 | 用途 | 需要准备的信息 |
| --- | --- | --- | --- |
| MongoDB | `7.x` | 主服务业务数据 | 内网地址、端口、用户名、密码、连接参数 |
| Redis | `7.x`,需支持至少 `16` 个逻辑 DB | 队列、缓存、WebSocket 集群状态 | 内网地址、端口、密码,需支持多个逻辑 DB |
| RabbitMQ | `3.13.x`,需支持 AMQP `0-9-1` | 消息队列 | AMQP 地址、端口、用户名、密码、vhost |
| PostgreSQL + pgvector | PostgreSQL `18` + pgvector `0.8.2` | Agent 治理和记忆服务 | 地址、端口、用户名、密码、数据库、扩展 |
| RWX 共享存储 | 与 Kubernetes 集群版本兼容的 CSI/存储插件 | 上传、备份、恢复文件共享 | 支持 `ReadWriteMany` 的 StorageClass |
| OSS/S3 对象存储 | 兼容 AWS S3 Signature V4 或云厂商 OSS/S3 当前 API,可选 | 文件存储,可选 | Endpoint、Bucket、Access Key |
本地验证环境中的 PostgreSQL/pgvector 镜像为:
```text
registry.cn-shanghai.aliyuncs.com/easyaigc/pgvector:0.8.2-pg18-trixie
```
外部依赖版本核对示例:
```bash
mongosh --eval 'db.version()'
redis-cli INFO server | grep '^redis_version:'
rabbitmqctl status | grep '{rabbit,'
psql "$ASG_DATABASE_URL" -c 'SHOW server_version;'
psql "$ASG_DATABASE_URL" -c "SELECT extversion FROM pg_extension WHERE extname = 'vector';"
kubectl get storageclass
```
PostgreSQL 需要创建两个数据库,并启用扩展:
```sql
CREATE DATABASE agent_governance;
\c agent_governance
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE DATABASE easyai_memory;
\c easyai_memory
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
```
最终需要准备两个连接串:
```text
postgresql://USER:PASSWORD@HOST:5432/agent_governance?schema=public
postgresql://USER:PASSWORD@HOST:5432/easyai_memory?schema=public
```
## 修改生产配置
所有生产配置都在:
```text
k8s/overlays/production
```
### 1. 修改非敏感配置
编辑:
```text
k8s/overlays/production/app-config.yaml
```
至少替换以下内容:
```yaml
NUXT_PUBLIC_BASE_SOCKETURL: wss://你的域名/socket.io
CONFIG_COMFYUI_QUENE_REDIS_HOST: 你的Redis内网地址
GATEWAY_CLUSTER_REDIS_HOST: 你的Redis内网地址
ASG_REDIS_HOST: 你的Redis内网地址
CONFIG_MQ_HOST: 你的RabbitMQ内网地址
```
如果使用统一域名访问,以下配置通常保持默认:
```yaml
NUXT_PUBLIC_BASE_APIURL: /api
NUXT_PUBLIC_SG_APIURL: /asg-api
```
### 2. 修改敏感配置
编辑:
```text
k8s/overlays/production/app-secret.yaml
```
至少替换以下内容:
```yaml
CONFIG_DB_MONGO_URI: mongodb://你的Mongo内网地址:27017
CONFIG_DB_MONGO_USERNAME: 你的Mongo用户名
CONFIG_DB_MONGO_PASSWORD: 你的Mongo密码
MONGO_INITDB_ROOT_USERNAME: 你的Mongo用户名
MONGO_INITDB_ROOT_PASSWORD: 你的Mongo密码
CONFIG_COMFYUI_QUENE_REDIS_PASSWORD: 你的Redis密码
GATEWAY_CLUSTER_REDIS_PASSWORD: 你的Redis密码
ASG_REDIS_PASSWORD: 你的Redis密码
CONFIG_MQ_USER: 你的RabbitMQ用户名
CONFIG_MQ_PASSWORD: 你的RabbitMQ密码
CONFIG_JWT_SECRET: 一段足够长的随机字符串
CONFIG_TOKEN_SIGN_SK: 一段足够长的随机字符串
ASG_DATABASE_URL: postgresql://USER:PASSWORD@HOST:5432/agent_governance?schema=public
MEMORY_DATABASE_URL: postgresql://USER:PASSWORD@HOST:5432/easyai_memory?schema=public
ASG_POSTGRES_USER: 你的PostgreSQL用户名
ASG_POSTGRES_PASSWORD: 你的PostgreSQL密码
ASG_ADMIN_PASSWORD: EasyAI管理员密码
SANDBOX_JUPYTER_TOKEN: 一段足够长的随机字符串
```
生成随机密钥示例:
```bash
openssl rand -base64 48
```
如果使用 OSS/S3,请同时替换:
```yaml
OSS_ENDPOINT: ""
OSS_ACCESS_KEY_ID: ""
OSS_ACCESS_KEY_SECRET: ""
OSS_BUCKET: ""
```
生产密钥不要提交到公共 Git 仓库。正式环境建议接入 External Secrets、Sealed Secrets 或云厂商 Secret Manager。
### 3. 修改域名和证书
编辑:
```text
k8s/overlays/production/ingress.yaml
```
将所有 `easyai.example.com` 替换为客户真实域名。
如果集群的 IngressClass 不是 `nginx`,同步修改:
```yaml
ingressClassName: nginx
```
创建 TLS Secret
```bash
kubectl create namespace easyai --dry-run=client -o yaml | kubectl apply -f -
kubectl -n easyai create secret tls easyai-tls \
--cert=/path/to/tls.crt \
--key=/path/to/tls.key
```
如果使用 cert-manager,请按客户集群规范在 `ingress.yaml` 中添加证书签发 annotation。
### 4. 修改共享存储
编辑:
```text
k8s/overlays/production/shared-pvc.yaml
```
将占位符替换为真实的 RWX StorageClass
```yaml
storageClassName: 你的RWX_StorageClass
```
默认 PVC 容量为 `100Gi`,可按客户实际文件量调整:
```yaml
storage: 100Gi
```
## 部署前检查
确认没有未替换的占位符:
```bash
grep -R -nE 'CHANGE_ME|easyai.example.com|你的' k8s/overlays/production
```
如果还有输出,请先完成配置替换。
渲染生产 YAML
```bash
kubectl kustomize k8s/overlays/production > /tmp/easyai-production.yaml
```
检查资源类型:
```bash
grep '^kind:' /tmp/easyai-production.yaml
```
执行服务端 dry-run
```bash
kubectl create namespace easyai --dry-run=client -o yaml | kubectl apply -f -
kubectl apply --dry-run=server -f /tmp/easyai-production.yaml
```
如果 dry-run 报 IngressClass、Ingress annotation 或权限相关错误,请先按客户集群规范调整 `ingress.yaml`
## 部署
执行部署:
```bash
kubectl apply -k k8s/overlays/production
```
查看资源:
```bash
kubectl -n easyai get deploy,svc,pvc,ingress,hpa,pdb
kubectl -n easyai get pods -o wide
```
等待服务发布完成:
```bash
for d in easyai-web easyai-server ws-gateway video-edit sandbox easyai-asg agent-memory; do
kubectl -n easyai rollout status deploy/$d --timeout=15m
done
```
如果某个 Deployment 超时,查看 Pod 状态和日志:
```bash
kubectl -n easyai get pods -o wide
kubectl -n easyai describe pod <PodName>
kubectl -n easyai logs <PodName> --all-containers --tail=200
```
## DNS 和访问验证
查看 Ingress 地址:
```bash
kubectl -n easyai get ingress
```
将客户域名解析到 Ingress 暴露的公网 IP 或 CNAME。
DNS 生效前,可以先用 `curl --resolve` 验证:
```bash
curl -i --resolve 你的域名:443:Ingress公网IP https://你的域名/api/health
```
DNS 生效后验证:
```bash
curl -i https://你的域名/api/health
curl -i https://你的域名/asg-api/health
curl -i https://你的域名/ams-api/health
```
浏览器访问:
```text
https://你的域名
```
重点确认:
| 检查项 | 预期结果 |
| --- | --- |
| Web 页面 | 可以正常打开 |
| `/api/health` | 返回健康状态,不是 404/502 |
| `/asg-api/health` | 返回健康状态 |
| `/ams-api/health` | 返回健康状态 |
| `/socket.io` | WebSocket 可以正常连接 |
## 更新到最新版本
本仓库默认使用 `latest` 镜像标签,并且工作负载已配置 `imagePullPolicy: Always`
当 EasyAI 发布新版本后,客户在本仓库目录执行以下命令。即使 `git pull` 没有拉到新的 YAML 变更,只要 EasyAI 已发布新的 `latest` 镜像,也需要执行后面的 `rollout restart`
```bash
git pull
kubectl apply -k k8s/overlays/production
kubectl -n easyai rollout restart \
deploy/easyai-web \
deploy/easyai-server \
deploy/ws-gateway \
deploy/video-edit \
deploy/sandbox \
deploy/easyai-asg \
deploy/agent-memory
for d in easyai-web easyai-server ws-gateway video-edit sandbox easyai-asg agent-memory; do
kubectl -n easyai rollout status deploy/$d --timeout=15m
done
```
说明:`latest` 标签更新后,Kubernetes 不会仅因为远端镜像变化就自动重建 Pod,所以更新时必须执行 `rollout restart`
## 回滚
如果是配置变更导致问题,可回到上一份配置后重新部署:
```bash
git checkout <上一个可用提交>
kubectl apply -k k8s/overlays/production
```
如果是镜像版本问题,请使用 EasyAI 提供的回滚版本或回滚仓库版本后重新执行部署。
查看发布历史:
```bash
kubectl -n easyai rollout history deploy/easyai-server
```
回滚单个服务:
```bash
kubectl -n easyai rollout undo deploy/easyai-server
kubectl -n easyai rollout status deploy/easyai-server --timeout=10m
```
## 常见问题
| 现象 | 优先检查 |
| --- | --- |
| `ImagePullBackOff` | 节点是否能访问镜像仓库,镜像仓库是否需要额外拉取凭证 |
| Pod 一直 `Pending` | 节点资源、PVC 是否 Bound、StorageClass 是否支持 RWX |
| HPA 显示 `unknown` | Metrics Server 是否可用,`kubectl top pods` 是否正常 |
| `/api/health` 返回 404/502 | IngressClass、rewrite annotation、后端服务是否 Ready |
| WebSocket 频繁断开 | `/socket.io` 是否路由到 `ws-gateway:3002`,Ingress 超时时间是否足够 |
| 文件上传后多副本不可见 | `easyai-shared-files` PVC 是否正确挂载到 `easyai-server` |
| 连接数据库或中间件失败 | VPC、安全组、白名单、端口、用户名密码、TLS 要求 |
| `video-edit` 无法创建 | 集群 PodSecurity/PSA 是否禁止 `SYS_ADMIN` capability |
查看事件和日志:
```bash
kubectl -n easyai get events --sort-by=.lastTimestamp | tail -80
kubectl -n easyai logs deploy/easyai-server --tail=200
kubectl -n easyai logs deploy/ws-gateway --tail=200
kubectl -n easyai logs deploy/easyai-asg --tail=200
kubectl -n easyai logs deploy/agent-memory --tail=200
```