Files
easyai-deploy/README.md
T

17 KiB
Raw Blame History

EasyAI Kubernetes 部署指南

本仓库用于将 EasyAI 部署到客户自己的 Kubernetes 环境中。客户拿到仓库后,只需要按本文准备外部依赖、修改生产配置并执行 kubectl apply,即可完成部署。

生产部署只使用以下目录:

k8s/overlays/production

本地部署验证可参考:

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 或独立基础设施中自建;本仓库已提供 RabbitMQ 三节点集群模板,其他自建依赖需由客户按其基础设施标准提供高可用、备份和监控能力。

部署前准备

Kubernetes 集群

请先确认集群满足以下条件:

项目 要求
Kubernetes 可正常使用 kubectl 连接
Worker 节点 建议不少于 3 个节点,生产环境建议跨可用区
Metrics Server 已启用,用于 HPA 自动扩缩容
Ingress Controller 已安装,当前配置默认使用 NGINX Ingress
共享存储 有支持 ReadWriteMany 的 StorageClass
镜像拉取 节点可以访问 registry.cn-shanghai.aliyuncs.com

检查命令:

kubectl config current-context
kubectl get nodes -o wide
kubectl top nodes
kubectl get ingressclass
kubectl get storageclass

如果 kubectl top nodes 不可用,请先启用 Metrics Server。

基础依赖

部署前需要准备以下基础依赖,并保证 EasyAI Pod 可以访问。依赖既可以使用云厂商托管服务,也可以由客户自行部署。

以下版本为新建生产环境的推荐基线;已有依赖满足各小节兼容条件时可以复用。实际部署时请固定主版本和补丁版本;大版本升级前必须在测试环境完成连接、功能、性能和备份恢复验证。

依赖 推荐版本 用途 需要准备的信息
MongoDB 7.x 主服务业务数据 内网地址、端口、用户名、密码、连接参数
Redis 7.x,需支持多个逻辑 DB;默认使用 DB 0681112 队列、缓存、WebSocket 集群状态 内网地址、端口、用户名、密码、可分配的 DB 编号
RabbitMQ 需支持 AMQP 0-9-1;新建环境建议使用官方当前仍受支持的版本,自建模板默认使用 4.3.2 消息队列 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

Redis 逻辑 DB 配置

Redis 地址、端口和逻辑 DB 编号统一配置在:

k8s/overlays/production/app-config.yaml

密码等敏感信息配置在:

k8s/overlays/production/app-secret.yaml

当前默认映射如下:

DB 用途 配置项
0 WebSocket 网关集群状态 GATEWAY_CLUSTER_REDIS_DB
6 任务队列、画布运行状态和模型限流 CONFIG_COMFYUI_QUENE_REDIS_DB
8 Agent 服务治理及其队列 ASG_REDIS_DB
11 业务缓存和 WebSocket 鉴权缓存 CONFIG_COMFYUI_CACHE_REDIS_DB
12 跨实例内部事件 CONFIG_EVENT_REDIS_DB
12 任务中止和超时控制 CONFIG_ABORT_REDIS_DB

系统实际使用 0681112 共 5 个不同的逻辑 DB。每个配置项填写的是一个确定的 DB 编号,不是起止范围。客户分配了其他连续或非连续 DB 时,可以逐项修改上述编号;若保持默认值,Redis 必须允许选择到 DB 12,常见的 databases 16 配置可以满足要求。

该多 DB 方案要求 Redis 服务支持 SELECT。Redis Cluster 只支持 DB 0,不能直接用于当前配置,详见 Redis 官方 SELECT 文档

MongoDB 数据库、集合和权限

EasyAI 默认使用以下业务数据库:

aidraw

部署时应显式配置数据库名,不要依赖应用默认值:

CONFIG_DB_MONGO_URI: mongodb://你的Mongo内网地址:27017/?authSource=admin
CONFIG_DB_MONGO_DBNAME: aidraw
CONFIG_DB_MONGO_USERNAME: 你的Mongo用户名
CONFIG_DB_MONGO_PASSWORD: 你的Mongo密码

