Files
olons_server/docs/工作台与Manager内部配置运维说明.md
T

443 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 工作台与 Manager 内部配置运维说明
更新时间:2026-09-17
## 1. 背景
`im_workbench` 需要从 `im_manager` 读取系统配置,例如:
- `im.uid_encryption_key`
读取链路如下:
```text
im_workbench
-> GET https://admin.118im.com/internal/im-config/third-party/im?keys=uid_encryption_key,UID_ENCRYPTION_KEY,uid_key
-> im_manager 校验 HMAC 签名
-> 返回系统配置
```
这个接口是服务间内部接口,不是普通前端接口。调用方必须带 HMAC 请求头:
```http
X-Service-Name: im-workbench
X-Timestamp: <unix seconds>
X-Nonce: <random nonce>
X-Signature: <hmac-sha256 hex>
```
签名使用的密钥来自 `im_manager` 测试环境 Secret 中的:
```text
manager-system / im-manager-secrets / IM_CONFIG_API_SECRET
```
注意:不要把真实密钥写进 Git 文档或代码。
## 2. 为什么 .env 不生效
测试环境运行在 Kubernetes Pod 中,服务启动时不会自动读取仓库里的 `.env` 文件。
当前代码和启动方式是:
- `im_workbench` 只读取进程环境变量和 `IM_WORKBENCH_CONFIG` 指向的 JSON 配置文件。
- `im_manager` 的 entrypoint 使用 Pod 环境变量做 `envsubst` 生成 `config.yaml`。
- 两个服务都没有 `godotenv.Load()`、`source .env` 或 docker compose `env_file` 逻辑。
所以测试环境真正生效的是:
```text
Kubernetes Secret / Deployment 环境变量
```
不是仓库中的 `.env`。
## 3. 当前 Kubernetes 配置关系
### im_workbench
命名空间:
```text
workbench-system
```
Deployment:
```text
im-workbench
```
当前 Pod 里只显式注入:
```text
IM_WORKBENCH_CONFIG=/etc/im-workbench/workbench.json
```
`/etc/im-workbench/workbench.json` 来自:
```text
workbench-system / im-workbench-secrets / workbench.json
```
因此 workbench 的运行时配置要改这个 Secret 里的 `workbench.json`,或在 Deployment 里显式加环境变量。
### im_manager
命名空间:
```text
manager-system
```
Deployment:
```text
im-manager
```
Secret:
```text
manager-system / im-manager-secrets
```
其中和内部配置接口相关的 key:
```text
IM_CONFIG_API_SERVICE_NAME
IM_CONFIG_API_SECRET
```
## 4. 必须配置什么
### 4.1 im_manager 需要允许 im_workbench 调配置接口
`im_manager` 的 `IM_CONFIG_API_SERVICE_NAME` 需要支持两个调用方:
```text
im-server,im-workbench
```
原因:
- `im_server` 也需要读取 manager 配置。
- `im_workbench` 也需要读取 manager 配置。
- 如果只配置 `im-workbench`,会影响 `im_server`。
- 如果只配置 `im-server`,`im_workbench` 用正确 service name 调用会 401。
目标配置:
```text
IM_CONFIG_API_SERVICE_NAME=im-server,im-workbench
```
`IM_CONFIG_API_SECRET` 保持现有值,不要改成空,也不要泄露到日志或文档。
### 4.2 im_workbench 需要配置 manager 连接信息
`workbench.json` 中需要有:
```json
{
"manager": {
"base_url": "https://admin.118im.com",
"service_name": "im-workbench",
"secret": "<填 manager-system/im-manager-secrets 中的 IM_CONFIG_API_SECRET>",
"uid_key_group": "im",
"uid_key_keys": [
"uid_encryption_key",
"UID_ENCRYPTION_KEY",
"uid_key"
],
"timeout_ms": 3000
}
}
```
也可以不用改 JSON,改成 Deployment 环境变量:
```text
IM_WORKBENCH_MANAGER_BASE_URL=https://admin.118im.com
IM_WORKBENCH_MANAGER_SERVICE_NAME=im-workbench
IM_WORKBENCH_MANAGER_SECRET=<填 manager-system/im-manager-secrets 中的 IM_CONFIG_API_SECRET>
```
建议优先统一放到 `workbench.json`,因为当前 workbench 已经通过 Secret 挂载 JSON 配置。
## 5. 推荐操作流程
### 步骤 1:更新 manager Secret
将:
```text
manager-system / im-manager-secrets / IM_CONFIG_API_SERVICE_NAME
```
改为:
```text
im-server,im-workbench
```
`IM_CONFIG_API_SECRET` 保持现有值。
### 步骤 2:更新 workbench Secret
从:
```text
manager-system / im-manager-secrets / IM_CONFIG_API_SECRET
```
取值,写入:
```text
workbench-system / im-workbench-secrets / workbench.json
```
目标字段:
```json
{
"manager": {
"base_url": "https://admin.118im.com",
"service_name": "im-workbench",
"secret": "<IM_CONFIG_API_SECRET>"
}
}
```
### 步骤 3:重启服务
更新 Secret 后需要重启 Pod,确保进程重新读取配置。
建议顺序:
```text
1. 重启 im-manager
2. 重启 im-workbench
```
原因:
- 先让 manager 支持 `im-workbench` service name。
- 再让 workbench 使用 `im-workbench` service name 去调用 manager。
## 6. 验证方法
### 6.1 验证 manager 是否接受 im-workbench
用 `IM_CONFIG_API_SECRET` 对请求签名,请求:
```text
GET https://admin.118im.com/internal/im-config/third-party/im?keys=uid_encryption_key,UID_ENCRYPTION_KEY,uid_key
X-Service-Name: im-workbench
```
期望结果:
```json
{
"code": 0,
"data": {
"values": {
"uid_encryption_key": "..."
}
}
}
```
如果返回 401,重点检查:
- `IM_CONFIG_API_SERVICE_NAME` 是否包含 `im-workbench`
- 请求里的 `X-Service-Name` 是否是 `im-workbench`
- `IM_CONFIG_API_SECRET` 是否和 manager 当前 Secret 一致
- 签名文本是否为:
```text
METHOD
RequestURI
BodySHA256
Timestamp
Nonce
```
### 6.2 验证 workbench 是否加载到 manager 配置
进入 workbench Pod 看环境和配置摘要,注意不要打印真实 secret:
```bash
kubectl -n workbench-system exec <im-workbench-pod> -- sh -c 'env | grep IM_WORKBENCH_MANAGER'
```
或查看挂载配置:
```bash
kubectl -n workbench-system exec <im-workbench-pod> -- sh -c 'cat /etc/im-workbench/workbench.json'
```
检查:
```text
manager.base_url = https://admin.118im.com
manager.service_name = im-workbench
manager.secret 非空
```
### 6.3 验证业务接口
从 IM 登录获取 token 后,请求 workbench 接口:
```http
GET https://api.118im.com/v1/workbench
Authorization: Bearer <IM token>
X-MeetingIM-APIKey: <api key>
X-IM-Schema: 1
X-Tenant-Code: <tenant code>
```
期望:
```json
{
"code": 0
}
```
再创建会议,确认 user id 编解码和展示名正常:
```http
POST https://api.118im.com/v1/workbench/meetings
Idempotency-Key: <unique id>
Authorization: Bearer <IM token>
X-MeetingIM-APIKey: <api key>
X-IM-Schema: 1
X-Tenant-Code: <tenant code>
Content-Type: application/json
```
请求体示例:
```json
{
"title": "运维验证会议",
"start_at": "2026-09-18T08:00:00Z",
"end_at": "2026-09-18T09:00:00Z",
"location": "",
"recorder_user_id": "usr...",
"attendee_user_ids": ["usr..."],
"reminder_minutes": []
}
```
期望:
```json
{
"code": 0,
"data": {
"state": "scheduled",
"organizer": {
"user_id": "usr...",
"display_name": "..."
},
"participant_names": ["..."]
}
}
```
## 7. 常见问题
### 7.1 为什么不能从 manager 读取 manager secret
因为 `IM_CONFIG_API_SECRET` 是调用 manager 配置接口的 HMAC 引导凭证。
如果要读取 manager 配置接口,必须先有这个 secret 才能签名。
所以它不能从同一个 manager 配置接口中获取,只能来自部署环境,例如 Kubernetes Secret。
### 7.2 为什么 service name 不是 im-server
`X-Service-Name` 表示调用方服务名。
- `im_server` 调 manager 时,应使用 `im-server`
- `im_workbench` 调 manager 时,应使用 `im-workbench`
manager 侧应该允许多个合法调用方:
```text
im-server,im-workbench
```
### 7.3 为什么配置了 .env 还是没用
因为 Kubernetes 不会自动读取仓库 `.env`。
`.env` 只有在以下情况才会生效:
- 程序代码主动 `godotenv.Load()`
- 启动脚本 `source .env`
- docker compose 配了 `env_file`
- CI/CD 将 `.env` 内容写进 Deployment 或 Secret
当前测试环境都不是这些方式。
### 7.4 只改 workbench 会怎样
如果只把 workbench 改成:
```text
X-Service-Name: im-workbench
```
但 manager 仍然只允许:
```text
IM_CONFIG_API_SERVICE_NAME=im-server
```
那么 workbench 调 manager 会返回 401。
所以需要 manager 和 workbench 一起配置。
## 8. 最终配置清单
manager:
```text
Namespace: manager-system
Secret: im-manager-secrets
IM_CONFIG_API_SERVICE_NAME=im-server,im-workbench
IM_CONFIG_API_SECRET=<保持现有值>
```
workbench:
```text
Namespace: workbench-system
Secret: im-workbench-secrets
Key: workbench.json
```
`workbench.json`:
```json
{
"manager": {
"base_url": "https://admin.118im.com",
"service_name": "im-workbench",
"secret": "<manager 的 IM_CONFIG_API_SECRET>",
"uid_key_group": "im",
"uid_key_keys": [
"uid_encryption_key",
"UID_ENCRYPTION_KEY",
"uid_key"
],
"timeout_ms": 3000
}
}
```