部署
从一个开发用的 standalone 实例到一个生产集群,需要做四个决定:密钥放在哪、跑几个控制平面节点、日志去哪、怎么升级。本页一一过。
生产加固
有两个配置字段带不能跨重启幸存的开发友好回退。上线前显式设定它们。
KEK —— 静态加密密钥
crypto:
kek_file: "/etc/tiyi/kek.bin" # 32 字节静态密钥
所有信封加密的 blob(TLS 私钥、ACME 账户密钥、ACME DNS provider 凭据、bundle 签名密钥)用这个 KEK 解密。生成一次并备份到 state 数据库旁边:
$ install -m 0600 /dev/null /etc/tiyi/kek.bin
$ head -c 32 /dev/urandom > /etc/tiyi/kek.bin
丢失 KEK 等于丢失所有加密 blob。把它备份到 state.db 同处。轮换 KEK 需要重包所有加密 blob —— v3.0.0-rc.1 暂不支持。
另:如果不显式配置 crypto.kek_file,Tiyi 在首次启动时会在 <state-db-dir>/kek.bin 自动生成。这对单机开发足够,但在 state 目录可能短暂的生产环境很脆弱。
JWT 签名密钥
auth:
jwt_secret: "<32+ 字节随机>" # 或通过 TIYI_AUTH_JWT_SECRET 环境变量
Access token 的 HS256 签名密钥。字段为空时,Tiyi 在每次重启时生成 32 字节临时密钥,并打印 WARNING。会话在重启时失效,副本之间不能共享 refresh token —— 在生产中通常都是问题。
Bundle 签名密钥
服务端的 ed25519 配置签名密钥落在 bundle_signing_key 单例行,使用 KEK 信封加密。节点首次接入时固定公钥(TOFU),之后拒绝重新固定。轮换需要重新入网 —— 用 tiyi agents issue-token 签新 token,把节点重新拉起。
HA 故障转移
Tiyi 集群可以只有一个主节点 + N 个节点(零热备也允许)。规模较大的部署建议跑一个热备,主节点宕机时不至于长时间不能写。
拓扑
# 全部四个节点都代理流量。L4/L7 LB 在每个节点上轮询 /healthz。
$ TOKEN_B="$(tiyi agents issue-token --tag secondary | jq -r .token)"
$ TOKEN_C="$(tiyi agents issue-token --tag edge-c | jq -r .token)"
Node A: tiyi server --addr 0.0.0.0:8080
Node B: tiyi secondary --primary-api http://A:8080 --enrollment-token $TOKEN_B
Node C: tiyi agent --api http://A:8080 --enrollment-token $TOKEN_C
提主
Node A 宕机,在 Node B 上跑 tiyi promote。两阶段切换避免脑裂:
- 通过
SystemService.Demote联系老主节点 —— 主节点切换为只读,返回当前 epoch 与最后一次写序号。 - 验证备节点已经追到了主节点最后的序号。如果落后则放弃。
- 在备节点上自增 epoch(
primary_epoch + 1),切换角色为主,接受写入。 - 老主节点的嵌入式节点重新连接到新主节点,变成普通节点。
主节点确认不可达时,tiyi promote --force 跳过 demote。你接受最后一次 bundle 同步到主节点失败之间的写丢失。如果老主节点回来,看到节点报告了更高 epoch 会自动降级为节点。
Epoch 隔离避免脑裂。每一次写入检查本地 epoch;任何节点收到 state 报告中的更高 epoch 会自动降级。Epoch 单调递增,持久化在 cluster_state。
客户端 IP 信任配置
Tiyi 在 CDN 或 L4 LB 后时,到达 WAF 的客户端 IP 不是真实 IP —— 那是前面的代理。信任配置告诉 Tiyi 哪些代理可信、哪个 header 携带真实 IP。
从 UI(设置 → 信任配置标签)或 CLI 设置一次:
$ tiyi trust set \
--trusted-proxies 10.0.0.0/8,172.16.0.0/12 \
--client-ip-headers X-Forwarded-For
# 自动拉取 CDN 段:
$ tiyi trust cdn list
$ tiyi trust cdn refresh cloudflare
$ tiyi trust cdn refresh fastly
# 把任意 (peer, headers) 元组回溯到解析后的客户端 IP:
$ tiyi trust test --peer 10.0.0.5 --header "X-Forwarded-For: 1.2.3.4, 10.0.0.5"
默认开启的 Origin Bypass Attempt 告警在请求通过 XFF 声称客户端 IP 但 peer 不是受信任代理时触发。
SIEM 转发
Tiyi 把安全、访问、错误、(可选)审计事件以 RFC 5424、CEF 或 LEEF 通过尽力的 TCP / UDP / unixgram 转发出去。从 设置 → SIEM 标签 或 CLI 配置一次:
$ tiyi system settings update --key siem.enabled --value true
$ tiyi system settings update --key siem.address --value "tcp://siem.internal:514"
$ tiyi system settings update --key siem.format --value rfc5424
$ tiyi system settings update --key siem.filter.include_audit --value true
SIEM 转发是有意尽力的。接收端健康、可靠投递、回放属于 SIEM 管道,而不是 Tiyi。转发器为每个 dispatcher 缓存一条 net.Conn,出错时重连。
可观测性
- Prometheus 导出器位于本地管理 socket 的
/metrics。从 sidecar 抓取;指标来自驱动 dashboard 的同一条遥测管道。 /healthz返回{epoch, role, proxy_healthy}。L4/L7 LB 健康检查用它。/debug/logsink/stats在本地管理 socket 暴露每种类别的attempted/written/dropped_full/panicked/queue_depth/last_error计数。panicked计数是边界defer recover处理器的跨层金丝雀。- 遥测深度视图 UI 位于
/telemetry/explorer,可在不离开 dashboard 的情况下做按需 Top-K 与采样浏览。
滚动升级
导入二进制 release 后,tiyi release apply 把 APPLY_BINARY 命令散到所有 OS/arch 匹配的节点。每个节点下载替换、校验 SHA-256,然后退出让 supervisor 重启进入新二进制。
$ tiyi release import --tarball ./tiyi-3.0.1.tar.gz
$ tiyi release list
$ tiyi release apply <release-id> # 所有匹配节点
$ tiyi release apply <release-id> --agent-id A # 灰度部署
$ tiyi release runs # 进行中的滚动
$ tiyi release rollback # 回滚到上一个二进制
备份
有三样东西要备份:
state.db—— SQLite 控制平面数据库。WAL 模式;sqlite3 state.db ".backup '/path/to/backup.db'"在 Tiyi 运行时也工作。kek.bin—— 静态加密密钥。丢失即不可恢复。备份到与其他长期密钥相同的保险库。jwt_secret—— 已经在你的配置仓库里,但要确认那个仓库也备份了。
支持(并推荐)Litestream 风格的 WAL 流式异地备份。logs/ 分区文件不属于备份集 —— 它们是有自己保留循环的运营数据。
上线检查表
- 把
crypto.kek_file设为已备份的文件 - 把
auth.jwt_secret设为 32+ 字节随机值 - 用真实账号替换引导管理员密码
- 如果 Tiyi 在 CDN/LB 后,配置信任配置
- 选定一个 SIEM 目的地并验证测试事件能落地
- 把
/healthz接到 L4/L7 LB - 从 Prometheus 抓取
/metrics - 把
state.db+kek.bin加入备份管道 - 至少签发一个备节点,这样单主丢失不致命
- 校验审计链:
tiyi audit verify-chain退出 0