如果 MongoDB 使用副本集,URI 需要包含所有可用节点和副本集名称,例如:

mongodb://mongo-0:27017,mongo-1:27017,mongo-2:27017/?replicaSet=rs0&authSource=admin

authSource 必须填写用户实际创建所在的认证库;如果用户创建在 aidraw,应改为 authSource=aidraw

无需提前创建或逐项提供集合名称。应用会根据业务模型在 aidraw 中创建所需集合和索引,集合也可能随产品版本或启用模块变化。建议为应用用户授予 aidraw 数据库级 readWrite 权限,不要采用固定集合白名单。若客户审计制度必须使用集合级授权,应以实际交付镜像在预发布环境启动后生成的集合和索引清单为准。

当前生产验证基线是 MongoDB 7.x。应用驱动可以连接 MongoDB 4.x,但 MongoDB 4.04.24.4 均已停止官方维护。存量环境确实无法升级时,建议至少使用最终补丁版 4.4.29,并在上线前完成完整回归;不要把 MongoDB 4.x 作为新的长期生产基线。

MongoDB 生命周期和驱动兼容性参考:

RabbitMQ 托管或自建方案

EasyAI 使用标准 AMQP 0-9-1 能力,不依赖 RabbitMQ 4.3 专属功能。自建模板中的 4.3.2 是默认部署版本,不是应用的硬性最低版本。

已有 RabbitMQ 3.13.7 及以上环境时,可以直接复用,不需要再部署本仓库的 RabbitMQ 模板;上线前应验证队列声明、消息发布和消费、断线重连及故障切换。低于 3.13.7 的版本不作为当前交付兼容范围。RabbitMQ 3.13.x 已停止社区支持,因此新建生产环境仍建议选择官方当前处于支持期的版本。

使用托管或客户已有的 RabbitMQ 时,向 EasyAI 提供内网 AMQP Service 地址、5672/5671 端口、用户名、密码和 vhost 即可。

不能使用云服务时,使用以下目录中的 RabbitMQ Cluster Operator 三节点模板:

k8s/addons/rabbitmq-cluster

详细的 Operator 安装、StorageClass 配置、部署、凭据读取和验证步骤见:

k8s/addons/rabbitmq-cluster/README.md

自建模板默认使用 RabbitMQ 4.3.2 和 quorum queue。升级现有集群前必须在测试环境验证队列声明、发布消费、重连和故障切换,不能直接跨版本替换数据节点。

RabbitMQ 配置分为三部分:

  • AMQP 协议、地址、端口和 vhost 等非敏感连接参数位于 k8s/overlays/production/app-config.yaml,该文件会生成 EasyAI 应用的 ConfigMap
  • 用户名和密码位于 k8s/overlays/production/app-secret.yaml
  • 使用自建模板时,RabbitMQ 服务端参数写在 RabbitmqCluster 资源的 spec.rabbitmq.additionalConfig 中,由 Cluster Operator 管理,不需要额外提供 RabbitMQ ConfigMap。

RabbitMQ 版本生命周期参考:

https://www.rabbitmq.com/release-information

本地验证环境中的 PostgreSQL/pgvector 镜像为:

registry.cn-shanghai.aliyuncs.com/easyaigc/pgvector:0.8.2-pg18-trixie

外部依赖版本核对示例:

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 需要创建两个数据库,并启用扩展:

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;

最终需要准备两个连接串:

postgresql://USER:PASSWORD@HOST:5432/agent_governance?schema=public
postgresql://USER:PASSWORD@HOST:5432/easyai_memory?schema=public

修改生产配置

所有生产配置都在:

k8s/overlays/production

1. 修改非敏感配置

编辑:

k8s/overlays/production/app-config.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内网地址

如果使用统一域名访问,以下配置通常保持默认:

NUXT_PUBLIC_BASE_APIURL: /api
NUXT_PUBLIC_SG_APIURL: /asg-api

