eventRT/deploy/deploy.md

431 lines
13 KiB
Markdown
Raw Normal View History

# 项目部署指南
本项目依赖 `MongoDB`(事件持久化存储)与 `RabbitMQ`mTLS 消息队列),并通过 `OpenTelemetry + Jaeger` 完成链路追踪。
## 前提条件
1. 已安装 `Docker``kubectl`
2. `Minikube` 集群已启动并可访问
3. 确保以下端口在宿主机上未被占用:`27017`MongoDB、`5671`RabbitMQ AMQP
---
### 1\. 部署 MongoDB 数据库Docker
使用官方 `mongo:7.0` 镜像,在 Ubuntu 宿主机(`192.168.1.101`)上以 Docker 容器运行。
#### 1.1 部署命令
```bash
docker run --name mongodb \
-e MONGO_INITDB_ROOT_USERNAME=coslight \
-e MONGO_INITDB_ROOT_PASSWORD=coslight@tj \
-p 27017:27017 \
-d mongo:7.0
```
#### 1.2 连接信息
| 参数 | 值 | 说明 |
| :--- | :--- | :--- |
| **容器名称** | `mongodb` | 容器名 |
| **镜像版本** | `mongo:7.0` | MongoDB 7.0 |
| **主机端口** | `27017` | 外部应用连接端口 |
| **用户名** | `coslight` | Root 管理员 |
| **密码** | `coslight@tj` | 启动时通过 `MONGO_INITDB_ROOT_USERNAME` 设置 |
| **鉴权数据库** | `admin` | `auth_db` |
| **业务数据库** | `eventdb` | EventRT 事件存储库 |
#### 1.3 状态检查
```bash
# 检查容器启动状态
docker ps -a | grep mongodb
# 检查启动日志
docker logs mongodb
```
#### 1.4 初始化 eventdb 数据库
MongoDB 启动后进入容器,为 `eventdb` 库授权:
```bash
docker exec -it mongodb mongosh \
-u coslight -p coslight@tj --authenticationDatabase admin
```
`mongosh` 中执行:
```javascript
// 切换到 eventdb若不存在则自动创建
use eventdb
// 授予 coslight 用户对 eventdb 的读写权限(根用户已有全库权限,此步可选)
db.createUser({
user: "coslight",
pwd: "coslight@tj",
roles: [{ role: "readWrite", db: "eventdb" }]
})
```
---
### 2\. 部署 RabbitMQKubernetes
RabbitMQ 配置为仅允许 TLS 连接(`listeners.tcp = none`),所有客户端须持有由同一 CA 签发的证书。YAML 文件位于 `deploy/mq/`
#### 2.1 TLS 证书生成
##### 2.1.1 生成根 CA
```bash
git clone https://github.com/rabbitmq/tls-gen.git
cd tls-gen/basic
# 生成根 CA结果输出至 result/
make CN=rabbitmq-server
# ca_certificate.pem 与 ca_key.pem即 cakey.pem生成于 result/
```
##### 2.1.2 生成服务端证书
服务端证书需包含 SAN使其同时匹配集群内 DNS 和 Minikube IP。使用 `deploy/mq/server.conf`(已预置正确配置):
```bash
# 将 ca_certificate.pem 和 cakey.pem 放在当前目录
openssl genrsa -out server_key.pem 2048
openssl req -new -key server_key.pem \
-out server_cert.csr -config deploy/mq/server.conf
openssl x509 -req -in server_cert.csr \
-CA ca_certificate.pem -CAkey cakey.pem -CAcreateserial \
-out server_certificate.pem -days 730 -sha256 \
-extfile deploy/mq/server.conf -extensions v3_server
rm server_cert.csr
```
##### 2.1.3 生成 EventRT 客户端证书
CN 必须与 RabbitMQ 中注册的用户名一致(`eventrt-client`)。使用 `deploy/mq/eventrt.conf`
```bash
openssl genrsa -out eventrt_client_key.pem 2048
openssl req -new -key eventrt_client_key.pem \
-out eventrt_client.csr -config deploy/mq/eventrt.conf
openssl x509 -req -in eventrt_client.csr \
-CA ca_certificate.pem -CAkey cakey.pem -CAcreateserial \
-out eventrt_client_cert.pem -days 365 \
-extensions v3_client -extfile deploy/mq/eventrt.conf
rm eventrt_client.csr
```
##### 2.1.4 生成 ModelRT 客户端证书
使用 `deploy/mq/modelrt.conf`CN 为 `modelrt-client`
```bash
openssl genrsa -out modelrt_client_key.pem 2048
openssl req -new -key modelrt_client_key.pem \
-out modelrt_client.csr -config deploy/mq/modelrt.conf
openssl x509 -req -in modelrt_client.csr \
-CA ca_certificate.pem -CAkey cakey.pem -CAcreateserial \
-out modelrt_client_cert.pem -days 365 \
-extensions v3_client -extfile deploy/mq/modelrt.conf
rm modelrt_client.csr
```
##### 2.1.5 验证证书
```bash
# 验证服务端证书
openssl verify -CAfile ca_certificate.pem server_certificate.pem
# 验证客户端证书
openssl verify -CAfile ca_certificate.pem eventrt_client_cert.pem
openssl verify -CAfile ca_certificate.pem modelrt_client_cert.pem
# 确认 CN 和扩展clientAuth / serverAuth
openssl x509 -in server_certificate.pem -noout -subject -ext subjectAltName
openssl x509 -in eventrt_client_cert.pem -noout -subject -text | grep -A1 "Extended Key Usage"
openssl x509 -in modelrt_client_cert.pem -noout -subject
```
#### 2.2 部署 RabbitMQ
##### 2.2.1 创建证书 Secret
在证书文件所在目录执行:
```bash
sh deploy/mq/secert.sh
```
该脚本等价于:
```bash
kubectl create secret generic rabbitmq-certs \
--from-file=ca_certificate.pem=./certs/ca_certificate.pem \
--from-file=server_certificate.pem=./certs/server_certificate.pem \
--from-file=server_key.pem=./certs/server_key.pem
```
##### 2.2.2 部署
```bash
kubectl apply -f deploy/mq/rabbitmq-secret.yaml
kubectl apply -f deploy/mq/rabbitmq-users-config.yaml
kubectl apply -f deploy/mq/rabbitmq-config.yaml
kubectl apply -f deploy/mq/rabbitmq-deployment.yaml
kubectl apply -f deploy/mq/rabbitmq-service.yaml
```
##### 2.2.3 端口汇总
| 端口 | NodePort | 说明 |
| :--- | :--- | :--- |
| `5671` | `30671` | AMQP over TLS客户端连接 |
| `5672` | `30672` | AMQP 明文(内部备用,生产禁用) |
| `15671` | `31671` | Management UI over TLS |
| `15672` | `31672` | Management UI 明文(内部备用) |
##### 2.2.4 用户与权限说明
用户定义在 `rabbitmq-users-config.yaml``definitions.json` 中,启动时通过 `load_definitions` 自动加载:
| 用户 | 认证方式 | 权限 | 说明 |
| :--- | :--- | :--- | :--- |
| `coslight` | 密码 | administrator | 管理员,密码在 `rabbitmq-secret.yaml` |
| `eventrt-client` | X.509 证书CN | configure/read/write | EventRT 服务专用 |
| `modelrt-client` | X.509 证书CN | configure/read/write | ModelRT 服务专用 |
| `web-client` | X.509 证书CN | read/write | Web 客户端 |
> **注意:** 证书认证用户的 `password_hash` 留空RabbitMQ 通过 `ssl_cert_login_from = common_name` 将证书 CN 映射为用户名。
---
### 3\. 部署 EventRTKubernetes
所有资源部署在 `default` 命名空间YAML 文件位于 `deploy/k8s/`
#### 3.1 构建并推送镜像
```bash
# 在项目根目录执行
docker build -f deploy/dockerfile/eventrt.Dockerfile -t coslight/eventrt:latest .
# 加载至 Minikube无需私有仓库时
minikube image load coslight/eventrt:latest
```
#### 3.2 创建客户端证书 Secret
在 RabbitMQ TLS 证书生成完成后(见 2.1),进入证书文件所在目录执行:
```bash
kubectl create secret generic eventrt-certs \
--from-file=ca_certificate.pem=./ca_certificate.pem \
--from-file=eventrt_client_cert.pem=./eventrt_client_cert.pem \
--from-file=eventrt_client_key.pem=./eventrt_client_key.pem
```
#### 3.3 部署
```bash
kubectl apply -f deploy/k8s/eventrt-secret.yaml
kubectl apply -f deploy/k8s/eventrt-configmap.yaml
kubectl apply -f deploy/k8s/eventrt-deployment.yaml
kubectl apply -f deploy/k8s/eventrt-service.yaml
```
#### 3.4 配置说明
| 配置项 | 方式 | 说明 |
| :--- | :--- | :--- |
| `mongodb.password` | Secret `eventrt-secret` | 不写入 ConfigMap通过环境变量 `MONGODB_PASSWORD` 注入 |
| `service.secret_key` | Secret `eventrt-secret` | 不写入 ConfigMap通过环境变量 `SERVICE_SECRET_KEY` 注入 |
| RabbitMQ 客户端证书 | Secret `eventrt-certs` | 挂载至 `/app/configs/certs/` |
| `config.yaml` 其余配置 | ConfigMap `eventrt-config` | `rabbitmq.host` 已设为 K8s Service 名 `rabbitmq-service` |
| `K8S_NAMESPACE` / `K8S_NODE_NAME` | Downward API | 注入至日志全局字段 |
#### 3.5 状态检查
```bash
# 查看 Pod 状态
kubectl get pods -l app=eventrt
# 查看启动日志
kubectl logs -l app=eventrt --tail=50
# 查看 Service
kubectl get svc eventrt-service
```
#### 3.6 端口汇总
| NodePort | 说明 |
| :--- | :--- |
| `30081` | EventRT HTTP API |
#### 3.7 清理
```bash
kubectl delete -f deploy/k8s/eventrt-service.yaml \
-f deploy/k8s/eventrt-deployment.yaml \
-f deploy/k8s/eventrt-configmap.yaml \
-f deploy/k8s/eventrt-secret.yaml
kubectl delete secret eventrt-certs
```
---
### 4\. Mac 本地访问SSH 隧道)
`EventRT` 在 Mac 本地运行时RabbitMQ 部署在 Ubuntu 宿主机(`192.168.1.101`)的 Minikube 中MongoDB 直接运行在宿主机上。需通过 SSH 本地端口转发建立访问隧道。
#### 4.1 网络拓扑
```text
Mac 本地端口 ──SSH隧道──▶ Ubuntu 宿主机 (192.168.1.101) ──▶ Minikube NodePort (192.168.49.2)
└──▶ MongoDB Docker (宿主机 27017)
```
#### 4.2 建立隧道
```bash
ssh -L 27017:127.0.0.1:27017 \
-L 5671:192.168.49.2:30671 \
-L 15671:192.168.49.2:31671 \
-L 4318:192.168.49.2:31318 \
-L 16686:192.168.49.2:31686 \
douxu@192.168.1.101
```
如需后台静默运行(不占用终端):
```bash
ssh -fN \
-L 27017:127.0.0.1:27017 \
-L 5671:192.168.49.2:30671 \
-L 15671:192.168.49.2:31671 \
-L 4318:192.168.49.2:31318 \
-L 16686:192.168.49.2:31686 \
douxu@192.168.1.101
```
#### 4.3 端口映射说明
| Mac 本地端口 | 目标 | 服务 | 说明 |
| :--- | :--- | :--- | :--- |
| `27017` | 宿主机 `127.0.0.1:27017` | MongoDB | EventRT 事件数据库 |
| `5671` | Minikube `192.168.49.2:30671` | RabbitMQ AMQP | 消息队列 mTLS 连接 |
| `15671` | Minikube `192.168.49.2:31671` | RabbitMQ Management | 管理界面 `http://localhost:15671` |
| `4318` | Minikube `192.168.49.2:31318` | OTLP HTTP | OTel Trace 上报Jaeger Collector |
| `16686` | Minikube `192.168.49.2:31686` | Jaeger UI | 链路追踪查询 `http://localhost:16686` |
> **注意:** 隧道建立后,本地 `config.yaml` 中所有服务地址填 `localhost:<本地端口>` 即可直接运行服务。
#### 4.4 关闭隧道
前台运行时直接 `Ctrl+C`;后台运行时查找并终止进程:
```bash
# 找到 ssh 隧道进程
ps aux | grep "ssh -fN"
# 终止(替换为实际 PID
kill <PID>
```
---
### 5\. 本地开发配置config.yaml
`configs/config.example.yaml` 复制为 `configs/config.yaml` 并按以下说明调整:
#### 5.1 配置参数说明
| 类别 | 参数名 | 作用描述 | 示例值 |
| :--- | :--- | :--- | :--- |
| **MongoDB** | `host` | MongoDB 服务器地址 | `"localhost"` |
| | `port` | MongoDB 端口 | `27017` |
| | `user` | 连接用户名 | `"coslight"` |
| | `password` | 连接密码 | `"coslight@tj"` |
| | `database` | 业务数据库名 | `"eventdb"` |
| | `auth_db` | 鉴权数据库 | `"admin"` |
| | `timeout` | 连接超时(秒) | `10` |
| **RabbitMQ** | `host` | RabbitMQ 服务器地址 | `"localhost"` |
| | `port` | AMQP over TLS 端口 | `5671` |
| | `server_name` | TLS SNI / 证书 CN | `"rabbitmq-server"` |
| | `ca_cert_path` | CA 证书路径 | `"./configs/certs/ca_certificate.pem"` |
| | `client_cert_path` | 客户端证书路径 | `"./configs/certs/eventrt_client_cert.pem"` |
| | `client_key_path` | 客户端私钥路径 | `"./configs/certs/eventrt_client_key.pem"` |
| | `insecure_skip_verify` | 是否跳过证书校验(开发临时用) | `false` |
| **Logger (Zap)** | `mode` | 日志模式 `development` / `production` | `"development"` |
| | `level` | 最低日志级别 | `"debug"` |
| | `filepath` | 日志文件路径(空字符串输出到 stdout | `""` |
| | `maxsize` | 单文件最大大小MB | `1` |
| | `maxbackups` | 保留旧文件最大个数 | `5` |
| | `maxage` | 保留旧文件最大天数 | `30` |
| | `compress` | 是否压缩备份文件 | `false` |
| **Service** | `service_addr` | HTTP 监听地址 | `":8081"` |
| | `service_name` | 服务名(日志/监控标识) | `"eventRT"` |
| | `secret_key` | 内部签名密钥 | `"eventrt_key"` |
| | `deploy_env` | 部署环境 `development` / `production` | `"development"` |
| **OTel** | `endpoint` | OTLP HTTP 上报地址(不含协议前缀) | `"localhost:4318"` |
| | `insecure` | 是否不启用 TLS | `true` |
---
### 6\. 排查手册
#### 6.1 证书权限检查
确认客户端证书包含 `TLS Web Client Authentication`
```bash
openssl x509 -in configs/certs/eventrt_client_cert.pem -noout -text \
| grep -A1 "Extended Key Usage"
```
预期输出包含 `TLS Web Client Authentication`
#### 6.2 握手连通性验证
```bash
openssl s_client -connect localhost:5671 \
-cert configs/certs/eventrt_client_cert.pem \
-key configs/certs/eventrt_client_key.pem \
-CAfile configs/certs/ca_certificate.pem
```
预期结果:看到 `Verify return code: 0 (ok)`
#### 6.3 RabbitMQ 日志检查
连接成功后RabbitMQ 日志应出现:
```
connection <xxx>: user 'eventrt-client' authenticated and granted access to vhost '/'
```
查看 Pod 日志:
```bash
kubectl logs -l app=rabbitmq --tail=50 | grep eventrt-client
```
#### 6.4 MongoDB 连通性验证
```bash
mongosh "mongodb://coslight:coslight@tj@localhost:27017/eventdb?authSource=admin"
```
预期进入 `mongosh` 提示符,执行 `show collections` 无报错。