chengcheng 024f9267a9 fix(security): drop SYS_ADMIN from video editor
The published service disables the Chromium sandbox and does not perform system administration operations, so the broad capability is unnecessary. Drop all capabilities, prevent privilege escalation, and use the runtime default seccomp profile.
2026-07-23 11:12:03 +08:00
2026-07-09 19:29:46 +08:00

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

生产初始规格与容量基线

客户尚未提供业务容量数据时,可先按下表准备生产环境。表中的 CPU、内存和磁盘均为单个数据节点的规格,标注“当前模板”的项目与仓库 YAML 一致;标注“官方容量参考”的项目引用官方规格指南;标注“项目初始值”的项目是用于首次部署和压测的起点,不是官方最低配置或吞吐量承诺。

数据库访问量应使用峰值数据库读写操作数、事务数和活跃数据库会话衡量,不能直接用日活、PV 或在线用户数代替。同一个 API 请求可能不访问数据库,也可能触发多次查询、写入或后台任务。

EasyAI 应用 Pod 当前资源规格如下,CPU 和内存均为单个 Pod 的配置:

服务 最小/固定副本 HPA 上限 CPU 请求/上限 内存请求/上限
easyai-web 2 10 200m / 1 CPU 512Mi / 1500Mi
easyai-server 2 20 500m / 2 CPU 1Gi / 2500Mi
ws-gateway 2 10 200m / 1 CPU 256Mi / 512Mi
video-edit 1 5 1 CPU / 2 CPU 2Gi / 4Gi
sandbox 固定 1 无 HPA 500m / 1 CPU 512Mi / 1Gi
easyai-asg 2 8 200m / 1 CPU 256Mi / 512Mi
agent-memory 2 8 200m / 1 CPU 256Mi / 512Mi
依赖 建议生产拓扑 单节点初始规格 初始存储容量 备注
MongoDB 云服务高可用版,或 3 个数据节点的副本集 Atlas M30 参考值为 2 vCPU / 8GB;自建环境以压测为准 无存量数据时每节点可从 50Gi SSD 开始压测;已有数据按下方公式计算 M303000/s2050GB 是 Atlas 近似集群负载,不是自建单节点性能承诺
Redis 云服务高可用版,或主节点 + 2 个副本并配套 Sentinel 2 vCPU / 4Gi 每节点 20Gi SSD,建议 maxmemory 初始设为 2Gi 规划参考;必须支持多个逻辑 DB 和 SELECT,当前不支持 Redis Cluster 模式
RabbitMQ 3 节点集群,持久化业务队列使用 quorum queue 请求 1 vCPU / 2Gi,上限 2 vCPU / 2Gi 每节点 50Gi RWO SSD,总计 150Gi 当前自建模板实际值;高吞吐或大消息场景需压测后增加内存和磁盘
PostgreSQL + pgvector 云服务高可用版,或主库 + 备库并配置经过验证的自动故障切换、隔离机制和统一访问端点 项目初始参考 2 vCPU / 8Gi 无存量数据时每节点可从 50Gi SSD 开始压测;已有数据按下方公式计算 按实际 SQL、并发客户端、向量规模和检索压测调整;本地 1 CPU / 1Gi 仅为功能验证上限
RWX 共享存储 支持高可用和在线扩容的 RWX 存储 由存储服务决定 初始总容量 100Gi 当前生产 PVC 实际值;不包含独立备份空间
OSS/S3 对象存储 云厂商托管对象存储 由对象存储服务决定 按量使用,无需预分配固定容量 可选;建议配置生命周期和历史文件清理策略
MongoDB 规格计算依据

MongoDB Atlas Cluster Size Guide 明确说明规格表仅用于近似起点,最终规格需要根据资源需求、性能目标、负载特征和增长持续迭代。官方给出的初步估算公式为:

预计数据存储 = 原始数据量 × 50%
预计 RAM = 原始数据量 × 10%
预计 CPU 核数 = 峰值数据库读写操作数/秒 ÷ 4000
预计存储 IOPS = 峰值数据库读写操作数/秒

Atlas 官方档位如下。CPU、内存和 IOPS 是 Atlas 数据节点的规格,典型数据量和峰值读写操作数是近似集群负载;自建 MongoDB 的云盘、CPU 型号和文件系统不同,不能把 Atlas 数值当作自建环境的固定性能承诺。

