使用 SigNoz + OneUptime 构建多租户可观测平台
Source: Dev.to
请提供您希望翻译的正文内容(除代码块和 URL 之外),我将按照要求将其翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。
架构概览
现代 SaaS 团队需要深度可观测性,同时不能牺牲租户隔离或合规性。本文阐述了我们如何构建一个多租户监控平台,将日志、指标和追踪路由到隔离的 SigNoz 和 OneUptime 堆栈,实施强安全控制,并符合 SOC 2 与 ISO 27001 的实践。结果是:每个客户都获得专属的监控体验,而我们保持运营足迹轻量且可重复。
我们采用了 中心‑辐射(hub‑and‑spoke)模型:
- 中央监控 VM 托管可观测性堆栈。
- 每个租户拥有以下两种方式之一:
- 完全隔离的 SigNoz 堆栈(前端、查询、收集器、ClickHouse),或
- 共享堆栈,通过租户标识符进行严格路由(适用于轻量租户)。
- 每个应用 VM 运行 OpenTelemetry(OTEL)Collector,负责:
- 读取 PM2 日志,
- 接收 OTLP 追踪/指标,
- 将所有数据转发至监控 VM。
这提供了一致的摄取管道,同时在需要时默认实现隔离。

租户隔离策略
我们支持两种隔离模式:
-
每个租户的完整隔离
- 为每个租户提供专用的 SigNoz 堆栈
- 独立的 ClickHouse 实例
- 独立的 OTEL 收集器上游
- 最强的数据隔离
-
共享堆栈上的逻辑隔离
- 单一的 SigNoz + ClickHouse 实例
- 通过
business_id(header + resource attribute)进行路由 - 适用于较小的租户
默认 – 对受监管或高流量客户进行完整隔离。
关键路由头部
x-business-id用于 SigNozx-oneuptime-token用于 OneUptime
监控虚拟机的配置与加固
我们将监控虚拟机视为受控的生产系统:
- 仅使用 SSH 密钥,不使用密码认证
- 最小化入站端口:
22, 80, 443, 4317, 4318 - Nginx 作为单一的 TLS 入口
- Docker Compose 用于不可变的服务布局
示例配置步骤(高级)
# SSH key‑based access only
az vm user update \
--resource-group \
--name \
--username \
--ssh-key-value ""
# Open required ports (restrict SSH to trusted IPs)
az network nsg rule create ... \
--destination-port-ranges 22 80 443 4317 4318
多租户边缘路由
我们使用 Nginx maps 根据主机名对 UI 和 OTLP 接入流量进行路由:
map $host $signoz_collector_upstream {
signoz.tenant-a.example signoz-otel-collector-tenant-a;
signoz.tenant-b.example signoz-otel-collector-tenant-b;
default signoz-otel-collector-default;
}
server {
listen 4318;
location / {
proxy_pass http://$signoz_collector_upstream;
}
}
这样即可实现基于 DNS 的干净租户路由,同时只保留一个 IP 地址。
收集器配置:日志、追踪、指标
每个租户的 VM 都运行一个带有 filelog + OTLP 的 OTEL Collector。我们解析 PM2 日志(JSON 包装),统一 severity(严重程度),并附加资源字段,以便在 SigNoz 中实现快速过滤。
我们强制的核心字段
severity_text(info / warn / error)service.namedeployment.environmenthost.namebusiness_id
最小配置摘录
processors:
resourcedetection:
detectors: [system]
resource:
attributes:
- key: business_id
value: ${env:BUSINESS_ID}
action: upsert
transform/logs:
log_statements:
- context: log
statements:
- set(severity_text, attributes["severity"])
where attributes["severity"] != nil
这些增强使得 severity_text、service.name 和 host.name 能够在 SigNoz 中立即被搜索。
客户端集成(应用)
我们在后端、Web 和代理服务中使用一致的 OTEL 模式:
- Backend – OTLP 导出器用于跟踪
- Web – 浏览器跟踪转发到后端(后端再重新导出)
- Agents – OTEL SDK 配置了
OTEL_EXPORTER_OTLP_ENDPOINT
常见环境变量
BUSINESS_ID=tenant-a
SIGNOZ_ENDPOINT=http://signoz.tenant-a.example:4318
ONEUPTIME_ENDPOINT=http://status.tenant-a.example:4318
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:4318/v1/traces
DEPLOY_ENV=production
DNS 和 TLS(公共 UX)
每个租户都有自己的子域名:
signoz.<tenant>.examplestatus.<tenant>.example
TLS 终止在 Nginx 上,使用真实证书(ACME/Let’s Encrypt):
sudo certbot --nginx \
-d signoz.tenant-a.example \
-d status.tenant-a.example
我们保持每个租户的 TLS 策略与强加密套件和 HSTS 对齐。
验证与可观测性 QA
我们使用以下方式验证管道:
- OTEL health endpoint(collector 上的
/health) - 来自后端服务的测试流量
- ClickHouse 查询以确认日志属性
- SigNoz 过滤器用于
severity_text、service.name、host.name
示例 ClickHouse 检查(内部)
SELECT severity_text, count()
FROM signoz_logs.logs_v2
WHERE resources_string['business_id'] = 'tenant-a'
AND timestamp >= now() - INTERVAL 15 MINUTE
GROUP BY severity_text;
安全与合规(SOC 2 + ISO 27001)
与 SOC 2 和 ISO 27001 对齐的控制措施:
- 访问控制 – 仅使用 SSH 密钥,最小权限 IAM,云控制台启用 MFA。
- 网络分段 – 开放端口最少;SSH 受源 IP 限制。
- 机密管理 – 运行时机密存放在保管库中,绝不写入代码。
- 传输加密 – 全面使用 TLS,杜绝明文流量。
- 审计日志 – 所有管理员操作均记录并根据合规窗口保留。
- 补丁管理 – 自动化的操作系统和容器镜像更新,并进行 CVE 扫描。
安全与运营控制
- 暴露明文端点。
- 静态加密:在虚拟机和数据库卷上启用磁盘加密。
- 审计追踪:系统日志保留;基础设施变更以代码形式追踪。
- 变更管理:所有配置存放在代码仓库中;部署前必须进行变更审查。
- 监控与告警:使用 OneUptime 进行 SLO 和正常运行时间检查。
- 事件响应:已制定文档化流程、保留策略和升级机制。
- 备份策略:针对每个租户的 ClickHouse 备份策略。
可重复性:基础设施 + 租户配置即代码
我们按职责划分配置:
- 监控服务仓库: 所有基础设施和 Nginx 路由。
- 租户仓库: OTEL 收集器配置和部署钩子。
这意味着可以通过以下步骤重建新 VM:
-
拉取监控仓库并运行:
docker compose up -d -
更新 DNS + TLS。
-
运行租户部署脚本以安装收集器和环境。
关键要点
- 为注重合规的客户提供强大的租户隔离。
- 共享运维流程和标准配置。
- 快速日志过滤(严重性 / 服务 / 环境 / 主机),实现高信噪比调试。
- 可重复、可审计的部署流程,符合 SOC 2 和 ISO 27001 要求。