Server和client部署整理

This commit is contained in:
xiuting.xu
2026-07-09 17:14:21 +08:00
parent b5cbc7fbee
commit e2bdcd3820
51 changed files with 532 additions and 344 deletions

View File

@@ -1,278 +0,0 @@
# Deploy Layout
`deploy/` 目录按角色拆分为四套部署与测试入口:
- `server/`: 本仓库 RTR Server(`src/main.rs`)容器化部署
- `client/`: 本仓库 `rtr_debug_client` 容器化部署
- `frr/`: FRR 作为黑盒 RTR Client 的配置与 compose
---
## 0) Build and Run Scripts
`deploy/server/build-run.sh` 只管理 server,`deploy/client/build-run.sh` 只管理 debug client。两个脚本默认 action 都是 `up`,默认 mode 都是 `tcp`。
常用命令:
以下命令默认从仓库根目录执行。
```bash
chmod +x deploy/server/build-run.sh deploy/client/build-run.sh
./deploy/server/build-run.sh up --mode tcp
./deploy/client/build-run.sh up --mode tcp
./deploy/client/build-run.sh up --clients multi
./deploy/client/build-run.sh down
./deploy/server/build-run.sh down
```
常用参数:
| 参数/变量 | server | client | 说明 |
| --- | --- | --- | --- |
| `--mode base\|tcp\|tls\|ssh`, `MODE` | yes | yes | 选择 compose 模式,默认 `tcp`。 |
| `--clients single\|multi`, `CLIENTS` | no | yes | 单 client 或 5 client,默认 `single`。 |
| `--no-build`, `BUILD=0` | yes | yes | 只运行已有镜像,不执行 compose build。 |
| `--server-image TAG`, `SERVER_IMAGE` | yes | no | server 镜像名;会传给 compose 的 `RPKI_RTR_SERVER_IMAGE`。 |
| `--client-image TAG`, `CLIENT_IMAGE` | no | yes | client 镜像名;会传给 compose 的 `RPKI_RTR_CLIENT_IMAGE`。 |
| `--platform VALUE`, `TARGET_PLATFORM` | yes | yes | `buildx` 目标平台,默认 `linux/arm64`。 |
| `--push`, `BUILDX_PUSH=1` | yes | yes | `buildx` 构建后推送到 registry;不设置时加载到本地 Docker。 |
| `--skip-base-pull`, `SKIP_BASE_IMAGE_PULL=1` | yes | yes | 跳过 buildx 前的基础镜像预拉取。 |
支持的 action 包括 `up`、`build`、`buildx`、`rebuild`、`down`/`stop`、`restart`、`logs`、`ps`。完整帮助见:
```bash
./deploy/server/build-run.sh --help
./deploy/client/build-run.sh --help
```
### x86 Build, ARM Deploy
x86 开发机上用 Docker Buildx 分别构建 ARM server/client 镜像。不加 `--push` 时,脚本会把单平台镜像加载到本地 Docker,随后可用 `docker save` 打包传到 ARM 机器。buildx 前会自动按目标平台预拉取 `rust:1.89-bookworm` 和 `debian:bookworm-slim`。
```bash
docker buildx create --use --name rpki-builder
docker buildx inspect --bootstrap
./deploy/server/build-run.sh buildx \
--platform linux/arm64 \
--server-image rpki-rtr:arm64
./deploy/client/build-run.sh buildx \
--platform linux/arm64 \
--client-image rpki-rtr-debug-client:arm64
mkdir -p dist/images
docker save rpki-rtr:arm64 -o dist/images/rpki-rtr-arm64.tar
docker save rpki-rtr-debug-client:arm64 -o dist/images/rpki-rtr-debug-client-arm64.tar
```
把 tar 包传到 ARM 部署机:
```bash
scp dist/images/*.tar user@arm-host:/tmp/
```
ARM 部署机上加载镜像并运行,不再本地构建:
```bash
docker load -i /tmp/rpki-rtr-arm64.tar
docker load -i /tmp/rpki-rtr-debug-client-arm64.tar
SERVER_IMAGE=rpki-rtr:arm64 \
BUILD=0 ./deploy/server/build-run.sh up --mode tcp
CLIENT_IMAGE=rpki-rtr-debug-client:arm64 \
BUILD=0 ./deploy/client/build-run.sh up --mode tcp
```
如果不使用脚本,也可以通过 compose 环境变量指定镜像:
```bash
export RPKI_RTR_SERVER_IMAGE=rpki-rtr:arm64
docker compose --env-file deploy/server/.env \
-f deploy/server/docker-compose.tcp.yml up -d --no-build
```
---
## 1) Server
路径:
- `deploy/server/Dockerfile`
- `deploy/server/docker-compose.yml`
- `deploy/server/DEPLOYMENT.md`
单独 build 镜像:
```bash
docker build -f deploy/server/Dockerfile -t rpki-rtr:latest .
```
启动:
```bash
docker compose -f deploy/server/docker-compose.yml up -d --build
```
停止:
```bash
docker compose -f deploy/server/docker-compose.yml down
```
日志:
```bash
docker compose -f deploy/server/docker-compose.yml logs -f rpki-rtr
```
报告文件:
- `report/rtr-source-*.json`:CCR/SLURM source、fingerprint、refresh 状态、数据质量、cache snapshot/delta 统计。
- `report/rtr-clients-*.json`:client 连接数和连接方式统计,启动时和连接变化时写入。
- `report/rtr-runtime-*.json`:进程 RSS、服务状态、当前生效 runtime configuration,启动时和周期性写入。
Admin config 接口默认关闭。需要运行中动态修改 `max_delta`、delta 裁剪策略、refresh/report interval、timezone 或 RTR timing 时,设置:
```env
RPKI_RTR_ADMIN_ADDR=127.0.0.1:8323
RPKI_RTR_ADMIN_TOKEN=change-me
```
调用示例:
```bash
curl -X POST http://127.0.0.1:8323/admin/rtr/config \
-H "Content-Type: application/json" \
-H "Authorization: Bearer change-me" \
-d '{"max_delta": 6, "prune_delta_by_snapshot_size": true}'
```
完整 API 说明见 `docs/rtr-admin-api.md`,更完整的 server 配置见 `deploy/server/DEPLOYMENT.md`。
---
## 2) Debug Client
路径:
- `deploy/client/Dockerfile`
- `deploy/client/docker-compose.yml`
- `deploy/client/docker-compose.clients.yml`
单独 build 镜像:
```bash
docker build -f deploy/client/Dockerfile -t rpki-rtr-debug-client:latest .
```
单实例启动(交互调试):
```bash
docker compose -f deploy/client/docker-compose.yml up --build
```
单实例停止:
```bash
docker compose -f deploy/client/docker-compose.yml down
```
单实例日志:
```bash
docker compose -f deploy/client/docker-compose.yml logs -f rtr-debug-client
```
多实例启动(5 个并发 client):
```bash
docker compose -f deploy/client/docker-compose.clients.yml up -d
```
多实例停止:
```bash
docker compose -f deploy/client/docker-compose.clients.yml down
```
多实例日志:
```bash
docker compose -f deploy/client/docker-compose.clients.yml logs -f
```
---
## 3) FRR Client
路径:
- `deploy/frr/docker-compose.yml`
- `deploy/frr/daemons.example`
- `deploy/frr/frr.conf.example`
- `deploy/frr/README.md`
- `deploy/frr/README.zh.md`
启动:
```bash
docker compose -f deploy/frr/docker-compose.yml up -d
```
检查连接:
```bash
docker exec -it frr-rpki-client vtysh -c "show rpki cache-connection"
docker exec -it frr-rpki-client vtysh -c "show rpki prefix-table"
```
停止:
```bash
docker compose -f deploy/frr/docker-compose.yml down
```
日志:
```bash
docker compose -f deploy/frr/docker-compose.yml logs -f frr-rpki-client
```
---
## 4) BIRD Client
路径:
- `deploy/bird/Dockerfile`
- `deploy/bird/docker-compose.yml`
- `deploy/bird/docker-compose.tls.yml`
- `deploy/bird/bird.conf.example`
- `deploy/bird/bird.conf.tls.example`
- `deploy/bird/README.md`
- `deploy/bird/README.zh.md`
启动:
```bash
docker compose -f deploy/bird/docker-compose.yml up --build
```
观察活动:
```bash
docker logs -f bird-rpki-client
```
停止:
```bash
docker compose -f deploy/bird/docker-compose.yml down
```
日志:
```bash
docker compose -f deploy/bird/docker-compose.yml logs -f bird-rpki-client
```
TLS/mTLS:
```bash
docker compose -f deploy/bird/docker-compose.yml -f deploy/bird/docker-compose.tls.yml up --build
docker logs -f bird-rpki-client
```