Atlas 参考档 CPU 内存 默认 IOPS 典型数据量 峰值读写操作数 官方用途
M10 2 2GB 1000 110GB 200/s 开发/测试
M30 2 8GB 3000 2050GB 3000/s 生产
M50 16 32GB 3000 360420GB 11000/s 生产
M80 32 128GB 3000 12001750GB 39000/s 生产

使用 MongoDB Atlas 时,客户未提供容量和压测数据可先选择 M30 作为生产准备参考,而不是原来的 4 vCPU / 16Gi 自建节点规格。自建环境可以使用 2 vCPU / 8Gi 作为首轮压测候选,但不能直接继承 Atlas 的吞吐量结论。如果实测负载低于 M10 参考范围,可在客户接受性能验证结果的前提下降配;高于 M30 范围时,应按数据量和峰值操作数选择更高档位并重新压测。

MongoDB 的实际峰值操作数应通过 mongostatserverStatus.opcounters 的时间差值测量,现有物理数据和索引大小通过 dbStats 测量。项目数据盘计算公式为:

MongoDB 单节点数据盘
>=(压缩后数据 + 索引 + oplog + 在线保留期增长量)÷ 0.7

除以 0.7 是为了符合本项目“使用率达到 70% 告警”的运维策略,不是 MongoDB 官方固定系数。3 个数据节点用于副本集高可用,每个节点都需要容纳完整数据副本;MongoDB 官方推荐的最小副本集配置是 3 个数据承载节点。

PostgreSQL 与 pgvector 规格计算依据

PostgreSQL 官方没有提供“多少 QPS/TPS 对应多少 CPU 和内存”的通用硬件表。查询复杂度、索引命中率、并发事务、向量维度、HNSW/IVFFlat 选择、召回率目标和存储延迟都会显著改变结果。为了给首次生产部署提供可执行的压测起点,本项目采用单节点 2 vCPU / 8Gi:按照 PostgreSQL 18 Resource Consumption 的建议,将 shared_buffers 从总内存的 25% 起步时约为 2Gi,其余内存用于操作系统文件缓存、并发 work_mem、连接进程、维护任务和 pgvector。该数值是项目初始参考,不是 PostgreSQL 官方最低配置或吞吐量承诺,最终规格仍必须通过实际负载确定。

自建高可用不能只写成“1 主 1 备”。还必须使用经过验证的高可用管理方案完成故障检测、自动切换、主库隔离或 fencing、客户端访问端点切换以及故障域隔离;所选方案需要仲裁或 witness 时还必须部署对应组件,并完成故障演练。

内存规划应遵循 PostgreSQL 18 Resource Consumption

  • 专用数据库服务器的 shared_buffers 可从系统内存的 25% 起步;官方说明超过 40% 通常不会比更小的值更好,因为 PostgreSQL 同时依赖操作系统文件缓存。
  • work_mem 是每个排序或哈希操作的基础上限,一个复杂查询可能同时使用多份 work_mem,多个会话还会并发叠加;哈希操作的内存上限还要乘以 hash_mem_multiplier,默认值为 2.0
  • maintenance_work_mem 可用于 VACUUM 和建索引,但 autovacuum 最多可能按 worker 数量重复分配相关内存。
  • max_connections 默认通常为 100,提高它会增加共享内存等资源分配;连接上限不能当作数据库吞吐量目标。

规划并发内存时至少要检查以下上界,而不能只看 shared_buffers

排序瞬时内存
≈ 活跃排序操作实例数 × work_mem

哈希瞬时内存
≈ 活跃哈希操作实例数 × work_mem × hash_mem_multiplier

HNSW 迭代扫描内存
≈ 并发 HNSW 扫描执行实例数 × work_mem × hnsw.scan_mem_multiplier

数据库节点内存
> shared_buffers
  + 排序瞬时内存
  + 哈希瞬时内存
  + HNSW 迭代扫描内存
  + autovacuum/维护任务内存
  + 会话本地内存、连接进程、操作系统和文件缓存预留

