分布式部署(按角色多机)
控制面按
control/user/media/edge四类角色拆到多台机器:每台机器克隆同一个仓库、跑同一条sudo ./install.sh,区别只在.env里的角色。存储与播放能力由外部工作节点提供。
这一页是分布式部署(DISTRIBUTED)的两种形态之一,对应部署仓库的 v3-multi-host 分支。control、user、media、edge 是分布式部署内部的角色, 不是独立的部署模式。
控制面只占一台机器?用同机形态
另一种形态是分布式·控制面同机(v2-all-in-one 分支): 同样 6 个应用服务,全部放在一台机器上,不需要角色变量,也不需要 join.env。 两者是同一个产品版本、同一套许可证,数据与工作节点通用——控制面压力大了再按本页拆开。
分布式部署需要 edition=DISTRIBUTED 的许可证
分布式部署只接受 edition=DISTRIBUTED。部署形态与许可证 Edition 严格一一匹配: 拿单机版许可证激活分布式部署会被拒绝,此时保留激活、许可证状态、日志和备份能力, 不开放业务功能,不删除任何数据。历史许可证(没有 edition 声明)按 DISTRIBUTED 兼容。详见授权与版本。
前置条件
| 项目 | 要求 |
|---|---|
| 机器数量 | 至少 4 台,必须位于同一私有网络 |
| 每台机器 | Docker Engine + Docker Compose v2、openssl、curl、python3,能用 sudo |
| 安装顺序 | control(只装一台)→ user → media → edge |
| 授权材料 | 一个 edition=DISTRIBUTED 的一次性授权码,只在网页里输入 |
| 出站网络 | control 能访问 YIYI_LICENSE_SERVER_URL 指向的授权中心(HTTPS)。其余机器只需要能访问 control |
| 私网端口 | 放行 5432、6379、18085、18089,见下方端口表 |
| 对用户开放 | 只有 edge 机器的 18080 |
角色模型:每台机器装什么
| 角色 | Compose profile | 启动的服务 | 数量 |
|---|---|---|---|
control | control | postgres、redis、license-agent、config | 4 |
user | user | license-sync、user | 2 |
media | media | license-sync、media | 2 |
edge | edge | license-sync、gateway、frontend | 3 |
control 上的 postgres 与 redis 可以用 YIYI_DB_MODE / YIYI_REDIS_MODE 换成外部实例(两者独立选择);换成外部后该机器只跑 license-agent 与 config 两个容器。 参数说明见控制面同机。
同机形态就是这四个角色装在一台机器上
v2-all-in-one 分支与你正在看的 v3-multi-host 是同一套控制面,只是布置不同。 所以「先同机跑起来、之后按本页拆成多机」是受支持的演进路径,数据与许可证都不用换。
单机版不是这里的一个角色
单机版部署不走 Compose profile 拆角色,它是 YiYi-media-standalone + YiYi-media-standalone-postgres + YiYi-media-standalone-redis 三容器聚合形态, 见单机版部署(三容器)。把多个分布式角色临时放在同一台物理机上, 产品能力仍然属于分布式版。
第 0 步:每台机器准备配置
四台机器都执行同样的命令(多机形态用 v3-multi-host 分支):
git clone -b v3-multi-host https://github.com/YiYi-Product/YiYi-media-deploy.git /opt/YiYi-media-deploy
cd /opt/YiYi-media-deploy
cp .env.example .env
chmod 0600 .env第 1 步:安装 control(主服务器)
只装一台。在 .env 中设置:
YIYI_DEPLOY_ROLE=control
YIYI_SERVER_HOST=<主服务器内网IP或域名>
YIYI_USER_HOST=<User服务器内网IP或域名>如需使用外部 PostgreSQL,同时填写 YIYI_DB_MODE=external 与数据库地址、端口、凭据,见下文「外部数据库」一节。
sudo ./install.shcontrol 的 YIYI_SERVER_HOST 必须是其他机器能访问到的地址
这一个值会同时决定各服务向注册中心登记的地址、数据库与 Redis 的绑定地址、集群同步证书里的主机名, 以及其他机器拉租约用的同步地址。填 127.0.0.1 或其他机器解析不到的名字,整条链路都会断。
control 上 install.sh 额外做三件事:
| 动作 | 结果 |
|---|---|
| 绑定基础设施 | YIYI_INFRA_BIND_HOST=<control 的 YIYI_SERVER_HOST>,postgres 与 redis 的端口发布到这个地址,私网内可达 |
| 打开集群同步 | YIYI_LICENSE_RELAY_LISTEN=0.0.0.0:18089,YIYI_LICENSE_SYNC_URL=https://<control 地址>:18089/v1/lease |
| 导出加入配置 | 安装成功后生成 join.env(0600)与根目录 cluster-relay.crt(0644) |
第 2 步:分发 join.env 与 cluster-relay.crt
control 安装成功后会打印:
已生成 join.env 和 cluster-relay.crt,请通过安全方式复制到其他节点。把这两个文件复制到 user、media、edge 机器的 /opt/YiYi-media-deploy/ 根目录(不是 config/ 子目录):
# 在 control 机器上执行,目标机用私网地址
scp -p /opt/YiYi-media-deploy/join.env \
/opt/YiYi-media-deploy/cluster-relay.crt \
<用户名>@10.0.0.12:/opt/YiYi-media-deploy/join.env 由 control 的 .env 导出,含数据库地址与凭据(YIYI_DB_HOST、YIYI_DB_USER、YIYI_DB_PASSWORD,以及可选的 YIYI_DB_MODE、YIYI_DB_PORT)、Redis 地址与密码、注册中心地址 YIYI_CONFIG_HOST、YIYI_USER_HOST、服务令牌 YIYI_SERVICE_TOKEN、集群同步令牌 YIYI_LICENSE_CLUSTER_TOKEN、授权中心地址 YIYI_LICENSE_SERVER_URL 与集群同步地址 YIYI_LICENSE_SYNC_URL。
join.env 等同于一份完整的集群凭据
它包含数据库口令、服务令牌与集群同步令牌。用 scp 或其他加密通道传输, 不要贴到聊天工具、不要提交到 Git(部署仓库的 .gitignore 已忽略它)。
第 3 步:安装 user、media、edge
在各自的 .env 中填写:
YIYI_DEPLOY_ROLE=user
YIYI_SERVER_HOST=<本机内网IP或域名>
YIYI_PUBLIC_HOST=<edge的公网IP或域名>media 与 edge 机器同理,只把 YIYI_DEPLOY_ROLE 换成 media 或 edge。然后每台执行相同命令:
sudo ./install.sh脚本检测到 join.env 存在时会自动:
- 把
join.env里的必填键覆盖写入本机.env,可选键(YIYI_DB_MODE、YIYI_DB_PORT)在join.env里存在时才覆盖; - 把根目录的
cluster-relay.crt复制到config/cluster-relay.crt,权限0644。
不要在这些机器上手填数据库与令牌
user、media、edge 的数据库地址、Redis 地址、注册中心地址、服务令牌与集群同步令牌 全部来自 join.env。手工填的值会被覆盖,而且各机器必须完全一致。 你只需要填角色与本机地址。
第 4 步:删除其他机器上的 join.env
# 在 user、media、edge 机器上分别执行
rm -f /opt/YiYi-media-deploy/join.env只删 join.env,不要删 config/cluster-relay.crt
安装完成后要从其他服务器删除 join.env。但 config/cluster-relay.crt 是 license-sync 校验集群同步服务端的 CA 文件,预检每次都会检查它非空。删掉之后再跑 install.sh 会报「集群同步证书缺失」。
第 5 步:访问并激活
http://<公网IP或域名>:18080打开 edge 机器的 18080,按页面提示输入发布方提供的一次性授权码。授权激活全部在网页完成, 不需要命令行激活,也不需要在四台机器上分别激活——租约由 control 换取,其余机器每 30 秒同步一次。
授权在集群里怎么分工
control 装授权代理 license-agent:它生成部署身份、用授权码换签名租约、定期续租,并在 18089 上为集群提供租约同步。user、media、edge 跑 license-sync,每 30 秒从 control 拉一次租约 写到本机,不联系授权中心。
私网端口放行
这四个端口只在私网内放行:
| 端口 | 用途 | 公网 |
|---|---|---|
5432 | 数据库 | 禁止 |
6379 | 缓存 | 禁止 |
18085 | 集群通信 | 禁止 |
18089 | 集群许可证同步 | 禁止 |
完整的跨机可达性:
| 端口 | 监听方 | 绑定地址 | 谁需要访问到它 |
|---|---|---|---|
18080 | edge 的 frontend | host 网络 | 用户浏览器,唯一对外开放的端口 |
5432 | control 的 postgres | control 的内网地址 | control 的 config、user 机的 user、media 机的 media |
6379 | control 的 redis | 同上 | user 机的 user、media 机的 media |
18085 | control 的 config | host 网络 | user、media、edge 三台机器,以及所有外部工作节点 |
18082 | user 机的 user | host 网络 | control 的 config 与 edge 的 gateway |
18083 | media 机的 media | host 网络 | 私网内的其他控制面服务 |
18086 | edge 机的 gateway | host 网络 | 同机 frontend 经 127.0.0.1 访问,不需要跨机放行 |
18088 | 每台的 license-agent / license-sync | 127.0.0.1 | 只有本机服务,天然不可跨机 |
18089 | control 的 license-agent relay | 0.0.0.0 | user / media / edge 的 license-sync(HTTPS) |
不得开放到公网
5432、6379、18085、18089 这四个端口不要开放到公网。上表里的 18082、18083、18086 同样只应在私网内可达。对外只留 edge 的 18080,并且生产环境要在它前面配 HTTPS。
外部数据库 YIYI_DB_MODE=external
默认 bundled 模式在 control 上装内置 PostgreSQL。要让 config、user、media 共用一个外部实例,在 control 的 .env 里设置:
YIYI_DB_MODE=external
YIYI_DB_HOST=<PostgreSQL服务器IP或域名>
YIYI_DB_PORT=5432
YIYI_DB_USER=<数据库用户>
YIYI_DB_PASSWORD=<数据库密码>外部 PostgreSQL 必须预先创建三个数据库,并授权上述用户连接和建表:
CREATE DATABASE yiyi_config;
CREATE DATABASE yiyi_user;
CREATE DATABASE yiyi_media;
-- 授权语句按你的实例版本与权限策略执行,示例:
GRANT ALL PRIVILEGES ON DATABASE yiyi_config TO <数据库用户>;
GRANT ALL PRIVILEGES ON DATABASE yiyi_user TO <数据库用户>;
GRANT ALL PRIVILEGES ON DATABASE yiyi_media TO <数据库用户>;yiyi_storage 不在这里建,它由 Storage 工作节点自己的部署配置管理。
单机版的数据库口径不同
单机版是同一个内置 PostgreSQL 实例承载四个数据库(含 yiyi_storage), 不需要你预建任何库,见单机版部署(三容器)。
external 模式下 install.sh 的行为:
- 不启动内置 PostgreSQL
- 不创建、不改权限、不校验本地的
data/postgres - 强制校验实际凭据:
YIYI_DB_HOST必须是不带协议和端口的主机名,YIYI_DB_USER与YIYI_DB_PASSWORD非空 - 不迁移数据:从
bundled切到external前必须自行迁移那三个库 - Redis 不受影响:该模式只替换 PostgreSQL
外部工作节点层
控制面拆成 4 台机器之后,Storage 节点与 Play Agent 节点并不属于这 4 台中的任何一台:
- 不在
compose.yaml里,install.sh也不安装它们; - 不读
YIYI_DEPLOY_ROLE,与control/user/media/edge的划分无关; - 在网页「节点管理」里创建节点,复制页面给出的一行安装命令到目标机执行;
- 可以部署在任意数量、任意位置的服务器上,只要那台机器能访问
control的18085; - 加节点就是扩容,同一类节点可以多实例,控制面一行配置都不用改。
控制面:4 台机器,同一私网,由 YiYi-media-deploy 安装
┌───────────────────┐ ┌──────────────┐ ┌──────────────┐ ┌───────────────────────┐
│ control │ │ user │ │ media │ │ edge │
│ config 18085 │ │ user 18082 │ │ media 18083 │ │ gateway 18086 │
│ postgres 5432 │ │ license-sync │ │ license-sync │ │ frontend 18080 ◄──────┼── 用户
│ redis 6379 │ └──────────────┘ └──────────────┘ │ license-sync │
│ license-agent │ └───────────────────────┘
│ relay 18089 │
└─────────┬─────────┘
│ 只连 config 的 18085(注册中心),地址与令牌由网页一键下发
│
工作节点层:任意多台服务器,与控制面角色无关,不由部署包安装
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Storage 节点 #1 │ │ Storage 节点 #2 │ │ Play Agent #1 │ │ Play Agent #2 │
│ 18084 │ │ 18084 │ │ 19090 │ │ 19090 │
└──────────────────┘ └──────────────────┘ └──────────────────┘ └──────────────────┘
…… 需要多少台就加多少台 ……一个常见组合是「4 台控制面 + N 台存储 + M 台播放」:控制面规模固定,N 与 M 随网盘数量 与播放并发增长,并受授权配额限制(maxStorageNodes 与 maxPlayAgentNodes), 见授权与版本与分布式工作节点部署。
与单机版的三点关键差异
- 单机版的 Storage 与 Play Agent 是内置节点,随主应用升级;分布式版是外部节点,各自独立安装与升级。
- 单机版不允许新增外部节点;分布式版按授权配额新增。
- 单机版只能新增手动反代地址;分布式版既能新增节点也能新增反代地址。
验证
每台机器在部署目录里执行:
cd /opt/YiYi-media-deploy
docker compose psinstall.sh 末尾的健康检查按角色探测这些端点,可以手工复现:
| 角色 | 端点 |
|---|---|
control | http://127.0.0.1:18088/v1/status(license-agent)、http://127.0.0.1:18085/api/license/status(config) |
user | http://127.0.0.1:18088/v1/status(license-sync)、http://127.0.0.1:18082/api/license/status |
media | http://127.0.0.1:18088/v1/status(license-sync)、http://127.0.0.1:18083/api/license/status |
edge | http://127.0.0.1:18088/v1/status(license-sync)、http://127.0.0.1:18086/api/license/status、http://127.0.0.1:18080/ |
# 跨机连通性:在 user / media / edge 机器上验证能连到 control
curl -fsS http://<control内网地址>:18085/actuator/health
# 在 control 上验证 postgres 与 redis 已在私网地址上监听
ss -lntp | grep -E '5432|6379'
# 在 user / media / edge 上验证集群许可证同步可达
curl -fsS --cacert config/cluster-relay.crt https://<control内网地址>:18089/v1/lease最后从用户实际访问的那台机器(不是服务器本机)打开 http://<edge公网地址>:18080, 确认能看到激活页。
常见错误
| 现象 | 原因 | 处理 |
|---|---|---|
想把 frontend 单独放一台机器 | 不存在这种角色,frontend 与 gateway 同属 edge | 网页入口机就是 edge,两个服务一起装 |
user 角色缺少 join.env | control 还没装,或 join.env 没复制过来 | 先装 control,再按第 2 步分发 |
user 角色缺少 cluster-relay.crt | 只复制了 join.env | 两个文件都要复制到部署目录根 |
Control 角色必须填写 YIYI_USER_HOST | control 的 YIYI_USER_HOST 没填或填错 | 填 user 机器的内网地址,改完在 control 重跑安装 |
| 服务注册上了但互相调用超时 | YIYI_SERVER_HOST 填了 127.0.0.1 或不可达地址 | 改成其他机器能访问到的内网地址 |
license-sync 拿不到租约 | config/cluster-relay.crt 被删;18089 没在私网放行;或证书与同步地址主机名不匹配 | 逐项排查;改过 control 地址的要重签并重新分发证书 |
| 激活被拒绝 / 提示版本不匹配 | 授权 Edition 与部署形态不一致 | 分布式部署要 edition=DISTRIBUTED |
从 bundled 切到 external 后数据全没了 | 脚本不会复制数据库内容 | 切换前先 pg_dump 三个库,切完再恢复 |
edge 页面能开但接口全失败 | frontend 与 gateway 不在同一台机器 | 装成同一个 edge 角色 |