View File

@@ -2,7 +2,7 @@
RPKI_BIRD_VERSION=3.2.1
# TCP mode target endpoint.
RPKI_BIRD_RPKI_HOST=rpki-rtr-tcp
RPKI_BIRD_RPKI_HOST=rpki-rtr
RPKI_BIRD_RPKI_PORT=323
# SSH mode target endpoint.
@@ -30,4 +30,4 @@ RPKI_BIRD_SHOW_ROA6=1
# Host volume mounts.
RPKI_BIRD_LOG_HOST_DIR=../../logs/bird
RPKI_BIRD_SSH_CERTS_HOST_DIR=../../certs
RPKI_BIRD_SSH_CERTS_HOST_DIR=../../certs/ssh

View File

@@ -82,7 +82,7 @@ docker logs -f bird-rpki-client
`OBSERVE_DEBOUNCE_SECS` (default `1`),
`OBSERVE_INTERVAL` (seconds, used when `OBSERVE_MODE=interval`),
and `OBSERVE_PROTO`.
- SSH mode mounts `../../certs` into `/config/ssh` and expects:
- SSH mode mounts `../../certs/ssh` into `/config/ssh` and expects:
`bird-rtr-client.pem` and `ssh_host_rsa_key.pub`.
- Entrypoint auto-generates `/run/bird/known_hosts` from
`/config/ssh/ssh_host_rsa_key.pub` for BIRD SSH host-key verification.

