跑在 PostgreSQL 上
Beacon 默认把状态放在 SQLite 里:一个文件,不用另跑服务,对哪个团队都够用。已经在跑 PostgreSQL、想把 Beacon 的状态和其他数据放在一起,想用托管数据库或按时间点恢复,或者要主备两台时,再搬到 PostgreSQL。性能不是搬的理由。两边的状态一样,表也一样:账号、Agent 和令牌,目录,告警组,审计日志和它的哈希链。示例以装在服务器上的参考部署为准,在 /opt/beacon 下以 root 执行。
准备数据库
Beacon 要 PostgreSQL 14 或更新的版本,以及一个归它自己的数据库和角色;表由它第一次启动时自己建。
CREATE ROLE beacon LOGIN PASSWORD 'a long random password';
CREATE DATABASE beacon OWNER beacon;还没有 PostgreSQL 的话,在同一个 compose 文件里和 Beacon 并排起一个就行。端口只在 compose 网络里,数据有自己的卷:
services:
postgres:
container_name: beacon-postgres
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: beacon
POSTGRES_DB: beacon
POSTGRES_PASSWORD_FILE: /run/secrets/postgres-password
volumes:
- postgres-data:/var/lib/postgresql/data
- ./secrets/postgres-password:/run/secrets/postgres-password:ro
healthcheck:
test: [CMD, pg_isready, -U, beacon, -d, beacon]
interval: 10s
mem_limit: 512m
volumes:
postgres-data:Beacon 从文件读连接串,不从 YAML 读,也从不把它写进日志或错误信息。把它放进密钥目录,和其他密钥一样只让 Beacon 的用户(uid 65532)能读:
cd /opt/beacon
printf 'postgres://beacon:%s@postgres:5432/beacon?sslmode=disable\n' "$PASSWORD" > secrets/postgres-dsn
chown 65532:65532 secrets/postgres-dsn && chmod 0400 secrets/postgres-dsnsslmode=disable 适合同一个 compose 网络里的数据库,流量不出这台机器;在别处的数据库用 sslmode=verify-full。
搬状态
搬迁在一个事务里把 SQLite 数据库复制进空的 PostgreSQL 数据库,提交前核对条数,并在审计链上加一条记录注明这次导入。SQLite 文件原样留着。搬的时候要停掉 Beacon:复制之后服务写的东西只会留在 SQLite 里。停机期间各检测点把结果排在本地磁盘上,网关恢复后再补发。
在
config.yaml里写上数据库,驱动暂时还是sqlite:yamlstorage: driver: sqlite dsn_file: /etc/beacon/secrets/postgres-dsn停掉 Beacon,开始搬:
bashdocker compose stop beacon docker compose run --rm --no-deps beacon storage migrate -to postgres -config /etc/beacon/config.yaml它回答
moved /var/lib/beacon/beacon.db into postgres postgres:5432/beacon: N entries across the buckets, the audit log newest …。PostgreSQL 数据库里已经有东西时会拒绝,所以再跑一次什么也不会复制。把
config.yaml里的驱动改成postgres,启动 Beacon:bashdocker compose up -d beacon
检查
docker exec beacon beacon storage check -config /etc/beacon/config.yaml
docker exec beacon beacon audit verify -config /etc/beacon/config.yaml前一条读每张表并校验审计链,后一条从头走一遍链;两条都应该报告完整,最新一条是导入的记录。登录控制台:账号、告警和配置的历史都和原来一样。
回退
把 storage.driver 改回 sqlite,重启 Beacon。它用的是搬迁那一刻的 SQLite 文件;之后写进 PostgreSQL 的东西不在里面。
备份
状态现在在 PostgreSQL 里,所以备份与恢复里每晚的备份改成导出数据库,不再拷 SQLite 文件。pg_dump 在 Beacon 运行时读一个一致的快照,什么都不用停:
docker compose exec -T postgres pg_dump -U beacon -Fc beacon > /opt/beacon-backups/beacon-$(date +%F).dumpbeacon-data 卷里还有会话录像(除非录像放在对象存储里,ssh.recordings: s3),照旧备份。恢复时先起一个空的 PostgreSQL,用 pg_restore -U beacon -d beacon 把导出倒进去,再启动 Beacon。
主备两台
用 PostgreSQL 时,两台机器上的两个 Beacon 实例可以共用状态:在数据库里持有租约的是主,主停止续约、租约过期后(约 15 秒)另一台接手。两台要用同样的配置、同样的密钥,录像放在同一个对象存储桶里;ha 和 ssh.recordings 的字段见配置参考。前面的负载均衡把流量发给 /healthz 返回 200 的那台。