pgvector 0.8.2 官方说明指出,HNSW 的查询性能通常优于 IVFFlat,但建索引更慢且使用更多内存;当 HNSW 图可以放入 maintenance_work_mem 时建索引明显更快,同时明确警告不能把该参数设置到耗尽服务器内存。hnsw.ef_searchhnsw.scan_mem_multiplier 和 IVFFlat probes 也会在召回率、速度和内存之间产生取舍。上式中的执行实例数必须把 leader 和参与查询的并行 worker 分别计算。存在较大向量索引或在线建索引需求时,应根据实际 HNSW 图大小临时提高维护窗口资源并重新压测,不能预先写死 CPU 和内存规格。

PostgreSQL 单节点数据盘按实际数据库大小计算:

PostgreSQL 单节点数据盘
>=pg_database_size('agent_governance')
   + pg_database_size('easyai_memory')
   + 其他数据库和集群级空间
   + WAL 预留
   + 临时文件预留
   + 最大计划索引重建、REINDEX 或表重写工作空间
   + 在线保留期增长量)÷ 0.7

pg_database_size 包含数据库中的表、索引和 TOAST 数据;使用额外 tablespace 时还要分别确认其存储卷容量。WAL 位于集群级目录,需要单独预留。PostgreSQL WAL 官方说明指出 max_wal_size 是软限制,在高负载、归档失败、较大的 wal_keep_size 或复制槽滞后时可能被超过,因此不能只按 max_wal_size 配置磁盘。主库和物理备库都需要容纳完整数据副本,备份和归档空间另行计算。

PostgreSQL 最终规格必须使用 PostgreSQL pgbench 的自定义事务脚本模拟 EasyAI 实际 SQL:

  1. 使用 -f 编写覆盖 Agent 治理写入、记忆写入、普通查询和向量检索的混合事务脚本;
  2. -c 表示并发客户端连接数,不等于生产环境的活跃会话数或请求到达率;需要结合实际连接池、思考时间,并在模拟固定到达率时使用 -R,同时通过 pg_stat_activity 验证数据库内实际活跃会话;
  3. 使用 -T 运行至少数分钟并重复多轮;
  4. 记录 TPS、事务延迟、失败事务和超过延迟限制的事务,不能使用默认 TPC-B-like 脚本结果直接代表 EasyAI
  5. 同时检查 pg_stat_database 的连接数、事务提交/回滚、磁盘块读取、临时文件、临时字节数和死锁;
  6. 启用 pg_stat_statements 后,检查实际 SQL 的调用次数、平均/最大执行时间、缓存命中、临时块、WAL 量和 I/O 时间;只有启用 track_io_timing 后 I/O 时间字段才有有效值,启用前应评估所在平台的计时开销;
  7. 选择满足客户峰值负载和延迟目标的最小规格,并在向量数量、维度、索引类型或召回率目标改变后重新压测。
容量信息与扩容规则

上线前请客户补充以下信息,以便把初始参考规格调整为最终规格:

  • API 峰值 QPS、MongoDB 峰值读写操作数/秒和 PostgreSQL 峰值 TPS
  • PostgreSQL 峰值活跃数据库会话数、目标事务延迟和主要 SQL 类型;
  • 每日任务量、峰值队列积压量及单条消息大小;
  • MongoDB 原始/压缩数据、索引和 oplog 大小;
  • PostgreSQL 两个数据库的 pg_database_size、WAL 峰值和临时文件峰值;
  • 向量条数、向量维度、索引类型、目标召回率和是否需要在线建索引;
  • 每日数据库增量和在线保留天数;
  • 每日上传文件量、平均文件大小和文件保留周期;
  • 备份周期、保留份数以及 RPO/RTO 要求。

所有数据盘在使用率达到 70% 时告警,达到 80% 前完成扩容。备份、快照、WAL 归档和跨区域副本空间单独计算。当前本地验证模板中 MongoDB 上限为 1 CPU / 2500MiPostgreSQL 上限为 1 CPU / 1Gi,且均使用单节点 emptyDir;这些数值只证明低负载功能验证可以运行,不能作为生产容量依据。

资源规划参考:

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_SECURITY_ORIGIN: https://你的域名
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: 一段足够长的随机字符串
CONFIG_INITIAL_ADMIN_PASSWORD: 至少12位的EasyAI初始管理员密码

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: 与CONFIG_INITIAL_ADMIN_PASSWORD相同

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 拒绝事件;清单兼容 Baseline,强制 Restricted 时当前镜像仍需改为非 root 运行

查看事件和日志:

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
S
Description
No description provided
Readme
160 KiB