View File

@@ -73,7 +73,7 @@ docker logs -f bird-rpki-client
- 当前 compose 使用 `network_mode: host`,默认通过 `host.docker.internal` 访问 server。
- 观测频率由环境变量控制:`OBSERVE_INTERVAL`(秒,默认 `30`)和 `OBSERVE_PROTO`。
- SSH 模式会将 `../../certs` 挂载到容器 `/config/ssh`,并使用:
- SSH 模式会将 `../../certs/ssh` 挂载到容器 `/config/ssh`,并使用:
`bird-rtr-client.pem`、`ssh_host_rsa_key.pub`。
- 入口脚本会基于 `/config/ssh/ssh_host_rsa_key.pub` 自动生成
`/run/bird/known_hosts`,用于 BIRD 的 SSH 主机密钥校验。

View File

@@ -7,7 +7,7 @@ services:
OBSERVE_PROTO: "rpki_ssh"
volumes:
- ./bird.conf.ssh.template:/config/bird.conf.ssh.template:ro
- ${RPKI_BIRD_SSH_CERTS_HOST_DIR:-../../certs}:/config/ssh:ro
- ${RPKI_BIRD_SSH_CERTS_HOST_DIR:-../../certs/ssh}:/config/ssh:ro
networks:
- rpki_net

View File

@@ -10,7 +10,7 @@ services:
environment:
BIRD_CONFIG_TEMPLATE_PATH: "${RPKI_BIRD_CONFIG_TEMPLATE_PATH:-/config/bird.conf.template}"
RPKI_HOST: "${RPKI_BIRD_RPKI_HOST:-rpki-rtr-tcp}"
RPKI_HOST: "${RPKI_BIRD_RPKI_HOST:-rpki-rtr}"
RPKI_PORT: "${RPKI_BIRD_RPKI_PORT:-323}"
OBSERVE_PROTO: "${RPKI_BIRD_OBSERVE_PROTO:-rpki_tcp}"

View File

@@ -1,8 +1,10 @@
# Target RTR server address for client compose files
# Target RTR server addresses for client compose files
# TCP example: 10.0.0.12:323
# TLS example: rpki.example.com:324
# SSH example: 10.0.0.12:22
RPKI_RTR_SERVER_ADDR=rpki-rtr-tcp:323
RPKI_RTR_TCP_SERVER_ADDR=rpki-rtr:323
RPKI_RTR_TLS_SERVER_ADDR=rpki-rtr:324
RPKI_RTR_SSH_SERVER_ADDR=rpki-rtr:22
# RTR protocol version used as client command second argument (supported: 0,1,2)
RPKI_RTR_PROTOCOL_VERSION=2
@@ -13,14 +15,14 @@ RPKI_RTR_TLS_SERVER_NAME=localhost
RPKI_RTR_TLS_CA_CERT_PATH=/app/certs/client-ca.crt
RPKI_RTR_TLS_CLIENT_CERT_PATH=/app/certs/client-good.crt
RPKI_RTR_TLS_CLIENT_KEY_PATH=/app/certs/client-good.key
RPKI_RTR_TLS_CERTS_HOST_DIR=../../tests/fixtures/tls
RPKI_RTR_TLS_CERTS_HOST_DIR=../../certs/tls
# Shared client logs mount on host.
RPKI_RTR_CLIENT_LOG_HOST_DIR=../../logs/client
# SSH mode examples:
# RPKI_RTR_SERVER_ADDR=10.0.0.12:2222
RPKI_RTR_CLIENT_KEYS_VOLUME=../../certs:/app/certs:ro
# RPKI_RTR_SSH_SERVER_ADDR=10.0.0.12:2222
RPKI_RTR_CLIENT_KEYS_VOLUME=../../certs/ssh:/app/certs:ro
RPKI_RTR_CLIENT_KEY_PATH=/app/certs/rtr-client.key
RPKI_RTR_SSH_SERVER_PUBKEY_PATH=/app/certs/ssh_host_rsa_key.pub
RPKI_RTR_SSH_USERNAME=rpki-rtr