2. 修改敏感配置

编辑:

k8s/overlays/production/app-secret.yaml

至少替换以下内容:

CONFIG_DB_MONGO_URI: mongodb://你的Mongo内网地址:27017/?authSource=admin
CONFIG_DB_MONGO_DBNAME: aidraw
CONFIG_DB_MONGO_USERNAME: 你的Mongo用户名
CONFIG_DB_MONGO_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: 一段足够长的随机字符串

生成随机密钥示例:

openssl rand -base64 48

如果使用 OSS/S3,请同时替换:

OSS_ENDPOINT: ""
OSS_ACCESS_KEY_ID: ""
OSS_ACCESS_KEY_SECRET: ""
OSS_BUCKET: ""

生产密钥不要提交到公共 Git 仓库。正式环境建议接入 External Secrets、Sealed Secrets 或云厂商 Secret Manager。

3. 修改域名和证书

编辑:

k8s/overlays/production/ingress.yaml

将所有 easyai.example.com 替换为客户真实域名。

如果集群的 IngressClass 不是 nginx,同步修改:

ingressClassName: nginx

创建 TLS Secret

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. 修改共享存储

编辑:

k8s/overlays/production/shared-pvc.yaml

将占位符替换为真实的 RWX StorageClass

storageClassName: 你的RWX_StorageClass

默认 PVC 容量为 100Gi,可按客户实际文件量调整:

storage: 100Gi

部署前检查

确认没有未替换的占位符:

grep -R -nE 'CHANGE_ME|easyai.example.com|你的' k8s/overlays/production

使用自建 RabbitMQ 时,还需要检查其模板:

grep -R -n 'CHANGE_ME' k8s/addons/rabbitmq-cluster

如果还有输出,请先完成配置替换。

渲染生产 YAML

kubectl kustomize k8s/overlays/production > /tmp/easyai-production.yaml

检查资源类型:

grep '^kind:' /tmp/easyai-production.yaml

执行服务端 dry-run

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

部署

执行部署:

kubectl apply -k k8s/overlays/production

查看资源:

kubectl -n easyai get deploy,svc,pvc,ingress,hpa,pdb
kubectl -n easyai get pods -o wide

等待服务发布完成:

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 状态和日志:

kubectl -n easyai get pods -o wide
kubectl -n easyai describe pod <PodName>
kubectl -n easyai logs <PodName> --all-containers --tail=200

DNS 和访问验证

查看 Ingress 地址:

kubectl -n easyai get ingress

将客户域名解析到 Ingress 暴露的公网 IP 或 CNAME。

DNS 生效前,可以先用 curl --resolve 验证:

curl -i --resolve 你的域名:443:Ingress公网IP https://你的域名/api/health

DNS 生效后验证:

curl -i https://你的域名/api/health
curl -i https://你的域名/asg-api/health
curl -i https://你的域名/ams-api/health

浏览器访问:

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

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

回滚

如果是配置变更导致问题,可回到上一份配置后重新部署:

git checkout <上一个可用提交>
kubectl apply -k k8s/overlays/production

如果是镜像版本问题,请使用 EasyAI 提供的回滚版本或回滚仓库版本后重新执行部署。

查看发布历史:

kubectl -n easyai rollout history deploy/easyai-server

回滚单个服务:

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:3002Ingress 超时时间是否足够
文件上传后多副本不可见 easyai-shared-files PVC 是否正确挂载到 easyai-server
连接数据库或中间件失败 VPC、安全组、白名单、端口、用户名密码、TLS 要求
MongoDB 认证成功但业务库没有数据 CONFIG_DB_MONGO_DBNAME 是否为 aidrawauthSource 是否指向用户实际所在的认证库
RabbitMQ 集群 Pod 一直 Pending RWO StorageClass、PVC、3 个 Worker 节点以及主机级 Pod 反亲和规则
video-edit 无法创建 集群 PodSecurity/PSA 是否禁止 SYS_ADMIN capability

查看事件和日志:

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