- 后端
- 前端
- 企业应用
- 运维
- 网络安全
【免费下载链接】fleet
Open device management
SigNoz 是 Fleet 负载测试(loadtesting)环境中的 OpenTelemetry 追踪后端,以独立 Terraform 根模块(root module)形式部署,确保在 Fleet 主基础设施启动之前即可开始采集遥测数据。本文基于 infrastructure/loadtesting/terraform/signoz/README.md 展开,结合模块内的 main.tf、otel-collector-values.yaml、outputs.tf 等源码,完整讲解从架构设计、部署顺序、Fleet 侧集成、OTLP Collector 调优到 ClickHouse 存储治理与销毁清理的端到端实战方案。读完本文,你将能够独立部署一套面向高并发负载测试的 OpenTelemetry 可观测性栈,并正确地把 Fleet 服务器的追踪数据接入 SigNoz 进行链路分析。
SigNoz 在 Fleet 负载测试体系中的定位
Fleet 的负载测试基础设施(位于 infrastructure/loadtesting/terraform 目录)由多个相互独立的 Terraform 根模块组成:共享 VPC(shared)、SigNoz(signoz)、Fleet 主基础设施(infra),以及 Android AMAPI mock、osquery 性能测试、PMM 监控等配套模块。SigNoz 模块的职责非常单一:为 Fleet 负载测试环境提供 OpenTelemetry 追踪能力。
为什么选 SigNoz 而不是 Elastic APM
从 infra/locals.tf 的注释可以读到关键决策背景:OpenTelemetry 是唯一被采用的追踪方案,Elastic APM 不被支持。原因是其埋点(instrumentation)是 gorilla 专属的,当 Elastic APM 激活时,Fleet 服务器会关闭标准库 ServeMux 的快速路径(fast path),这对负载测试来说,追踪带来的开销远大于收益。因此负载测试默认完全关闭追踪,只有显式设置enable_otel=true时才启用。
架构总览
SigNoz 模块的架构要点(README 中的 Architecture 一节):
- EKS 集群:每个工作区(workspace)一套独立集群,命名形如
signoz-victor-baseline(前缀signoz-加上当前 Terraform workspace 名,见 main.tf 中的local.cluster_name = "signoz-${terraform.workspace}"); - Kubernetes 版本:v1.31;
- 节点组:README 描述为 2 台 t3.xlarge,而当前 main.tf 实际配置为单个
m6i.8xlarge托管节点(min/max/desired 均为 1),以承载 ClickHouse 与 OTLP Collector 的高资源需求; - 核心组件:
- SigNoz UI:公网 LoadBalancer 暴露,端口 8080;
- OTLP Collector:内网 LoadBalancer 暴露,端口 4317(gRPC),供 Fleet 服务器发送追踪数据;
- ClickHouse:存储追踪数据,README 提及 200Gi,而当前 main.tf 将持久卷大小设置为 600Gi,存储类为 gp3。
部署顺序(关键约束)
SigNoz 必须先于 Fleet 主基础设施部署,否则无法捕获 Fleet 初始启动阶段的遥测数据。标准顺序为:
- 部署共享 EKS VPC(一次性、跨工作区共享,通常已存在);
- 部署 SigNoz(即本模块);
- 部署 Fleet 基础设施(infrastructure/loadtesting/terraform/infra)。
这个顺序在 infra/signoz.tf 中通过terraform_remote_state数据源体现:Fleet 基础设施会读取 SigNoz 模块的远程状态(remote state)来获取 OTLP 端点,因此 SigNoz 必须先 apply。
模块文件与前置依赖
SigNoz 模块目录结构非常精简:
infrastructure/loadtesting/terraform/signoz/ ├── README.md # 部署与运维说明 ├── main.tf # 核心资源:EKS、EBS CSI、StorageClass、SigNoz Helm Release、销毁清理 ├── otel-collector-values.yaml # OTLP Collector Helm values 覆盖 ├── outputs.tf # 提供给 Fleet 基础设施消费的输出 └── variables.tf # 唯一变量:aws_region依赖的 Provider 与版本约束
main.tf 声明了 Terraform 与 Provider 版本要求:
| 组件 | 版本约束 | 用途 |
|---|---|---|
| Terraform | >= 1.5 | 模块运行的最低版本 |
| AWS Provider | >= 5.68.0 | 创建 EKS、IAM、存储相关资源 |
| Helm Provider | ~> 2.11 | 部署 SigNoz chart |
| Kubernetes Provider | ~> 2.23 | 创建 StorageClass、读取 Service |
| Null Provider | ~> 3.2 | 执行销毁前清理脚本 |
远程状态与共享 VPC
模块使用 S3 作为远程状态后端,配置了 workspace key 前缀、加密、DynamoDB 锁以及assume_role:
backend "s3" { bucket = "fleet-terraform-state20220408141538466600000002" key = "loadtesting/loadtesting/signoz/terraform.tfstate" workspace_key_prefix = "loadtesting" region = "us-east-2" encrypt = true kms_key_id = "9f98a443-ffd7-4dbe-a9c3-37df89b2e42a" dynamodb_table = "tf-remote-state-lock" assume_role = { role_arn = "arn:aws:iam::353365949058:role/terraform-loadtesting" } }EKS 集群创建在共享 VPC 中,通过terraform_remote_state读取shared模块的输出获取 VPC ID 与私有子网(见 main.tf 与 L107-L117),这保证了 SigNoz 的内网 OTLP 端点能被同 VPC 内的 Fleet 服务器访问。
部署步骤详解
按照 README 的 Usage 一节,部署流程如下:
# 1. 初始化并选择工作区 cd infrastructure/loadtesting/terraform/signoz terraform init terraform workspace new <workspace_name> # 与你的 infra 工作区保持一致 # 2. 部署 SigNoz terraform apply # 3. 等待部署完成(约 10-15 分钟) # OTLP collector 端点会显示在 outputs 中 # 4. 部署 Fleet 主基础设施 cd ../infra terraform apply工作区命名一致性
工作区名称至关重要:EKS 集群名、IAM 角色名(如ebs-csi-driver角色、${local.cluster_name}-ebs-csi-driver)、以及 AWS 资源的 default tag 都会引用terraform.workspace(见 main.tf)。同时,Fleet 基础设施(infra)读取 SigNoz 远程状态时也使用当前工作区(infra/signoz.tf 中workspace = terraform.workspace),因此 SigNoz 与 infra 必须使用同名工作区,才能正确关联。
部署耗时说明
helm_release.signoz设置了timeout = 3600(60 分钟),注释明确说明这是为了容忍 AWS 在 apply 与 destroy 阶段的最坏情况延迟(main.tf)。正常情况下整体部署约 10-15 分钟完成,其中包含 EKS 集群创建、EBS CSI Driver 就绪等待(time_sleep60 秒)、gp3 StorageClass 创建以及 SigNoz 全家桶(UI、OTLP Collector、ClickHouse、ZooKeeper、Alertmanager)的 Helm 安装。
访问 SigNoz UI
部署完成后有两种方式获取 UI 地址:
# 方式一:直接输出 UI URL 命令 terraform output -raw get_signoz_ui_url | bash # 方式二:配置 kubectl 后手动查询 $(terraform output -raw configure_kubectl) kubectl get svc -n signoz signoz -o jsonpath='http://{.status.loadBalancer.ingress[0].hostname}:8080'对应的输出定义在 outputs.tf:
configure_kubectl:生成aws eks update-kubeconfig --region <region> --name <cluster>命令,用$(...)包裹后可直接执行;get_signoz_ui_url:查询signoz命名空间下名为signoz的 Service 的 LoadBalancer hostname,拼上:8080端口。
如果是在infra目录部署完成后访问,也可以使用 infra/README.md 提供的等价命令:
$(terraform output -raw signoz_configure_kubectl) && kubectl get svc signoz -n signoz -o jsonpath='http://{.status.loadBalancer.ingress[0].hostname}:8080'输出与 Fleet 基础设施的集成
模块 Outputs
outputs.tf 共导出 7 个输出,其中被 Fleet 基础设施通过远程状态消费的关键三个是:
| 输出 | 说明 |
|---|---|
cluster_name | EKS 集群名称,Fleet 基础设施用于关联与诊断 |
otel_collector_endpoint | 内网 OTLP 端点(hostname:4317),Fleet 服务器发送追踪数据的地址 |
configure_kubectl | 配置 kubectl 访问 SigNoz 集群的命令 |
otel_collector_endpoint通过 Kubernetes Provider 的data "kubernetes_service"数据源,读取signoz-otel-collectorService 的 LoadBalancer hostname 并拼接:4317端口(outputs.tf)。它还提供了get_otlp_endpoint输出,方便手动查询 OTLP 端点。
Fleet 侧如何消费这些输出
Fleet 基础设施模块(infra)在 signoz.tf 中通过terraform_remote_state读取 SigNoz 的远程状态,并使用变量enable_otel(默认false,定义于 infra/variables.tf)控制是否启用追踪:
data "terraform_remote_state" "signoz" { count = var.enable_otel ? 1 : 0 backend = "s3" # ... 与 SigNoz 模块相同的 bucket/key/workspace_key_prefix 配置 workspace = terraform.workspace }启用后,infra/locals.tf 会为 Fleet 服务器注入以下环境变量:
otel_environment_variables = var.enable_otel ? { OTEL_SERVICE_NAME = "fleet" OTEL_RESOURCE_ATTRIBUTES = "deployment.environment.name=${terraform.workspace},deployment.environment=${terraform.workspace}" OTEL_EXPORTER_OTLP_ENDPOINT = "http://${data.terraform_remote_state.signoz[0].outputs.otel_collector_endpoint}" FLEET_LOGGING_TRACING_ENABLED = "true" FLEET_LOGGING_TRACING_TYPE = "opentelemetry" } : {}这些环境变量与 Fleet 服务器配置一一对应:FLEET_LOGGING_TRACING_ENABLED映射logging.tracing_enabled,FLEET_LOGGING_TRACING_TYPE映射logging.tracing_type(配置解析见 server/config/config.go 与 server/config/config.go)。Fleet 服务器通过OTELEnabled()方法判断是否启用 OpenTelemetry:
// server/config/config.go#L939-L941 func (f FleetConfig) OTELEnabled() bool { return f.Logging.TracingEnabled && f.Logging.TracingType != "elasticapm" }即:只有tracing_enabled=true且tracing_type不是elasticapm时,OTel 追踪才会生效——这与 infra 模块"OpenTelemetry 是唯一选项"的设计完全吻合。OTEL_EXPORTER_OTLP_ENDPOINT指向 SigNoz 内网 OTLP Collector(http://<internal-lb-hostname>:4317),追踪数据默认通过 gRPC 协议上报。
在 infra 中启用追踪
按照 infra/README.md 的说明,部署 Fleet 基础设施时加上enable_otel=true即可同时启用 SigNoz 追踪:
terraform apply -var=tag=v4.72.0 -var=fleet_task_count=20 -var=fleet_task_memory=4096 -var=fleet_task_cpu=512 -var=database_instance_size=db.t4g.large -var=database_instance_count=3 -var=redis_instance_size=cache.t4g.small -var=redis_instance_count=3 -var=enable_otel=true源码级深潜:Terraform 模块实现要点
EKS 集群与插件安装顺序
main.tf 中有一处极具工程价值的注释:核心插件必须在节点组之前安装,否则会死锁。原因在于:节点需要 VPC CNI 才能变为 Ready,而 Terraform 在创建附加组件(addons)前会等待节点 Ready,两者互相等待导致节点卡在 NotReady。解决方案是使用before_compute = true,让 vpc-cni、kube-proxy、coredns 三个 addon 在节点组完成之前安装:
addons = { vpc-cni = { most_recent = true, before_compute = true } kube-proxy = { most_recent = true, before_compute = true } coredns = { most_recent = true, before_compute = true } }集群启用了 cluster creator admin 权限(enable_cluster_creator_admin_permissions = true)与 IRSA(enable_irsa = true),为后续 EBS CSI Driver 服务账户授权做准备。
EBS CSI Driver 与 gp3 存储类
ClickHouse、ZooKeeper、Alertmanager 都需要持久化存储。模块专门为 EBS CSI Driver 创建了 IRSA 角色(ebs-csi-driver),并单独挂载aws-eks-addon资源以避免与 OIDC Provider 的循环依赖(main.tf)。随后创建默认的gp3存储类,启用加密、容量扩容与WaitForFirstConsumer绑定模式:
resource "kubernetes_storage_class_v1" "gp3" { storage_provisioner = "ebs.csi.aws.com" reclaim_policy = "Delete" allow_volume_expansion = true volume_binding_mode = "WaitForFirstConsumer" parameters = { type = "gp3", encrypted = "true", fsType = "ext4" } }所有 SigNoz 组件(ClickHouse 600Gi、ZooKeeper、Alertmanager)的持久卷都显式指定storageClass = "gp3"(main.tf)。
SigNoz Helm Release 的关键参数
helm_release.signoz使用官方 chart(https://charts.signoz.io,chart 名为signoz),安装在signoz命名空间(main.tf),核心覆盖参数如下:
| 参数 | 值 | 说明 |
|---|---|---|
cloud | false | 自托管模式,不使用 SigNoz Cloud |
signoz.service.type | LoadBalancer | SigNoz UI 公网暴露 |
otelCollector.service.type | LoadBalancer | OTLP Collector 服务暴露 |
otelCollector.service.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-scheme | internal | 关键:OTLP Collector 仅内网可达,不对外开放 |
clickhouse.persistence.size | 600Gi | ClickHouse 持久卷大小 |
clickhouse.persistence.storageClass | gp3 | 使用 gp3 存储类 |
zookeeper.persistence.storageClass | gp3 | ZooKeeper 存储类 |
alertmanager.persistence.storageClass | gp3 | Alertmanager 存储类 |
clickhouse.resources.requests.cpu/memory | 6000m/12Gi | ClickHouse 请求资源 |
clickhouse.resources.limits.cpu/memory | 12000m/24Gi | ClickHouse 资源上限 |
otelCollector.resources.requests.cpu/memory | 3000m/24Gi | OTLP Collector 请求资源 |
otelCollector.resources.limits.cpu/memory | 12000m/36Gi | OTLP Collector 资源上限 |
otelCollector.replicaCount | 3 | OTLP Collector 三副本,保证采集高可用 |
代码注释明确说明了资源调整的动机:chart 默认的 ClickHouse100mCPU 与200Mi内存对高吞吐遥测数据来说远远不够,必须按负载测试的规模显著放大。
OTLP Collector 配置详解
模块通过 otel-collector-values.yaml 对 OTLP Collector 进行"完全显式"的配置覆盖,目标是生产级稳定性。这份配置是理解整个追踪链路的钥匙。
接收端(Receivers)
| 接收器 | 协议 | 端点 | 说明 |
|---|---|---|---|
otlp/grpc | gRPC | 0.0.0.0:4317 | 标准 OTLP 入口,max_recv_msg_size_mib: 16限制单条消息大小 |
otlp/http | HTTP | 0.0.0.0:4318 | OTLP HTTP 入口 |
jaeger/grpc | gRPC | 0.0.0.0:14250 | 兼容 Jaeger gRPC 协议 |
jaeger/thrift_http | Thrift | 0.0.0.0:14268 | 兼容 Jaeger Thrift 协议 |
处理管道(Processors)
- batch:
send_batch_size=6000、send_batch_max_size=7500、timeout=5s,为 traces/logs/metrics 主链路设计,平衡吞吐与内存; - batch/meter:
send_batch_max_size=75000、send_batch_size=60000、timeout=1s,面向 meter 指标的高容量批处理; - memory_limiter:
limit_mib=33792(约 33Gi)、spike_limit_mib=1536、check_interval=1s,与 Collector 36Gi 的内存上限配合,防止 OOM; - signozspanmetrics/delta:把 span 转换为 RED 指标(请求率、错误率、耗时分布),
latency_histogram_buckets定义了从 100us 到 60s 的 16 档直方图桶,dimensions_cache_size=100000缓存维度,aggregation_temporality=DELTA使用增量聚合。
导出端(Exporters)与管道编排
| 导出器 | 超时 | 重试 | 发送队列 | 目标 |
|---|---|---|---|---|
clickhousetraces | 60s | 5s→30s 指数退避,最长 300s | 30 消费者,15000 队列 | 追踪数据写入 ClickHouse |
clickhouselogsexporter | 60s | 同上 | 30 消费者,15000 队列 | 日志写入 ClickHouse |
signozclickhousemetrics | 45s | — | — | 指标写入 ClickHouse |
metadataexporter | 60s | 同上 | — | 元数据导出 |
signozclickhousemeter | 45s | 关闭队列 | — | meter 指标写入 ClickHouse |
service.pipelines定义了四条链路:traces(otlp+jaeger → memory_limiter → signozspanmetrics/delta → batch → clickhousetraces + metadataexporter + signozmeter)、metrics、logs、metrics/meter。另有两个值得注意的细节:
lowCardinalityExceptionGrouping: true:开启低基数异常分组,压缩异常告警噪声;signozmeter连接器设置了metrics_flush_interval: 1h,并按service.name、deployment.environment、host.name三个维度聚合;service.telemetry.logs.encoding: json:Collector 自身日志输出为 JSON,便于接入日志系统排查。
ClickHouse 存储管理与保留期治理
README 的 "Managing storage and retention" 一节是整个运维部分的重心。ClickHouse 存储有限(当前配置 600Gi gp3 卷),负载测试会产生海量 trace,因此必须主动治理。
1. 缩短追踪数据保留期
在 SigNoz UI 中操作:
- 进入Settings → Retention Period;
- 针对 traces 降低保留期(默认值对负载测试场景过长);
- 活跃负载测试环境建议设置为1-3 天。
2. 监控 ClickHouse 存储用量
# 查看 ClickHouse pod 存储使用情况 kubectl exec -n signoz chi-signoz-clickhouse-cluster-0-0-0 -- df -h /var/lib/clickhouse # 按数据库统计磁盘占用 kubectl exec -n signoz chi-signoz-clickhouse-cluster-0-0-0 -- clickhouse-client --query "SELECT database, formatReadableSize(sum(bytes_on_disk)) AS size FROM system.parts WHERE active GROUP BY database ORDER BY sum(bytes_on_disk) DESC"第一条命令检查数据目录所在文件系统的剩余空间;第二条命令通过 ClickHouse 的system.parts系统表,按数据库聚合活跃分区(active)的磁盘占用,并按从大到小排序,能够快速定位是 trace、log 还是 metric 库在膨胀。
3. 存储写满的后果
README 明确列出了存储耗尽时的行为,这决定了监控的重要性:
- ClickHouse 会拒绝新的写入请求;
- 新的 trace 将无法被采集;
- OTLP Collector 会记录写入失败的报错日志;
- Fleet 服务器继续运行,但追踪数据会丢失。
换句话说,存储写满不会导致负载测试失败,但会让追踪数据出现静默缺口,误导后续性能分析。因此,在长跑型负载测试前,务必先调整保留期并确认磁盘水位。
销毁流程与已知问题处理
基本销毁
terraform destroy已知的销毁挂起问题(fleetdm/fleet#35405)与预销毁清理
main.tf 中实现了一个非常值得借鉴的null_resource预销毁清理机制。其背景是:SigNoz chart 安装了 Altinity clickhouse-operator,该 operator 会在其ClickHouseInstallation(CHI)自定义资源上放置 finalizer。执行helm uninstall时 operator 先被移除,于是没有任何组件来处理这个 finalizer,导致 CHI 删除卡死,进而拖住 PVC 与命名空间删除,最终让helm_release(wait = true)在销毁时等待到完整超时。
清理脚本利用"Terraform 在销毁时先销毁依赖方"的特性(depends_on = [helm_release.signoz]保证该资源先于 helm_release 执行),依次完成:
- 先删除 clickhouse-operator Deployment:因为 operator 运行时会立即重新添加 CHI finalizer,仅 patch finalizer 会输掉竞争;删除后还会等待 pod 真正终止(
kubectl wait --for=delete,上限 120s,外加轮询兜底); - 剥离 CHI 的 finalizer:
kubectl patch clickhouseinstallations.clickhouse.altinity.com signoz-clickhouse -n signoz --type merge -p '{"metadata":{"finalizers":[]}}',使 CHI 可以立即删除; - 删除 LoadBalancer Service:释放 AWS ELB,避免其在 EKS/VPC 拆除阶段残留;
- 排队删除 PVC(
--wait=false):让 EBS CSI Driver 在集群仍存活时释放 EBS 卷(包括 600Gi 的 ClickHouse 卷),否则集群销毁后这些卷会成为孤儿资源。
每个步骤都具备幂等性与容错性(on_failure = continue、|| exit 0、--ignore-not-found),对全新或部分创建的堆栈来说,这些清理动作只是"无事可做"的空操作。
输出清单与快速参考
部署完成后,模块导出的全部输出如下(见 outputs.tf):
| 输出 | 类型 | 说明 |
|---|---|---|
cluster_name | string | EKS 集群名称 |
cluster_endpoint | string | EKS 集群 API 端点 |
cluster_certificate_authority_data | string | 集群 CA 证书 |
configure_kubectl | string | 配置 kubectl 的命令 |
get_signoz_ui_url | string | 获取 SigNoz UI 地址的命令 |
get_otlp_endpoint | string | 获取 OTLP 端点的命令 |
otel_collector_endpoint | string | 内网 OTLP 端点(hostname:4317),供 Fleet 消费 |
最佳实践小结
结合 README 与源码,SigNoz 负载测试环境的运维要点可归纳为:
- 顺序不可颠倒:SigNoz 必须先于 Fleet 基础设施部署,否则 Fleet 启动阶段的 trace 无法采集;工作区命名必须与 infra 保持一致,远程状态才能正确关联。
- 存储治理要前置:负载测试开始前先调整 Settings → Retention Period 到 1-3 天,并用
clickhouse-client查询system.parts持续监控磁盘水位,避免 ClickHouse 静默拒绝写入导致 trace 缺口。 - OTLP 端点保持内网:
otelCollector.service的 AWS LoadBalancer scheme 被显式设置为internal,这是安全基线,不应移除。 - 资源规格按负载测试规模调优:chart 默认资源远不足以支撑高吞吐遥测,当前配置(ClickHouse 12Gi/24Gi、Collector 3 副本 24Gi/36Gi、600Gi 存储)是经过实践校准的值,调整时需同步评估 EKS 节点规格(m6i.8xlarge)。
- 销毁依赖预清理钩子:
null_resource的 pre-destroy 清理(删 operator、剥离 finalizer、释放 ELB 与 EBS 卷)是避免销毁挂起的必要保障,涉及 SigNoz 版本升级或重建时应保留该逻辑。
通过以上部署与运维流程,即可在 Fleet 负载测试环境中稳定获得端到端的 OpenTelemetry 链路追踪能力,为性能分析与瓶颈定位提供可靠的数据基础。
- 后端
- 前端
- 企业应用
- 运维
- 网络安全
【免费下载链接】fleet
Open device management
相关推荐
Fleet 负载测试环境中的 Percona PMM 部署指南:用 Terraform 在 ECS Fargate 上监控 Aurora MySQL 内部瓶颈
Fleet 负载测试环境中的 Percona PMM 部署指南:用 Terraform 在 ECS Fargate 上监控 Aurora MySQL 内部瓶颈
后端前端企业应用运维网络安全SigNoz最佳实践:生产环境部署与运维指南
SigNoz最佳实践:生产环境部署与运维指南 概述 SigNoz是一款开源的可观测性平台,专为微服务架构设计,提供分布式追踪、日志管理和度量指标等功能。在生产环
可观测性指标监控链路追踪日志分析后端告警如何将 ClickHouse 的指标与查询追踪接入 OpenTelemetry 采集器
如何将 ClickHouse 的指标与查询追踪接入 OpenTelemetry 采集器 如果你已经在运行 ClickHouse 服务器,想让它产生的查询追踪数据
数据库OLAP列式数据库大数据实时分析数据分析
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考