外观
第 4 章 安装与配置
4.1 租户开通
租户开通由沅虹运营执行 sense-tenant,脚本编排处理节点、中心与公网入口三类角色:
sense-tenant add <租户> <序号n> [--name 名称] [--workers 2] [--disk 500G] [--rotate-link-key] [--dry-run]
sense-tenant status <租户> <序号n>
sense-tenant remove <租户> <序号n> --yes序号 n(1 至 19)决定全部编号:uid=2000+n,网段 10.90.n.0/30(节点在 .2),中心端口 8090+n,视频墙端口 5060+n。序号分配后不再复用。每台机器上的动作先判断再执行,同一租户重复执行结果一致。
脚本在各角色上的动作:
| 角色 | 动作 |
|---|---|
| 处理节点 | 系统用户 sense-<租户>、网络命名空间(一对 veth)、XFS 存储镜像、模板单元 uansense-node@<租户>、NFS 导出给中心、mediamtx 按来源地址限制该租户只读自己的流、nftables 仅放行必要端口、回放地址表 /etc/uansense/centers.map 增加一行 |
| 中心 | 同名同 uid 用户、模板单元 uansense@<租户>(独立端口、会话密钥、只认本租户门户票、随机管理员口令)、NFS 挂载节点数据目录、公网入口到该实例的转发 |
| 公网入口 | 在入口网关的三张 map(接口上游、视频墙路径、前端目录,vision.uanhon.cn 与 sense.uanhon.cn 共用)各登记一行;不建子域、不签证书 |
| 控制面 | 执行环境中存在 UANLINK_ADMIN_KEY 时建立租户、取得租户钥匙并写入中心环境(UANLINK_TENANT_KEY);不存在时提示并跳过 |
控制面地址分为两个变量:脚本自身调用控制面使用 UANLINK_URL;写入中心环境的地址必须是中心可达的地址(SENSE_LINK_URL_CENTER,缺省 https://link.uanhon.cn),给出回环地址时脚本拒绝执行。
节点共享目录 /opt/uansense(Python 环境与模型)为只读共享,租户代码树中的 models 以软链指向它。脚本先移走代码树中原有的 models 目录再建立软链,避免软链建到目录内部导致模型无法加载。
4.2 接入盒安装
安装包发布在下载站 https://dl.uanhon.cn/box/:get.sh 引导脚本、latest 当前版本号、<版本>/ 目录下两个架构的安装包、install.sh、SHA256SUMS。
bash
# 双网口盒子(蓝口宽带、黄口相机),安装后需重启
curl -fsSL https://dl.uanhon.cn/box/get.sh | sudo bash -s -- --router
sudo reboot
sudo uanbox-prebind <接入码>
# 单网口主机,安装后直接入网
curl -fsSL https://dl.uanhon.cn/box/get.sh | sudo bash -s -- --code <接入码>
# 两台盒子接同一台相机交换机互备:另一台使用 --ha 2
curl -fsSL https://dl.uanhon.cn/box/get.sh | sudo bash -s -- --router --ha 1get.sh 按机器架构获取 latest 与 SHA256SUMS,核对 install.sh 与安装包的哈希后交给 install.sh。除 --code 与 --base(更换下载站)外的参数原样透传。
install.sh 参数:
| 参数 | 用途 | |:------------------------|:-------------------------------------|:------------------------------------| | --bundle <目录或 tar.gz> / --url <地址> --sha256 <值> | 包来源;均未指定时,脚本所在目录若为解开的安装包则直接使用 | | --link <地址> | 控制面地址,缺省 link.uanhon.cn;已有 agent.env 时不改 | | --router | 双网口:WAN 口自动获取地址,LAN 口固定 192.168.88.1/24 并给相机分配地址,不转发。重启后生效 | | --wan / --lan | 网口名不是 enp1s0 / enp2s0 时指定 | | --ha 1|2 | 两盒互备:黄口 .2 / .3,仅 1 号分配地址,.1 由 keepalived 浮动(VRRP 组 88,1 号优先级 150,回抢延迟 30 秒),防火墙放行 VRRP | | --pppoe <账号> | 光猫桥接需要拨号。口令按提示输入或经环境变量 UANBOX_PPPOE_PASS 传入,不进入命令行 | | --ssh-wan / --ssh-lan | 防火墙缺省不放行 SSH;远程维护加前者,技术员现场接黄口维护加后者 | | --no-apt | 离线镜像已装 chrony、ffmpeg 时跳过系统包安装 | | --reset-machine-id | 制作出厂镜像克隆前必须指定(见下) | | --any-distro | 发行版不在 Debian 12+ / Ubuntu 22.04+ 范围时仍安装,仅用于测试机,通常与 --no-apt 同用 | | --dry-run / --uninstall / --purge / --root <假根> | 演示、卸载、连身份一起删除、测试用假根 |
安装内容:
| 路径 | 说明 |
|---|---|
/opt/uanbox/versions/<版本>/ 与 current 软链 | 两个二进制、install.sh、prebind.sh、MANIFEST;升级进入新目录后原子切换,旧版本保留 |
/usr/local/sbin/uanbox-prebind | 指向 current/prebind.sh |
/etc/uanbox/agent.env(600) | UANBOX_LINK、UANBOX_STATE、UANBOX_CAMERA_SECRETS、UANBOX_MEDIAMTX_YML、UANBOX_MEDIAMTX_API、RUST_LOG |
/etc/uanbox/cameras.secret(600) | 相机口令,每行 IP 账号 口令;手工填写的优先于接入页下发的 |
/etc/uanbox/mediamtx.yml(600) | 首次为空配置,之后由代理整份覆盖 |
/var/lib/uanbox/(700) | 身份(box.key、seal.key、state.json)、下发配置、记账、标签、备份 |
uanbox-mediamtx.service、uanbox-agent.service | Restart=always,代理在 mediamtx 之后启动 |
/etc/chrony/conf.d/uanbox.conf | 国内公共 NTP;--router 时允许黄口网段对时 |
--router 另外写入 systemd-networkd 的两个 .network、/etc/sysctl.d/90-uanbox.conf(关闭转发)、/etc/uanbox/firewall.nft(仅管理 inet uanbox 一张表)以及拨号时的 ppp 配置。修改前的原文件备份到 /var/lib/uanbox/backup-<时间>/。
制作出厂镜像必须指定 --reset-machine-id。硬件指纹为 machine-id 与物理网卡 MAC 的哈希,克隆镜像的盒子指纹相同,第二台入网会被控制面拒绝("这台机器已有在用的盒子")。母机清除后不再执行预绑定。
4.3 预绑定
预绑定在沅虹办公场所完成。前提:盒子已安装(双网口带 --router 并已重启),蓝口可上网。接入码在接入页"生成接入码"获取,24 小时有效、仅可使用一次。
bash
sudo uanbox-prebind ABCD-EFGH-JKLM # 入网、显示自检判定、启动两个单元、打印标签
sudo uanbox-prebind --label # 重印标签预绑定场所的自检结论不代表现场,盒子到现场更换宽带后会重新自检。已入网的盒子会被拒绝:先在控制面吊销,待盒子收到吊销并自行标记后,再预绑定。不要直接删除 /var/lib/uanbox:控制面旧记录仍在,相同硬件指纹会被拒绝(409),旧记录也无法正常停用。
4.4 升级、回滚与卸载
升级:再次执行安装命令(或 install.sh --bundle <新包>)。回滚:
bash
ls /opt/uanbox/versions/
sudo ln -sfn versions/<旧版本> /opt/uanbox/.current.new && sudo mv -T /opt/uanbox/.current.new /opt/uanbox/current
sudo systemctl restart uanbox-mediamtx uanbox-agent身份与口令文件不随版本变动,回滚无需重新入网。卸载 install.sh --uninstall 保留身份与口令,--purge 连身份一起删除(控制面上的记录由运营吊销)。网口配置在卸载时保留,避免卸载过程中断开自身网络。
4.5 安装包构建与发布
bash
# 构建主机上执行;mediamtx 使用官方 v1.21.1 发布包
MEDIAMTX_TAR=<x86_64 包路径> MEDIAMTX_TAR_AARCH64=<aarch64 包路径> deploy/box/make-bundle.sh --arch all
deploy/box/publish.sh # 上传到公网入口,切换 latest,从公网回读 Content-Length 核对版本号为 <Cargo 版本>-g<提交号>,工作区有未提交改动时带 .dirty,publish.sh 拒绝发布 dirty 版本。下载站的 nginx 配置不得引入扫描器拦截片段,该片段会拦截全部 .tar.gz 请求。
4.6 控制面部署
二进制 /opt/uanlink/uanlink(musl 静态链接,cargo build --release --target x86_64-unknown-linux-musl -p uanlink),环境文件 /etc/uanlink.env(UANLINK_ADMIN_KEY、UANLINK_INGEST_HOST、UANLINK_DB、UANLINK_BIND),数据库 /var/lib/uanlink/uanlink.db(sqlite WAL,权限 600,含推流口令明文),单元 uanlink.service。
版本更新:备份二进制与数据库,新二进制先复制到 /tmp 再 mv 替换,systemctl restart uanlink,检查 GET /v1/admin/hubs 返回 200 且盒子心跳正常。数据库在启动时自动补列建表,旧版本不读取新列,回滚无需处理数据库。
nginx conf.d/link.conf:/v1/box/ 与 /v1/t/ 的 client_max_body_size 2m,/v1/t/ 仅放行中心主机的出口 IP(出口变更时同步修改),/v1/admin/ 按来源白名单放行。
4.7 处理节点与中心部署
节点代理 uanhub-agent 在处理节点本机编译,x-hub-key 每个节点一把。它将 p_ 开头的推流账号整段替换进 /opt/mediamtx/mediamtx.yml 的 authInternalUsers(本机与视频墙的固定条目不动),先写临时文件再改名,两次写入至少间隔 1.2 秒,写入后通过 /v3/config/global/get 核对。
节点侧三项自动机制:公网地址跟随(每 15 秒 STUN,连续两次得到同一新地址即更新 webrtcAdditionalHosts,UANHUB_PUBLIC_HOSTS=off 关闭);上行拥塞卸路(每 10 秒按现场汇总丢包,连续 3 个窗口不低于 5% 判定拥塞,卸载到测得容量的一半,恢复需连续 3 个窗口低于 1%,UANHUB_SHED=off 关闭);配置检查(出现 turn: 或非中国大陆地址时拒绝写入)。
回放直连依赖处理节点上的两项配置:/opt/uansense/bin/clip-stream(按需转码脚本)与 /etc/uansense/centers.map(租户到中心地址的映射,每行 <租户> http://<中心地址>:<端口>);mediamtx 的路径模板与匿名读权限由 deploy/cloud/mediamtx-clip-path.py 幂等写入。
中心接入页的后端为 console/link_api.py,环境变量位于 env.d/center:UANLINK_URL、UANLINK_TENANT_KEY、UANLINK_TENANT、SENSE_INGEST_RTSP、UANLINK_HUB_NAME。未配置租户钥匙时接入页不开通,/api/link/* 一律返回 503。