View File

@@ -3,7 +3,7 @@ version: "3.9"
services:
rtr-client-1:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command: ["${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tcp:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
command: ["${RPKI_RTR_TCP_SERVER_ADDR:-rpki-rtr:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
volumes:
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no
@@ -12,7 +12,7 @@ services:
rtr-client-2:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command: ["${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tcp:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
command: ["${RPKI_RTR_TCP_SERVER_ADDR:-rpki-rtr:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
volumes:
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no
@@ -21,7 +21,7 @@ services:
rtr-client-3:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command: ["${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tcp:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
command: ["${RPKI_RTR_TCP_SERVER_ADDR:-rpki-rtr:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
volumes:
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no
@@ -30,7 +30,7 @@ services:
rtr-client-4:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command: ["${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tcp:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
command: ["${RPKI_RTR_TCP_SERVER_ADDR:-rpki-rtr:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
volumes:
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no
@@ -39,7 +39,7 @@ services:
rtr-client-5:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command: ["${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tcp:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
command: ["${RPKI_RTR_TCP_SERVER_ADDR:-rpki-rtr:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
volumes:
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no

View File

@@ -8,7 +8,7 @@ services:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command:
[
"${RPKI_RTR_SERVER_ADDR:-rpki-rtr-ssh:22}",
"${RPKI_RTR_SSH_SERVER_ADDR:-rpki-rtr:22}",
"${RPKI_RTR_PROTOCOL_VERSION:-2}",
"reset",
"--ssh",
@@ -22,7 +22,7 @@ services:
"--summary-only"
]
volumes:
- ${RPKI_RTR_CLIENT_KEYS_VOLUME:-../../certs:/app/certs:ro}
- ${RPKI_RTR_CLIENT_KEYS_VOLUME:-../../certs/ssh:/app/certs:ro}
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no
stdin_open: true

View File

@@ -8,7 +8,7 @@ services:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command:
[
"${RPKI_RTR_SERVER_ADDR:-rpki-rtr-ssh:22}",
"${RPKI_RTR_SSH_SERVER_ADDR:-rpki-rtr:22}",
"${RPKI_RTR_PROTOCOL_VERSION:-2}",
"reset",
"--ssh",
@@ -22,7 +22,7 @@ services:
"--summary-only"
]
volumes:
- ${RPKI_RTR_CLIENT_KEYS_VOLUME:-../../certs:/app/certs:ro}
- ${RPKI_RTR_CLIENT_KEYS_VOLUME:-../../certs/ssh:/app/certs:ro}
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no
stdin_open: true

View File

@@ -4,7 +4,7 @@ services:
context: ../..
dockerfile: deploy/client/Dockerfile
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command: ["${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tcp:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
command: ["${RPKI_RTR_TCP_SERVER_ADDR:-rpki-rtr:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
volumes:
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no

View File

@@ -8,7 +8,7 @@ services:
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command:
[
"${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tls:324}",
"${RPKI_RTR_TLS_SERVER_ADDR:-rpki-rtr:324}",
"${RPKI_RTR_PROTOCOL_VERSION:-2}",
"reset",
"--tls",
@@ -24,7 +24,7 @@ services:
"--summary-only"
]
volumes:
- ${RPKI_RTR_TLS_CERTS_HOST_DIR:-../../tests/fixtures/tls}:/app/certs:ro
- ${RPKI_RTR_TLS_CERTS_HOST_DIR:-../../certs/tls}:/app/certs:ro
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no
stdin_open: true

View File

@@ -4,7 +4,7 @@ services:
context: ../..
dockerfile: deploy/client/Dockerfile
image: ${RPKI_RTR_CLIENT_IMAGE:-rpki-rtr-debug-client:latest}
command: ["${RPKI_RTR_SERVER_ADDR:-rpki-rtr-tcp:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
command: ["${RPKI_RTR_TCP_SERVER_ADDR:-rpki-rtr:323}", "${RPKI_RTR_PROTOCOL_VERSION:-2}", "reset", "--keep-after-error", "--summary-only"]
volumes:
- ${RPKI_RTR_CLIENT_LOG_HOST_DIR:-../../logs/client}:/app/logs
restart: no

4
deploy/frr/.env Normal file
View File

@@ -0,0 +1,4 @@
# RTR server endpoint used by deploy/frr/frr.conf.template.
RPKI_FRR_RPKI_HOST=127.0.0.1
RPKI_FRR_RPKI_PORT=323
RPKI_FRR_RPKI_PREFERENCE=1

View File

@@ -15,7 +15,10 @@ Reference:
## Files
- `daemons.example`: sample `/etc/frr/daemons`
- `frr.conf.example`: sample `/etc/frr/frr.conf`
- `frr.conf.example`: static sample `/etc/frr/frr.conf`
- `frr.conf.template`: Docker template used to generate `/etc/frr/frr.conf`
- `entrypoint.sh`: renders `frr.conf.template` from environment variables before starting FRR
- `.env`: default Docker environment values
## How to apply on an FRR host
@@ -44,21 +47,32 @@ contains VRPs, the RTR client path is working.
From repository root:
```bash
docker compose -f deploy/frr/docker-compose.yml up -d
docker compose --env-file deploy/frr/.env -f deploy/frr/docker-compose.yml up -d
docker exec -it frr-rpki-client vtysh -c "show rpki cache-connection"
docker exec -it frr-rpki-client vtysh -c "show rpki prefix-table"
```
The Docker example defaults to `127.0.0.1:323`. Override the RTR server
endpoint with environment variables:
```bash
RPKI_FRR_RPKI_HOST=10.0.0.12 \
RPKI_FRR_RPKI_PORT=323 \
docker compose --env-file deploy/frr/.env -f deploy/frr/docker-compose.yml up -d
```
Stop:
```bash
docker compose -f deploy/frr/docker-compose.yml down
docker compose --env-file deploy/frr/.env -f deploy/frr/docker-compose.yml down
```
## Notes
- This setup targets RTR over TCP (`rpki cache tcp`).
- Docker mode renders `frr.conf.template` into `/etc/frr/frr.conf` at startup.
- Keep protocol-level conformance checks in Rust tests and
`src/bin/rtr_debug_client`.
- `network_mode: host` expects your RTR server to be reachable at
`127.0.0.1:323` from the Docker host.
- `network_mode: host` is kept for the minimal FRR container example, but the
RTR server address is controlled by `RPKI_FRR_RPKI_HOST` and
`RPKI_FRR_RPKI_PORT`.

View File

@@ -12,7 +12,10 @@
## 文件说明
- `daemons.example`:示例 `/etc/frr/daemons`
- `frr.conf.example`:示例 `/etc/frr/frr.conf`
- `frr.conf.example`:静态示例 `/etc/frr/frr.conf`
- `frr.conf.template`:Docker 启动时生成 `/etc/frr/frr.conf` 的模板
- `entrypoint.sh`:启动 FRR 前根据环境变量渲染 `frr.conf.template`
- `.env`:Docker 示例使用的默认环境变量
## 在 FRR 主机上应用
@@ -40,15 +43,23 @@ vtysh -c "show rpki prefix-table"
在仓库根目录执行:
```bash
docker compose -f deploy/frr/docker-compose.yml up -d
docker compose --env-file deploy/frr/.env -f deploy/frr/docker-compose.yml up -d
docker exec -it frr-rpki-client vtysh -c "show rpki cache-connection"
docker exec -it frr-rpki-client vtysh -c "show rpki prefix-table"
```
Docker 示例默认连接 `127.0.0.1:323`。如果 RTR Server 在其他地址,可以通过环境变量覆盖:
```bash
RPKI_FRR_RPKI_HOST=10.0.0.12 \
RPKI_FRR_RPKI_PORT=323 \
docker compose --env-file deploy/frr/.env -f deploy/frr/docker-compose.yml up -d
```
停止:
```bash
docker compose -f deploy/frr/docker-compose.yml down
docker compose --env-file deploy/frr/.env -f deploy/frr/docker-compose.yml down
```
## 可测试范围
@@ -68,4 +79,5 @@ docker compose -f deploy/frr/docker-compose.yml down
## 说明
- 当前示例主要针对 RTR over TCP(`rpki cache tcp`)
- `network_mode: host` 模式下,容器内访问 `127.0.0.1:323` 指向 Docker Host,请确保本机 RTR Server 可达
- Docker 模式会在启动时把 `frr.conf.template` 渲染为 `/etc/frr/frr.conf`
- `network_mode: host` 仍用于最小化 FRR 容器示例,但 RTR Server 地址由 `RPKI_FRR_RPKI_HOST` 和 `RPKI_FRR_RPKI_PORT` 控制

View File

@@ -5,6 +5,12 @@ services:
restart: unless-stopped
network_mode: host
privileged: true
environment:
RPKI_FRR_RPKI_HOST: "${RPKI_FRR_RPKI_HOST:-127.0.0.1}"
RPKI_FRR_RPKI_PORT: "${RPKI_FRR_RPKI_PORT:-323}"
RPKI_FRR_RPKI_PREFERENCE: "${RPKI_FRR_RPKI_PREFERENCE:-1}"
entrypoint: ["/bin/sh", "/config/entrypoint.sh"]
volumes:
- ./frr/daemons.example:/etc/frr/daemons:ro
- ./frr/frr.conf.example:/etc/frr/frr.conf:ro
- ./daemons.example:/etc/frr/daemons:ro
- ./frr.conf.template:/config/frr.conf.template:ro
- ./entrypoint.sh:/config/entrypoint.sh:ro

24
deploy/frr/entrypoint.sh Normal file
View File

@@ -0,0 +1,24 @@
#!/bin/sh
set -eu
: "${RPKI_FRR_RPKI_HOST:=127.0.0.1}"
: "${RPKI_FRR_RPKI_PORT:=323}"
: "${RPKI_FRR_RPKI_PREFERENCE:=1}"
: "${RPKI_FRR_CONFIG_TEMPLATE_PATH:=/config/frr.conf.template}"
: "${RPKI_FRR_CONFIG_PATH:=/etc/frr/frr.conf}"
escape_sed() {
printf '%s' "$1" | sed 's/[&|\\]/\\&/g'
}
host="$(escape_sed "${RPKI_FRR_RPKI_HOST}")"
port="$(escape_sed "${RPKI_FRR_RPKI_PORT}")"
preference="$(escape_sed "${RPKI_FRR_RPKI_PREFERENCE}")"
sed \
-e "s|\${RPKI_FRR_RPKI_HOST}|${host}|g" \
-e "s|\${RPKI_FRR_RPKI_PORT}|${port}|g" \
-e "s|\${RPKI_FRR_RPKI_PREFERENCE}|${preference}|g" \
"${RPKI_FRR_CONFIG_TEMPLATE_PATH}" > "${RPKI_FRR_CONFIG_PATH}"
exec /usr/lib/frr/docker-start

View File

@@ -0,0 +1,22 @@
frr version 10.2
frr defaults traditional
hostname rpki-lab
service integrated-vtysh-config
!
debug rpki
!
rpki
rpki polling_period 10
rpki timeout 10
rpki retry_interval 10
rpki expire_interval 7200
rpki cache tcp ${RPKI_FRR_RPKI_HOST} ${RPKI_FRR_RPKI_PORT} preference ${RPKI_FRR_RPKI_PREFERENCE}
exit
!
router bgp 65001
bgp router-id 192.0.2.1
!
address-family ipv4 unicast
exit-address-family
!
line vty

View File

@@ -5,10 +5,6 @@ RPKI_RTR_SLURM_HOST_DIR=../../data
# In-container data source directories.
RPKI_RTR_CCR_DIR=/app/data
RPKI_RTR_SLURM_DIR=/app/slurm
# Persistent directories on host.
RPKI_RTR_DB_HOST_DIR=../../rtr-db
RPKI_RTR_LOG_HOST_DIR=../../logs/server
RPKI_RTR_REPORT_HOST_DIR=../../report
# In-container runtime paths.
@@ -16,6 +12,9 @@ RPKI_RTR_DB_PATH=/app/rtr-db
RPKI_RTR_REPORT_DIR=/app/report
# Core runtime knobs.
# Persistent directories on host.
RPKI_RTR_DB_HOST_DIR=../../rtr-db
RPKI_RTR_LOG_HOST_DIR=../../logs/server
RPKI_RTR_SOURCE_REFRESH_INTERVAL_SECS=300
RPKI_RTR_RUNTIME_REPORT_INTERVAL_SECS=300
RPKI_RTR_REPORT_HISTORY_LIMIT=10
@@ -32,7 +31,8 @@ RPKI_RTR_ENFORCE_TLS_CLIENT_SAN_IP_MATCH=false
RPKI_RTR_TLS_CERT_PATH=/app/certs/server-dns.crt
RPKI_RTR_TLS_KEY_PATH=/app/certs/server-dns.key
RPKI_RTR_TLS_CLIENT_CA_PATH=/app/certs/client-ca.crt
RPKI_RTR_TLS_CERTS_HOST_DIR=../../tests/fixtures/tls
RPKI_RTR_TLS_CERTS_HOST_DIR=../../certs/tls
# SSH mode knobs.
RPKI_RTR_SSH_HOST_PORT=2222
@@ -40,7 +40,7 @@ RPKI_RTR_SSH_CONTAINER_PORT=22
RPKI_RTR_SSH_AUTH_MODE=key
RPKI_RTR_SSH_USERNAME=rpki-rtr
RPKI_RTR_SSH_SUBSYSTEM_NAME=rpki-rtr
RPKI_RTR_SSH_HOST_KEY_PATH=/host-ssh/ssh_host_ed25519_key
RPKI_RTR_SSH_HOST_KEY_PATH=/app/certs/ssh_host_rsa_key
RPKI_RTR_SSH_AUTHORIZED_KEYS_PATH=/app/certs/rtr-authorized_keys
RPKI_RTR_SSH_KEYS_VOLUME=/etc/ssh:/host-ssh:ro
RPKI_RTR_SSH_CERTS_HOST_DIR=../../certs
RPKI_RTR_SSH_CERTS_HOST_DIR=../../certs/ssh

View File

@@ -38,7 +38,7 @@ The container runs `rpki` directly as PID 1.
- Core: `RPKI_RTR_SOURCE_REFRESH_INTERVAL_SECS`, `RPKI_RTR_MAX_DELTA`, `RPKI_RTR_MAX_CONCURRENT_HANDSHAKES`, `RPKI_RTR_RUNTIME_REPORT_INTERVAL_SECS`, `RPKI_RTR_REPORT_HISTORY_LIMIT`, `RPKI_RTR_TIMEZONE`, `RPKI_RTR_ADMIN_ADDR`, `RPKI_RTR_ADMIN_TOKEN`, `RUST_LOG`
- TCP mode: `RPKI_RTR_MAX_CONNECTIONS`
- TLS mode: `RPKI_RTR_ENFORCE_TLS_CLIENT_SAN_IP_MATCH`, `RPKI_RTR_TLS_CERT_PATH`, `RPKI_RTR_TLS_KEY_PATH`, `RPKI_RTR_TLS_CLIENT_CA_PATH`, `RPKI_RTR_TLS_CERTS_HOST_DIR`
- SSH mode: `RPKI_RTR_SSH_HOST_PORT`, `RPKI_RTR_SSH_CONTAINER_PORT`, `RPKI_RTR_SSH_AUTH_MODE`, `RPKI_RTR_SSH_USERNAME`, `RPKI_RTR_SSH_SUBSYSTEM_NAME`, `RPKI_RTR_SSH_HOST_KEY_PATH`, `RPKI_RTR_SSH_AUTHORIZED_KEYS_PATH`, `RPKI_RTR_SSH_KEYS_VOLUME`, `RPKI_RTR_SSH_CERTS_HOST_DIR`
- SSH mode: `RPKI_RTR_SSH_HOST_PORT`, `RPKI_RTR_SSH_CONTAINER_PORT`, `RPKI_RTR_SSH_AUTH_MODE`, `RPKI_RTR_SSH_USERNAME`, `RPKI_RTR_SSH_SUBSYSTEM_NAME`, `RPKI_RTR_SSH_HOST_KEY_PATH`, `RPKI_RTR_SSH_AUTHORIZED_KEYS_PATH`, `RPKI_RTR_SSH_CERTS_HOST_DIR`
## Start

View File

@@ -17,7 +17,7 @@ services:
RPKI_RTR_ENABLE_SSH: "true"
RPKI_RTR_TCP_ADDR: "0.0.0.0:323"
RPKI_RTR_SSH_ADDR: "0.0.0.0:${RPKI_RTR_SSH_CONTAINER_PORT:-22}"
RPKI_RTR_SSH_HOST_KEY_PATH: "${RPKI_RTR_SSH_HOST_KEY_PATH:-/host-ssh/ssh_host_ed25519_key}"
RPKI_RTR_SSH_HOST_KEY_PATH: "${RPKI_RTR_SSH_HOST_KEY_PATH:-/app/certs/ssh_host_rsa_key}"
RPKI_RTR_SSH_AUTHORIZED_KEYS_PATH: "${RPKI_RTR_SSH_AUTHORIZED_KEYS_PATH:-/app/certs/rtr-authorized_keys}"
RPKI_RTR_SSH_USERNAME: "${RPKI_RTR_SSH_USERNAME:-rpki-rtr}"
RPKI_RTR_SSH_SUBSYSTEM_NAME: "${RPKI_RTR_SSH_SUBSYSTEM_NAME:-rpki-rtr}"
@@ -42,8 +42,7 @@ services:
- ${RPKI_RTR_CCR_HOST_DIR:-../../data}:${RPKI_RTR_CCR_DIR:-/app/data}:ro
- ${RPKI_RTR_DB_HOST_DIR:-../../rtr-db}:${RPKI_RTR_DB_PATH:-/app/rtr-db}
- ${RPKI_RTR_SLURM_HOST_DIR:-../../data}:${RPKI_RTR_SLURM_DIR:-/app/slurm}
- ${RPKI_RTR_SSH_KEYS_VOLUME:-/etc/ssh:/host-ssh:ro}
- ${RPKI_RTR_SSH_CERTS_HOST_DIR:-../../certs}:/app/certs:ro
- ${RPKI_RTR_SSH_CERTS_HOST_DIR:-../../certs/ssh}:/app/certs:ro
- ${RPKI_RTR_LOG_HOST_DIR:-../../logs/server}:/app/logs
- ${RPKI_RTR_REPORT_HOST_DIR:-../../report}:${RPKI_RTR_REPORT_DIR:-/app/report}
networks:

View File

@@ -36,7 +36,7 @@ services:
- ${RPKI_RTR_CCR_HOST_DIR:-../../data}:${RPKI_RTR_CCR_DIR:-/app/data}:ro
- ${RPKI_RTR_DB_HOST_DIR:-../../rtr-db}:${RPKI_RTR_DB_PATH:-/app/rtr-db}
- ${RPKI_RTR_SLURM_HOST_DIR:-../../data}:${RPKI_RTR_SLURM_DIR:-/app/slurm}
- ${RPKI_RTR_TLS_CERTS_HOST_DIR:-../../tests/fixtures/tls}:/app/certs:ro
- ${RPKI_RTR_TLS_CERTS_HOST_DIR:-../../certs/tls}:/app/certs:ro
- ${RPKI_RTR_LOG_HOST_DIR:-../../logs/server}:/app/logs
- ${RPKI_RTR_REPORT_HOST_DIR:-../../report}:${RPKI_RTR_REPORT_DIR:-/app/report}
networks:

View File

@@ -35,7 +35,7 @@ services:
# RPKI_RTR_ENABLE_SSH: "true"
# RPKI_RTR_SSH_ADDR: "0.0.0.0:22"
# RPKI_RTR_SSH_PORT: "22"
# RPKI_RTR_SSH_HOST_KEY_PATH: "/app/certs/ssh_host_ed25519_key"
# RPKI_RTR_SSH_HOST_KEY_PATH: "/app/certs/ssh_host_rsa_key"
# RPKI_RTR_SSH_AUTHORIZED_KEYS_PATH: "/app/certs/rtr-authorized_keys"
# RPKI_RTR_SSH_USERNAME: "rpki-rtr"
# RPKI_RTR_SSH_SUBSYSTEM_NAME: "rpki-rtr"
@@ -48,7 +48,7 @@ services:
- ${RPKI_RTR_LOG_HOST_DIR:-../../logs/server}:/app/logs
- ${RPKI_RTR_REPORT_HOST_DIR:-../../report}:${RPKI_RTR_REPORT_DIR:-/app/report}
# TLS mode example:
# - ../../certs:/app/certs:ro
# - ../../certs/ssh:/app/certs:ro
networks:
- rpki_net