以下步骤前提条件:
系统为Ubuntu22.04或其它支持的系统
没有安装 Docker
没有部署过其它系统
拥有root权限并切换成root
网络连接正常,能访问互联网
登录 Docker仓库
以 Ubuntu为例,先登录一个普通用户,再输入 sudo -i 切换到 root
# 输入当前用户密码(非root密码) # 切换到root后,提示符由$变为# # 比如登录了一个 XXXX 用户,输入命令后再输入 XXXX 的密码 xxxx@xxxxserver:~$ sudo -i [sudo] password for xxxx: root@tianrunserver:~#
ip命令
# 查看 IP 地址 ip addr ip addr show dev eth0 # 临时添加 IP 地址,重启失效 ip addr add 10.102.66.200/24 dev eth0 # 启动和停用网卡 ip link set dev eth0 up ip link set dev eth0 down # 查看路由 ip route show # 临时添加默认路由 ip route add default via 10.102.66.1 # 删除默认路由 ip route del default via 10.102.66.1 # 清空网络 ip addr flush eth0 # 临时配置DNS vim /etc/resolv.conf
netplan管理网络(Ubuntu)
配置文件/etc/netplan/99_config.yaml(名字可以是其它的,如果需要系统管理需要这个名称)
动态 获取 IP 配置示例
network: version: 2 renderer: networkd ethernets: enp3s0: dhcp4: true
静态 获取 IP,可以设置 IP,路由,DNS,注意网卡名
network: version: 2 renderer: networkd ethernets: eth0: addresses: - 10.10.10.2/24 routes: - to: default via: 10.10.10.1 nameservers: search: [mydomain, otherdomain] addresses: [10.10.10.1, 1.1.1.1]
配置生效运行
netplan apply
时区设置
# 查看时区设置 timedatectl # 设置时区为上海 timedatectl set-timezone Asia/Shanghai # 设置为24小时格式(可选) export LC_TIME=en_DK.UTF-8
时间同步服务(Ubuntu)
# 配置 echo "[Time] NTP=ntp.aliyun.com FallbackNTP=ntp.tuna.tsinghua.edu.cn" > /etc/systemd/timesyncd.conf # 启动 systemctl enable systemd-timesyncd systemctl restart systemd-timesyncd
时间同步服务(CentOS)
# 安装 yum install chrony # 配置 echo "server ntp.aliyun.com iburst stratumweight 0 driftfile /var/lib/chrony/drift rtcsync makestep 10 3 bindcmdaddress 127.0.0.1 bindcmdaddress ::1 keyfile /etc/chrony.keys commandkey 1 generatecommandkey logchange 0.5 logdir /var/log/chrony" > /etc/chrony.conf # 启动服务 systemctl start chronyd systemctl enable chronyd # 查看状态 chronyc sources
说明(与 MCC 界面"同步服务器时间 / 服务监控 / 双机热备"联动):上述是宿主机 NTP/时间基础。 MCC 界面内的"同步服务器时间""重启/重启系统""双机热备一键启用"等动作,需 tr-mcc 容器以宿主 root执行 systemctl/timedatectl。请在两台宿主部署独立守护
tr-mcc-base.service(跑start-tr-mcc-base.sh, 与 tr-mcc 共享/tmp信号文件),并给 tr-mcc 容器挂载宿主/tmp(改/usr/local/tianrun/mcc/start.sh加-v /tmp:/tmp)。交付件与完整步骤见本文**「八、tr-mcc-base 宿主守护服务安装」; 该守护用TRMcc*命名空间,与既有tr-base.service(start-tr-base.sh)并存互不影响。 双机热备所需的 keepalived/syncthing 前置件见本文「七、双机热备前置软件安装」**。
# apparmor(Ubuntu) systemctl disable apparmor systemctl stop apparmor # selinux(CentOS) setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# ufw(Ubuntu) ufw disable # firewalld(CentOS) systemctl stop firewalld systemctl disable firewalld
# TCP 优化 echo "net.ipv4.tcp_fin_timeout=30" > /etc/sysctl.d/20-default.conf echo "net.ipv4.tcp_keepalive_intvl=10" >> /etc/sysctl.d/20-default.conf echo "net.ipv4.tcp_keepalive_probes=3" >> /etc/sysctl.d/20-default.conf echo "net.ipv4.tcp_keepalive_time=60" >> /etc/sysctl.d/20-default.conf sysctl -p /etc/sysctl.d/20-default.conf # 最大打开文件数 echo "root soft nofile 65535" > /etc/security/limits.d/20-nofile.conf echo "root hard nofile 65535" >> /etc/security/limits.d/20-nofile.conf echo "* soft nofile 65535" >> /etc/security/limits.d/20-nofile.conf echo "* hard nofile 65535" >> /etc/security/limits.d/20-nofile.conf # 最大进程数配置 echo "* - nproc 65535" > /etc/security/limits.d/20-nproc.conf echo "root soft nproc unlimited" >> /etc/security/limits.d/20-nproc.conf echo "root hard nproc unlimited" >> /etc/security/limits.d/20-nproc.conf ulimit -SHn 65535 # 如果需要在程序运行时增加 # prlimit --nofile=65535:65535 --pid 39977
#Ubuntu apt remove unattended-upgrades -y
#已经迁移
cd /tmp curl -fsSL http://117.139.247.192:81/packages/get-docker.sh -o get-docker.sh sh get-docker.sh --mirror Aliyun #安装iptables依赖,必须安装 apt install ipset fail2ban -y
# 镜像加速以及日志大小限制
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"log-driver":"json-file",
"log-opts": {"max-size":"100m", "max-file":"3"},
"userland-proxy": true,
"insecure-registries": ["117.139.247.192:5000"]
}
EOF# 开机自启、重启 systemctl enable docker systemctl restart docker
登录docker仓库
docker login 117.139.247.192:5000
运行初始化镜像(注意版本)
# 下载初始化镜像并运行,第一次部署时需要运行 # 这个镜像主要包含,配置文件和脚本,还有一些默认录音音频文件 docker pull 117.139.247.192:5000/tianrun/init-mcc:v6.0.7 docker run -it --rm -v /usr/local/tianrun:/usr/local/tianrun -v /lib/systemd/system/:/lib/systemd/system/ -v /etc/systemd/system/multi-user.target.wants/:/etc/systemd/system/multi-user.target.wants/ -v /etc/profile.d/:/etc/profile.d/ 117.139.247.192:5000/tianrun/init-mcc:v6.0.7 # 加载环境变量 source /etc/profile.d/tianrun_profile.sh
# 一键下载/更新镜像 sh /usr/local/tianrun/pull.sh # 更新镜像 systemctl daemon-reload # 加载配置 sh /usr/local/tianrun/base/init.sh
# 需要根据实际情况手动修改vim /usr/local/tianrun/env.sh中以下字段
vim /usr/local/tianrun/env.sh
IP_LOCAL # 默认取服务器IP,不需要修改,仅在单独部署fs节点时修改为mcc服务器ip
KAM_IP_LOCAL # 默认是服务器IP,tr-kam 和 tr-nginx 启动会取该值 --add-host=tr-kam:${KAM_IP_LOCAL}
KAM_IP_PUBLIC # 如果需要映射到公网,这里设置成公网IP
# 启动mysql
systemctl start tr-mysql
# 启动mq
systemctl start tr-rabbitmq
# 启动redis
systemctl start tr-redis
# mcc
# 需要根据实际情况手动修改/usr/local/tianrun/mcc/start.sh中修改下面的内容,tr-kam是host模式启动,用docker网桥ip无法直接访问,默认用服务器IP
--add-host=tr-kam:${KAM_IP_LOCAL}
# 启动mcc
systemctl start tr-mcc
# kam
# 需要根据实际情况手动修改vim /usr/local/tianrun/env.sh中以下字段
# 需要根据实际情况手动修改vim /usr/local/tianrun/env.sh中以下字段
# 需要根据实际情况手动修改vim /usr/local/tianrun/env.sh中以下字段
# 1、如果需要对接IMS,需要设置IMS网口IP,
# 2、在MCC单独加一个external-ims 的 profile,修改rtp-ip和sip-ip为ims专线ip地址
KAM_IP_IMS
# 如果需要设置成公网IP
KAM_IP_PUBLIC
# 启动Kamailio (初次安装时需要先等tr-mcc 启动初始化数据库后再启动)
systemctl start tr-kam
# FreeSwitch
# 手动修改配置文件, 默认不需要修改
# 修改mq连接地址
# vim /usr/local/freeswitch/conf/autoload_configs/amqp.conf.xml #hostname(两个) 改成 env.sh中的IP_LOCAL
# 修改配置获取地址
# vim /usr/local/freeswitch/conf/autoload_configs/xml_curl.conf.xml #gateway-url改成 env.sh中的IP_LOCAL
# 修改funarr地址
# vim /usr/local/freeswitch/conf/autoload_configs/funasr.conf.xml #wss改成 env.sh中的IP_LOCAL
# 启动FreeSwitch
systemctl start freeswitch
# nginx
# 需要根据实际情况手动修改vim /usr/local/tianrun/nginx/start.sh中修改下面的内容,tr-kam是host模式启动,用docker网桥ip无法直接访问,默认用服务器IP
--add-host=tr-kam:${KAM_IP_LOCAL}
# 启动nginx
systemctl start tr-nginx
# 防火墙 按需执行
#vim /usr/local/tianrun/iptables/config-mcc.sh # 防火墙主要采用白名单策略,根据业务自行加白,
systemctl start tr-iptables
# 将初始化数据及相关参数(mcc本机fsnode节点,kam参数,默认cdr_url,默认oss服务器地址)改成IP_LOCAL地址
sh /usr/local/tianrun/base/init-mcc.sh #取env的IP_LOCAL地址,修改初始化fs节点和system_setting相关配置;初始安装时,需要等待flyway初始化完成后再执行,如果服务器修改ip也可以通过该脚本进行更新,但是如果有多节点需要另外手动操作修改节点,本脚本只会更新本机初始节点ip
#呼叫中心和mcc都支持将文件上传到oss服务器
systemctl start tr-minio
#mcc宿主脚本执行服务器
systemctl start tr-mcc-base
# 呼叫中心版本才执行!!! 呼叫中心版本才执行!!!呼叫中心版本才执行!!!
systemctl start cc-platform
systemctl start cc-ui
systemctl start tr-text2vec环境变量配置文件 /usr/local/tianrun/env.sh 中统一定义了各组件版本及端口,修改后重启对应服务即可生效。
| 发布日期 | 安装版本 | MCC | Kamailio | Nginx | FreeSWITCH | Redis | MySQL | RabbitMQ | CC-UI | CC-Platform | MinIO | Text2Vec | dmidecode | 备注 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-05 | v6.0.5 | v6.0.5 | v6.0.5 | v6.0.5 | vx1.0.3 | 7.4.0-v8 | 8.0.45 | 3.12.12 | v6.0.1 | v6.0.1 | 2025-09-07 | cn_base_py398_v129 | v0.0.1 | |
| 2026-09 | v6.0.7 | v6.0.7 | v6.0.5 | v6.0.7 | vx1.0.5 | 7.4.0-v8 | 8.0.45 | 3.12.12-management | v6.0.7 | v6.0.7 | RELEASE.2025-09-07T16-13-09Z | cn_base_py398_v129 | v0.0.1 |
发布新版本时在表末追加一行即可;未变更的组件填
-或留空。
| 发布日期 | 安装版本 | Kam-SIP | Kam-TLS | Kam-HTTP | Nginx | Nginx-SSL | MCC | Redis | MySQL | MQ-HTTP | MQ | CC-UI | CC-Platform | MinIO | Text2Vec | RTP起 | RTP止 | 备注 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-05 | v6.0.5 | 7005 | 7006 | 7007 | 7008 | 7009 | 7070 | 2222 | 3333 | 5555 | 6666 | 7010 | 8080 | 9070 | 8001 | 17000 | 20000 | |
| 2026-09 | v6.0.7 |
发布新版本时在表末追加一行即可;端口未变的填
-或留空。
一、 编辑env文件 vim /usr/local/tianrun/env.sh 配置 KAM_IP_IMS 为ims专线ip地址 二、 单独加一个 external-ims 的 profile,修改rtp-ip和sip-ip为ims专线ip地址 启用 enable-100rel 参数 三、 ims的线路需要出局配置选择这个profile 填写示例 线路号:+862862003626 鉴权用户名:+862862003626 对接地址:sc.ims.chinaunicom.cn 密码:xxx 注册代理地址:10.20.2.1:5060
本章仅在部署双机热备 时需要;单机部署可跳过。双机热备的部署与实施步骤见《MCC - 双机热备部署与实施手册.md》。
双机热备需要两类产品包外 的宿主软件:keepalived (虚拟 IP/VIP 主备切换)与 syncthing (本地 /soft/audio 的音频双向同步)。仓库/向导脚本不包含、也不再自动安装这两个外部件 ——一键向导只做"已安装校验":缺件即中止并提示本章。请在两台服务器上都先把它们部署好(以及按 §7.4 放行两盒互通网络),再在 MCC 界面运行双机热备向导。
对应校验的向导步骤:
MASTER_INIT(主机)/BACKUP_DEPLOY(备机)要求两盒都已装 keepalived;AUDIO_SYNC(双端)要求两盒都已部署 ** syncthing**。其余步骤(MySQL 主主复制/拉数据/起服务)依赖的产品组件(tr-mysql 容器、docker、mysql 客户端)属本文前几章"每盒自洽部署"范畴,不在本章。
| 组件 | 用途 | 安装对象 | 向导哪个步骤校验 | 缺件时的脚本报错关键词 |
|---|---|---|---|---|
| keepalived | VIP 漂移 / 主备探测切换 | 两盒都要 | MASTER_INIT(主机)/ BACKUP_DEPLOY(备机)/ FINALIZE(主机) | 未找到 keepalived |
| syncthing | /soft/audio 音频双向同步(仅本地目录场景) | 两盒都要 | AUDIO_SYNC(双端) | 未找到 syncthing |
若
/soft/audio由独立共享存储(NFS) 承载,向导AUDIO_SYNC会自动探测并跳过 syncthing(返回ST_NFS_SHARED),此时不必 安装 syncthing。keepalived 无论何种存储方案都需要。
版本建议:keepalived ≥ 2.2;syncthing ≥ 1.23 (需具备现代子命令 CLI——顶层 generate/serve 及 --home/--config/--data;v1.23 之前或发行版衍生旧包如 Debian 的 v1.18.0-ds1 不认 generate 子命令,向导直接拒并指回本节),强烈建议两盒统一装 §7.3.1 官方静态包 v1.27.x。
keepalived 提供 VRRP 协议实现,承载 MCC 对外虚拟 IP(VIP)。安装即可,无需手工写配置:一键向导的 MASTER_INIT/BACKUP_DEPLOY 会自动生成 /etc/keepalived/keepalived.conf(主机 MASTER / 备机 BACKUP)并注册开机自启(暂不启动,由 FINALIZE 统一拉起夺 VIP)。
Debian / Ubuntu(apt)
apt-get update apt-get install -y keepalived
RHEL / CentOS / Rocky(yum / dnf)
yum install -y keepalived # 或 dnf install -y keepalived
若发行版仓库无包,见下方源码构建。校验:
keepalived --version # 打印 Keepalived v2.x.x systemctl cat keepalived >/dev/null 2>&1 && echo "unit OK" # systemd 单元存在 ls -ld /etc/keepalived # 配置目录存在(向导会向其中写 keepalived.conf)
请勿 在向导运行前
systemctl start keepalived——主机MASTER_INIT/BACKUP_DEPLOY阶段刻意"只 enable 不 start",由FINALIZE(主机侧)统一拉起,避免备机先抢 VIP 抖动。手动演练另见《MCC - 双机热备部署与实施手册》§十。
发行版无包时的源码构建(备选)
# 依赖: 编译工具 + openssl 开发头(libssl-dev / openssl-devel) apt-get install -y build-essential libssl-dev # Debian/Ubuntu yum groupinstall -y 'Development Tools'; yum install -y openssl-devel # RHEL 系 cd /usr/local/src curl -fSL https://keepalived.org/software/keepalived-2.2.8.tar.gz -o ka.tar.gz tar -xzf ka.tar.gz && cd keepalived-2.2.8 ./configure --prefix=/usr/local/keepalived && make -j"$(nproc)" && make install # 补 systemd 单元(示例, 按实际安装路径调整): cat > /etc/systemd/system/keepalived.service <<'EOF' [Unit] Description=Keepalive Daemon (LVS and VRRP) After=network-online.target Wants=network-online.target [Service] Type=forking PIDFile=/run/keepalived.pid ExecStart=/usr/local/keepalived/sbin/keepalived -P -f /etc/keepalived/keepalived.conf ExecReload=/bin/kill -HUP $MAINPID ExecStop=/usr/local/keepalived/sbin/keepalived --stop Restart=always [Install] WantedBy=multi-user.target EOF systemctl daemon-reload mkdir -p /etc/keepalived ln -sf /usr/local/keepalived/sbin/keepalived /usr/local/bin/keepalived
源码构建后同样满足上述校验(需能 command -v keepalived、有可管理的 systemd 单元、/etc/keepalived 存在)。
syncthing 负责把两台机器各自的 /soft/audio 实时双向互传(录音 / IVR 媒体)。向导 AUDIO_SYNC 不再下载/安装二进制,只校验其就位后生成运行配置并托管为宿主服务 syncthing-audio.service。
向导校验优先认 /usr/local/bin/syncthing (§7.3.1 官方静态包推荐路径),找不到则退而认 PATH 中的 syncthing (发行版包常装到 /usr/bin/syncthing)。两盒务必装同版本、且都 ≥ 1.23 (校验不通过会报版本过旧并指回本节)——发行版旧包(如 Debian v1.18.0-ds1)缺 generate 子命令,不能 用,改装官方静态包即可。
7.3.1 官方静态包(推荐,落地 /usr/local/bin/syncthing)
到 syncthing 官方 Release 取 linux x86_64(或 arm64) tar 包,解出可执行文件放 /usr/local/bin/syncthing:
VER=v1.27.12
# x86_64:
curl -fSL "https://github.com/syncthing/syncthing/releases/download/${VER}/syncthing-linux-amd64-${VER}.tar.gz" -o /tmp/st.tar.gz
# arm64(aarch64)请把 amd64 换成 arm64
tar -xzf /tmp/st.tar.gz -C /tmp
install -m 0755 /tmp/syncthing-linux-amd64-${VER}/syncthing /usr/local/bin/syncthing
rm -rf /tmp/st.tar.gz /tmp/syncthing-linux-amd64-${VER}7.3.2 发行版仓库包(备选,装到 PATH)
仅当发行版仓库里的 syncthing ≥ 1.23 才建议走本途径(装完用 §7.3.3 校验 --version);装出来若是旧子命令缺失的衍生版(如 Debian 曾给过 v1.18.0-ds1),请改装官方静态包。
Debian/Ubuntu:官方第三方源
# 加源(见 https://apt.syncthing.net), 然后: apt-get install -y syncthing # 二进制落 /usr/bin/syncthing(PATH 命中, 向导可识别)
RHEL 系(EPEL):yum install -y syncthing(如仓库有)。
无论哪种方式,最终要求
syncthing能被执行且 ≥ 1.23;向导已兼容/usr/local/bin/syncthing与 PATH 两种落点,无需为固定路径额外做符号链接。
7.3.3 校验
syncthing --version # syncthing v1.27.x "..." (go...) test -x /usr/local/bin/syncthing && echo "/usr/local/bin/syncthing OK" # 推荐路径在
提示:syncthing 是静态构建,直接运行时若无 HOME 环境变量会报
$HOME is not defined;向导脚本与它生成的syncthing-audio.service已显式设HOME=/root,无需现场处理。
两盒间需要放行下列协议/端口(自建防火墙如 ufw/firewalld,或云安全组同理)。只放开 keepalived 却漏 syncthing(或反之)会导致"装好仍连不通",故两盒都要做、双向都要通。
| 用途 | 协议 | 方向 | 说明 |
|---|---|---|---|
| keepalived VRRP | IP 协议 112 (VRRP) | 两盒互访 | 向导 keepalived.conf 用 unicast_peer,放行"来自对端 IP 的协议 112";若走组播再加放 224.0.0.18 协议 112 |
| syncthing 同步数据 | TCP 22000 | 两盒互访 | 对端 syncthing 的监听端口 |
| syncthing 本地发现 | UDP 21027 | 两盒互访 | 建议放行(LAN 发现),不放也能经 device 直连 |
| MCC 应用 HTTP | TCP 7070 | 两盒互访 | 主机 FINALIZE 经 HTTP 拉起备机 keepalived / 备机对端动作都走 7070 |
| MySQL 复制/拉全量 | TCP 3333 | 备机 → 主机 | 备机 mysqldump 拉主 + 双向 GTID 复制实时连主库 |
放行示例(ufw,两盒都执行,换成对方 IP):
ufw allow proto vrrp from <对端IP> # keepalived 协议 112(unicast 或组播 224.0.0.18) ufw allow 22000/tcp # syncthing(如装) ufw allow 21027/udp # syncthing 发现(如装, 建议) ufw allow 7070/tcp # MCC 双机互通 ufw allow 3333/tcp from <对端IP> # MySQL 复制(仅放开给对端更稳)
firewalld 示例(两盒各一条进向规则 + 出向默认允许即可),或云安全组在"入方向"按上表放行。
双盒间
ping通 ≠ 全通:请以"能否建立 keepalived 主备会话 / syncthing 已连接"为准;排障时在两盒互nc -vz <对端> 22000/nc -vz <对端> 3333复核。
两盒都装完软件、放行完网络后,再回 MCC 界面按向导依次:MASTER_INIT(主机)→ DATA_SYNC(备机)→ AUDIO_SYNC(双端,本地目录场景)→ BACKUP_DEPLOY(备机)→ FINALIZE(主机,拉起 keepalived 夺 VIP)。任一前置缺失时向导会在此类步骤立即中止并回显指引,补齐后** 可安全重跑**该步骤(脚本幂等)。
本章为双机热备、时间同步、服务管理 等"宿主级动作"的前置;单机不使用这些功能时可跳过。完整部署背景见《MCC - 双机热备部署与实施手册.md》。
双机热备、时间同步、服务管理需要以宿主 root 执行 systemctl/timedatectl/写 /etc/探 VIP 等动作。tr-mcc 以容器方式运行时没有这些宿主视图,故在宿主部署本守护:容器把要执行的脚本写进共享 /tmp 信号文件,守护以宿主 root 执行并把结果写回 /tmp。使用 TRMcc* 命名空间、独立服务。
tianrun-mcc/src/main/resources/hostScripts/)| 文件 | 作用 | 宿主部署位置 |
|---|---|---|
start-tr-mcc-base.sh | 守护主脚本(常驻循环) | /usr/local/tianrun/base/hostScripts/start-tr-mcc-base.sh |
tr-mcc-base.service | systemd 单元 | /etc/systemd/system/tr-mcc-base.service |
master-init-ha.sh | 启用 ①MASTER_INIT(主机): GTID 基座/repl 账号/keepalived(MASTER) | /usr/local/tianrun/base/hostScripts/master-init-ha.sh |
data-sync-ha.sh | 启用 ②DATA_SYNC(备机): 覆盖前备份备机三库 → 全量拉主 + 双向主主复制 | /usr/local/tianrun/base/hostScripts/data-sync-ha.sh |
audio-sync-ha.sh | 启用 ③AUDIO_SYNC(双端): Syncthing 音频双向同步 install/peer/link/remove; status 只读探测(监控页/收敛等待共用) | /usr/local/tianrun/base/hostScripts/audio-sync-ha.sh |
backup-deploy-ha.sh | 启用 ④BACKUP_DEPLOY(备机): 备机 keepalived/角色脚本 | /usr/local/tianrun/base/hostScripts/backup-deploy-ha.sh |
finalize-ha.sh | 启用 ⑤FINALIZE(主机): 起 keepalived 夺 VIP + SIP/RTP 切 VIP | /usr/local/tianrun/base/hostScripts/finalize-ha.sh |
unenable-ha.sh | 解除/拆除: 停 keepalived/断主主复制/删 repl/清顶层运行时/回单机基线 | /usr/local/tianrun/base/hostScripts/unenable-ha.sh |
kam-ha.sh | 向导内部委托脚本(非阶段): Kamailio(tr-kam) 切/还原「0.0.0.0 监听 + alias=VIP」+ ** 节点地址切/还原 VIP**(apply/restore):mcc.pbx_dispatcher.destination/mcc_api_url 与 kamailio.dispatcher 一并随 VIP 切换,由 FINALIZE(主)/BACKUP_DEPLOY(备)/UNENABLE 以 bash kam-ha.sh <子命令> 调起 | /usr/local/tianrun/base/hostScripts/kam-ha.sh |
time-ha.sh | 宿主操作·时间/NTP: NTP 同步(chrony/timesyncd 自动识别)、停 NTP、手动设时、设时区、同步 freeswitch 时钟 | /usr/local/tianrun/base/hostScripts/time-ha.sh |
svc-ha.sh | 宿主操作·服务/磁盘: 服务运行状态(时长)与磁盘占用统计 | /usr/local/tianrun/base/hostScripts/svc-ha.sh |
vip-probe-ha.sh | 宿主操作·VIP 占用 L2 探测(启用前校验) | /usr/local/tianrun/base/hostScripts/vip-probe-ha.sh |
PREREQ.md | 前置软件安装手册 (即本文「七、双机热备前置软件安装」):keepalived/syncthing 等产品包外件由客户/现场先行部署 (含两盒网络/防火墙放行);向导脚本只校验已装、不再自动安装 | /usr/local/tianrun/base/hostScripts/PREREQ.md(随附参考, 非可执行) |
keepalived / syncthing 是向导校验的外部前置件 (见本文「七」):
MASTER_INIT/BACKUP_DEPLOY/FINALIZE要求 keepalived 已装,AUDIO_SYNC要求 syncthing 已装;缺件时脚本立即中止并提示按「七」补齐,补齐后可安全重跑(脚本幂等)。脚本不再触发 apt/yum 安装或从外网下载二进制。
6 个向导
*-ha.sh(master-init/data-sync/audio-sync/backup-deploy/finalize/unenable)为双机热备的宿主静态脚本 (模型同 Dispatcher 的 shell-script 目录):启用/拆除的宿主动作不再由 Java 承载/渲染。Java 仅在向导运行时把拓扑+共享密钥写入/usr/local/tianrun/base/hostScripts/ha-topo.env(root 600,与静态脚本同目录),再经下方守护触发对应*-ha.sh,静态脚本自行 source 拓扑并派生口令执行。因此两台宿主都必须安装全部 6 个向导脚本 (与后端 jar 版本配套)。
其中
FINALIZE(主机)/BACKUP_DEPLOY(备机)/UNENABLE还会委托同目录kam-ha.sh apply|restore统一承载 Kamailio(tr-kam) 的 VIP 化改造:宿主侧覆盖 kamailio.cfg 的 listen 行(→0.0.0.0)并给/usr/local/tianrun/kamailio/start.sh注入只读挂载、env.sh的KAM_IP_LOCAL/KAM_IP_PUBLIC置 VIP、库内kam_sip_url/kam_http_url/kamailio.subscriber.domain的 IP 段改 VIP。另将 ** HA 逻辑节点那一行的地址切到 VIP**:mcc.pbx_dispatcher.destination/mcc_api_url由 HA 对两盒的物理 IP 改 VIP(该表** 跨机复制**,两盒同值),** 同表里其他节点的行原样保留**;kamailio.dispatcher的 HA 那一行重建为sip:VIP:65080(该表** 现已纳入复制**,两盒同值),其余节点的调度行同样保留,并dispatcher.reload使运行中的 tr-kam 生效。于是 HA 下双机对外是** 一个逻辑节点(地址=VIP),且可与 独立真实 IP 节点共存**(其他机器在 fsNodes 页按真实 IP 新增的 FS 节点不受 HA 启用/解除影响);VIP 漂移** 不需要重写 dispatcher /reload mod_sofia/ 重启 tr-kam;待命盒同样是热的(两盒共绑 VIP)。故kam-ha.sh是 必装件**(缺失时向导仅告警,但 Kamailio 不会切到 VIP,分机/中继注册在切换后不通)。
另 3 个宿主操作脚本 (time-ha/svc-ha/vip-probe)为轻量只读/短动作,由后端经
HostScripts.invoke发"薄引导"直接exec bash <脚本> <mode> <args>触发(脚本缺失时 exit 127 报错并提示按本文部署),不经拓扑、不经守护排队,亦须随包部署到两台宿主/usr/local/tianrun/base/hostScripts/。其中audio-sync-ha.sh status兼作 Syncthing 音频同步引擎的只读探测:HA 监控页健康帧与 AUDIO_SYNC 首次收敛等待共用同一契约(NA_NO_ENV/ACTIVE=/PING_ERR/CONN=/DB=,见脚本 header)。
宿主日志统一落
/usr/local/tianrun/base/hostScripts/logs/(与全部 -ha.sh、运行时环境文件同目录):每个向导/解除步骤执行前,后端生成的 bootstrap 先在执行所在这台宿主该目录创建<STAGE>-<yyyyMMdd-HHmmss>.log并把整步完整输出写入;守护tr-mcc-base的常驻日志由start-tr-mcc-base.sh自行mkdir本目录并把自身输出exec >>重定向到同目录tr-mcc-base.log(不再依赖 systemdStandardOutput=append,新装/清空 logs 后重启无需手工建目录),音频引擎syncthing-audio.log亦落同目录。完整输出不回传后端,向导界面只凭退出码报成败,排障到对应宿主看该目录日志。UNENABLE(解除)按文件名删除启用期写入的运行时文件 (ha-topo.env/ha-db.env/syncthing.env/check_mcc.sh/promote.sh/fence.sh,与静态 -ha.sh 同目录)并在**最末一步整目录清空logs/(仅整链拆除成功才执行;中途失败时本次运行的 UNENABLE-.log 保留供排障);静态脚本与 PREREQ.md 不在删除清单内,供再启用。
# 0) 统一目录(先建; 静态脚本/运行时环境文件/PREREQ.md/logs 全在此目录, 命名空间独立) mkdir -p /usr/local/tianrun/base/hostScripts # 1) 放脚本(守护 + 10 个 *-ha.sh: 6 向导 + kam-ha 向导内部委托 + time/svc/vip-probe 宿主操作; # 本目录常驻, 拆除只删运行时文件不会删它们) cp start-tr-mcc-base.sh master-init-ha.sh data-sync-ha.sh backup-deploy-ha.sh audio-sync-ha.sh finalize-ha.sh unenable-ha.sh kam-ha.sh time-ha.sh svc-ha.sh vip-probe-ha.sh PREREQ.md /usr/local/tianrun/base/hostScripts/ chown root:root /usr/local/tianrun/base/hostScripts/start-tr-mcc-base.sh /usr/local/tianrun/base/hostScripts/*-ha.sh chmod +x /usr/local/tianrun/base/hostScripts/start-tr-mcc-base.sh /usr/local/tianrun/base/hostScripts/*-ha.sh # 1b) PREREQ.md 一并置于本目录(随附参考, 非可执行; keepalived/syncthing 由客户/现场按此先行部署, 向导只校验不自动装) # 2) 装单元并启用(守护常驻日志落 /usr/local/tianrun/base/hostScripts/logs/tr-mcc-base.log) cp tr-mcc-base.service /etc/systemd/system/ systemctl daemon-reload systemctl enable --now tr-mcc-base systemctl status tr-mcc-base # active(running)
守护与容器通过 /tmp 下的 TRMcc*.txt 信号文件通信,两者必须看到同一个 /tmp。因此 tr-mcc 容器需新增/确认卷挂载(替换为你的实际 run/compose 参数):
docker run ... -v /tmp:/tmp ... <tr-mcc镜像> # 或 compose volumes: # volumes: # - /tmp:/tmp
改完挂载后重启 tr-mcc 容器。若容器此前把 /tmp 当作私有目录(匿名卷),挂载宿主 /tmp 会覆盖它——tr-mcc 对 /tmp 只做临时文件读写(Java 临时文件、信号文件),共享宿主 /tmp 安全。
容器内(或任意能写宿主 /tmp 的 root 身份)执行:
# 守护响应探测(应很快出现结果文件且内容一致) rm -f /tmp/TRMccPingResult.txt echo "hello-$(date +%s%N)" > /tmp/TRMccPing.txt sleep 1 cat /tmp/TRMccPingResult.txt # 端到端: 让守护以宿主 root 执行一条命令 printf 'TRMCC_TIMEOUT_MS=5000necho host=$(hostname); systemctl is-system-running || truen' > /tmp/TRMccExec.txt sleep 1 cat /tmp/TRMccExecResult.txt /tmp/TRMccExecResult.out /tmp/TRMccExecResult.err
输出应显示宿主机名与 EXIT=0。之后在 MCC 界面做一次"同步服务器时间"或打开"服务监控/双机热备"即可看到本机动作变为 real(宿主通道)而非失败。
守护为 exec 主循环 + 后台 query worker 双 worker:exec 串行处理 Ping/Exec/Detach;query worker 独立轮询 TRMccQuery,二者并行。只读探测(服务状态/磁盘/网卡/HA 监控帧)走 query,写/长动作(向导脚本、NTP、服务重启/reboot、音频同步)仍走 exec。升级请 ** jar 与守护成套**重布;若只升 jar 不升守护,后端 HostExec 能力探测会自动把只读回退到 exec 串行通道(功能不挂,仅并发能力降级),守护补齐后重启 tr-mcc 即切回快通道。
守护未运行:systemctl status tr-mcc-base;常驻日志由守护脚本自建目录并 exec >> 重定向到 /usr/local/tianrun/base/hostScripts/logs/tr-mcc-base.log,亦可用 journalctl -u tr-mcc-base -n 50 看 systemd 侧近况。
容器未挂 /tmp:探测/执行文件写了但守护无响应 → 按 §8.3 补 -v /tmp:/tmp 并重启容器。
信号被拒(owner check failed):守护只执行 root 所有 的信号文件。确认 tr-mcc 容器以 root 运行(写出的 /tmp 文件属主为 root)。若以非 root 用户跑容器,需改为 root 或另行评估。
想在本机裸跑(不开容器)联调:让 tr-mcc 以宿主身份直接运行并配置 mcc.ha.host-exec-mode=direct,则不依赖本守护(直连 bash)。
| 方向 | 文件 | 说明 |
|---|---|---|
| 探测 | /tmp/TRMccPing.txt → /tmp/TRMccPingResult.txt | 内容=随机 token, 守护原样回写 token |
| 执行 | /tmp/TRMccExec.txt → /tmp/TRMccExecResult.txt | 首行 TRMCC_TIMEOUT_MS=<毫秒>, 其余为脚本; 结果首行 EXIT=<code>(最后写, 即完成标记) |
| 执行输出 | /tmp/TRMccExecResult.out / .err | stdout/stderr 分流, 各截断 300KB |
| 后台 | /tmp/TRMccDetach.txt → /tmp/TRMccDetachResult.txt | 内容=命令; 守护 setsid 异步执行, 回 EXIT=0 表示已接收 |
| 查询(只读/快通道) | /tmp/TRMccQuery.txt → /tmp/TRMccQueryResult.txt | 首行 TRMCC_TIMEOUT_MS=<毫秒>, 其余为脚本体; 结果首行 EXIT=<code>(最后写)。守护 query worker 消费, 与 exec 通道** 并行** |
| 查询输出 | /tmp/TRMccQueryResult.out / .err | stdout/stderr 分流, 各截断 300KB |
安全:守护仅执行由 root 写下的信号(容器内 tr-mcc 以 root 运行 → uid 0),拒绝符号链接及普通用户伪造,避免共享 /tmp 的本地提权;信号先 mv 到 /tmp/.mcc-ha(root 700)再校验执行。