Target Allocator

Target Allocator(TA)是 OpenTelemetry Operator 的一个可选组件,用于在多个 Collector 实例之间分发 Prometheus targets。它解耦了 Prometheus 的服务发现和指标收集功能,使它们可以独立扩展。通过使用 Target Allocator,Collector 可以管理 Prometheus 指标,而无需安装完整的 Prometheus。

概述

什么是 Target Allocator?

Target Allocator 是一个工具,用于:

  • 分发 Prometheus targets:在多个 Collector 实例之间均匀分发 Prometheus 抓取目标
  • 发现 Prometheus Custom Resources:自动发现 Kubernetes 中的 Prometheus Custom Resources(如 ServiceMonitor、PodMonitor)
  • 提供 HTTP 服务发现:为每个 Collector Pod 提供专用的 HTTP 服务发现配置

为什么需要 Target Allocator?

在 Kubernetes 环境中使用 Prometheus Receiver 时,面临以下挑战:

  1. Target 分发问题:当有多个 Collector 实例时,如何确保每个 target 只被一个 Collector 抓取?
  2. 服务发现复杂性:Prometheus 的服务发现配置需要在每个 Collector 中重复配置
  3. 扩展性问题:增加 Collector 实例时,需要重新配置所有实例

Target Allocator 解决了这些问题:

  • 自动分发:自动在 Collector 实例之间分发 targets
  • 统一管理:在一个地方管理所有 Prometheus 配置
  • 易于扩展:增加 Collector 实例时,自动重新分发 targets

Target Allocator 的优势

  • 解耦服务发现和收集:服务发现和指标收集可以独立扩展
  • 避免重复抓取:确保每个 target 只被一个 Collector 抓取
  • 简化配置:无需在每个 Collector 中配置服务发现
  • 自动发现:自动发现 Kubernetes 中的 Prometheus Custom Resources
  • 动态更新:Target 变化时自动更新分发

核心功能

Target Allocator 提供两个核心功能:

1. Prometheus Targets 分发

Target Allocator 的主要功能是在多个 Collector 实例之间均匀分发 Prometheus targets。这确保了:

  • 负载均衡:每个 Collector 实例负责大致相同数量的 targets
  • 避免重复:每个 target 只被一个 Collector 抓取
  • 动态调整:当 Collector 实例数量变化时,自动重新分发 targets

2. Prometheus Custom Resources 发现

Target Allocator 可以自动发现 Kubernetes 中的 Prometheus Custom Resources:

  • ServiceMonitor:基于 Service 的监控配置
  • PodMonitor:基于 Pod 的监控配置
  • PrometheusRule:Prometheus 告警规则

这些资源由 Prometheus Operator 定义,Target Allocator 可以自动发现并使用它们。

工作原理

架构图

┌─────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Prometheus Custom Resources │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ServiceMonitor│ │ PodMonitor │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Target Allocator │ │
│ │ ┌────────────────────────────────────────────┐ │ │
│ │ │ 1. 发现 Prometheus Custom Resources │ │ │
│ │ │ 2. 解析 scrape_configs │ │ │
│ │ │ 3. 分发 targets 到 Collector 实例 │ │ │
│ │ │ 4. 提供 HTTP SD API │ │ │
│ │ └────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Collector Instances │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │Collector│ │Collector │ │Collector │ │ │
│ │ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │ │
│ │ │Targets: │ │Targets: │ │Targets: │ │ │
│ │ │ 1,4,7 │ │ 2,5,8 │ │ 3,6,9 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

工作流程

  1. Target Allocator 启动:

    • 读取 OpenTelemetryCollector 配置中的 Prometheus receiver 配置
    • 发现 Kubernetes 中的 Prometheus Custom Resources
    • 解析所有 scrape_configs
  2. Target 分发:

    • 收集所有需要抓取的 targets
    • 根据 Collector 实例数量计算每个实例应该负责的 targets
    • 使用一致性哈希算法分发 targets
  3. HTTP SD API:

    • 为每个 Collector Pod 提供专用的 HTTP 服务发现端点
    • Collector Pod 通过 $POD_NAME 标识自己
    • Target Allocator 返回该 Pod 应该抓取的 targets
  4. 动态更新:

    • 当 targets 变化时(新增、删除、修改),自动更新分发
    • 当 Collector 实例数量变化时,自动重新分发

HTTP 服务发现配置

Target Allocator 使用 Prometheus 的 HTTP 服务发现(HTTP SD)机制。当启用 Target Allocator 时,Operator 会自动修改 Collector 配置:

原始配置:

receivers:
prometheus:
config:
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: ['0.0.0.0:8888']

转换后的配置:

receivers:
prometheus:
config:
scrape_configs:
- job_name: otel-collector
scrape_interval: 10s
http_sd_configs:
- url: http://collector-with-ta-targetallocator:80/jobs/otel-collector/targets?collector_id=$POD_NAME

启用 Target Allocator

基本配置

在 OpenTelemetryCollector 资源中启用 Target Allocator:

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: collector-with-ta
spec:
mode: statefulset
targetAllocator:
enabled: true
config: |
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: ['0.0.0.0:8888']
metric_relabel_configs:
- action: labeldrop
regex: (id|name)
replacement: $$1
- action: labelmap
regex: label_(.+)
replacement: $$1
exporters:
debug: {}
service:
pipelines:
metrics:
receivers: [prometheus]
processors: []
exporters: [debug]

配置说明

targetAllocator.enabled

  • 类型:布尔值
  • 默认值:false
  • 说明:启用或禁用 Target Allocator
  • 必需:是

Prometheus Receiver 配置

当启用 Target Allocator 时,需要注意:

  1. 服务发现配置会被替换:

    • static_configs、file_sd_configs 等会被移除
    • 替换为 http_sd_configs 配置
  2. 保留其他配置:

    • scrape_interval、scrape_timeout 等配置会保留
    • metric_relabel_configs 会保留
    • relabel_configs 会保留

完整配置示例

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: collector-with-ta
namespace: observability
spec:
mode: statefulset
replicas: 3
# 启用 Target Allocator
targetAllocator:
enabled: true
# Collector 配置
config: |
receivers:
prometheus:
config:
scrape_configs:
# Job 1: 监控 Collector 自身
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: ['0.0.0.0:8888']
metric_relabel_configs:
- action: labeldrop
regex: (id|name)
replacement: $$1
- action: labelmap
regex: label_(.+)
replacement: $$1
# Job 2: 监控 Kubernetes 服务
- job_name: 'kubernetes-services'
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_name]
action: keep
regex: my-service
- source_labels: [__meta_kubernetes_service_port_name]
action: keep
regex: metrics
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 75
spike_limit_percentage: 15
batch:
timeout: 1s
send_batch_size: 1024
exporters:
otlp:
endpoint: uptrace-grpc.yodao.cn:4317
tls:
insecure: false
service:
pipelines:
metrics:
receivers: [prometheus]
processors: [memory_limiter, batch]
exporters: [otlp]

应用配置

# 应用配置
kubectl apply -f collector-with-ta.yaml
# 检查 Target Allocator 是否创建
kubectl get deployment -n observability | grep targetallocator
# 检查 Target Allocator Pod
kubectl get pods -n observability | grep targetallocator
# 检查 Target Allocator Service
kubectl get svc -n observability | grep targetallocator

配置转换说明

当启用 Target Allocator 时,Operator 会自动转换 Collector 配置。理解这个转换过程对于正确配置很重要。

转换规则

  1. 移除服务发现配置:

    • 移除 static_configs
    • 移除 file_sd_configs
    • 移除 kubernetes_sd_configs
    • 移除其他服务发现配置
  2. 添加 HTTP SD 配置:

    • 为每个 scrape_configs 添加 http_sd_configs
    • URL 格式:http://<ta-service-name>:80/jobs/<job_name>/targets?collector_id=$POD_NAME
  3. 保留其他配置:

    • 保留 scrape_interval、scrape_timeout
    • 保留 metric_relabel_configs、relabel_configs
    • 保留 scheme、metrics_path 等

转换示例

原始配置

receivers:
prometheus:
config:
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: ['0.0.0.0:8888']
metric_relabel_configs:
- action: labeldrop
regex: (id|name)
replacement: $$1

转换后的配置

receivers:
prometheus:
config:
scrape_configs:
- job_name: otel-collector
scrape_interval: 10s
http_sd_configs:
- url: http://collector-with-ta-targetallocator:80/jobs/otel-collector/targets?collector_id=$POD_NAME
metric_relabel_configs:
- action: labeldrop
regex: (id|name)
replacement: $$1

查看实际配置

可以通过以下方式查看 Operator 转换后的实际配置:

# 查看 Collector ConfigMap
kubectl get configmap <collector-name>-collector -n <namespace> -o yaml
# 或查看 Collector Pod 的环境变量
kubectl exec <collector-pod-name> -n <namespace> -- env | grep OTEL_CONFIG

高级配置

Target Allocator 资源配置

可以自定义 Target Allocator 的资源请求和限制:

spec:
targetAllocator:
enabled: true
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi

Target Allocator 副本数

默认情况下,Target Allocator 以单副本 Deployment 运行。如果需要高可用,可以配置多个副本:

spec:
targetAllocator:
enabled: true
replicas: 2

注意:多个 Target Allocator 实例会共享配置,但每个 Collector Pod 仍然只从一个 Target Allocator 获取 targets。

自定义 Target Allocator 镜像

spec:
targetAllocator:
enabled: true
image: ghcr.io/open-telemetry/opentelemetry-operator/target-allocator:v0.100.0

环境变量配置

为 Target Allocator 添加环境变量:

spec:
targetAllocator:
enabled: true
env:
- name: LOG_LEVEL
value: debug
- name: ALLOCATOR_STRATEGY
value: consistent-hashing

Prometheus Custom Resources 发现

Target Allocator 可以自动发现 Prometheus Custom Resources。确保已安装 Prometheus Operator:

# 检查 Prometheus Operator
kubectl get crd | grep prometheus
# 应该看到:
# - servicemonitors.monitoring.coreos.com
# - podmonitors.monitoring.coreos.com
# - prometheusrules.monitoring.coreos.com

创建 ServiceMonitor 示例:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: my-service-monitor
namespace: observability
spec:
selector:
matchLabels:
app: my-app
endpoints:
- port: metrics
interval: 30s
path: /metrics

Target Allocator 会自动发现这个 ServiceMonitor 并创建相应的 scrape_configs。

实战示例

示例 1:监控 Kubernetes 服务

1. 创建 ServiceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-metrics
namespace: production
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
endpoints:
- port: metrics
interval: 30s
path: /metrics

2. 配置 Collector 使用 Target Allocator

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: collector-with-ta
namespace: observability
spec:
mode: statefulset
replicas: 3
targetAllocator:
enabled: true
config: |
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'kubernetes-services'
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_app]
action: keep
regex: my-app
exporters:
otlp:
endpoint: uptrace-grpc.yodao.cn:4317
service:
pipelines:
metrics:
receivers: [prometheus]
exporters: [otlp]

3. 验证

# 检查 Target Allocator 是否发现 targets
kubectl logs -l app.kubernetes.io/name=target-allocator -n observability | grep targets
# 检查 Collector 是否正在抓取
kubectl logs -l app.kubernetes.io/name=opentelemetry-collector -n observability | grep prometheus

示例 2:监控多个应用

1. 创建多个 ServiceMonitor

# ServiceMonitor 1
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: frontend-metrics
namespace: production
spec:
selector:
matchLabels:
app: frontend
endpoints:
- port: metrics
interval: 30s
---
# ServiceMonitor 2
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: backend-metrics
namespace: production
spec:
selector:
matchLabels:
app: backend
endpoints:
- port: metrics
interval: 30s

2. 配置 Collector

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: collector-with-ta
namespace: observability
spec:
mode: statefulset
replicas: 3
targetAllocator:
enabled: true
config: |
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'frontend'
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_app]
action: keep
regex: frontend
- job_name: 'backend'
kubernetes_sd_configs:
- role: service
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_app]
action: keep
regex: backend
exporters:
otlp:
endpoint: uptrace-grpc.yodao.cn:4317
service:
pipelines:
metrics:
receivers: [prometheus]
exporters: [otlp]

示例 3:使用静态配置

即使使用 Target Allocator,也可以使用静态配置:

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: collector-with-ta
spec:
mode: statefulset
targetAllocator:
enabled: true
config: |
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'static-targets'
scrape_interval: 10s
static_configs:
- targets:
- 'external-service-1:9090'
- 'external-service-2:9090'
- 'external-service-3:9090'
exporters:
otlp:
endpoint: uptrace-grpc.yodao.cn:4317
service:
pipelines:
metrics:
receivers: [prometheus]
exporters: [otlp]

Target Allocator 会将静态 targets 分发到各个 Collector 实例。

故障排查

1. Target Allocator 无法启动?

检查步骤:

# 检查 Target Allocator Pod 状态
kubectl get pods -l app.kubernetes.io/name=target-allocator -n <namespace>
# 查看 Target Allocator 日志
kubectl logs -l app.kubernetes.io/name=target-allocator -n <namespace>
# 检查 Target Allocator Service
kubectl get svc -l app.kubernetes.io/name=target-allocator -n <namespace>

常见原因:

  • 配置错误
  • 资源不足
  • 镜像拉取失败

2. Collector 无法从 Target Allocator 获取 targets?

检查步骤:

# 检查 Collector Pod 日志
kubectl logs <collector-pod-name> -n <namespace> | grep -i "http_sd\|target"
# 检查 Target Allocator HTTP SD 端点
kubectl exec <collector-pod-name> -n <namespace> -- \
curl http://<ta-service-name>:80/jobs/<job_name>/targets?collector_id=<pod-name>
# 检查网络连接
kubectl exec <collector-pod-name> -n <namespace> -- \
ping <ta-service-name>

常见原因:

  • Target Allocator Service 未创建
  • 网络策略阻止连接
  • Target Allocator 未发现 targets

3. Targets 未分发?

检查步骤:

# 检查 Target Allocator 日志
kubectl logs -l app.kubernetes.io/name=target-allocator -n <namespace> | grep -i "target\|allocation"
# 检查 Collector 配置
kubectl get configmap <collector-name>-collector -n <namespace> -o yaml
# 检查 Prometheus Custom Resources
kubectl get servicemonitor -n <namespace>
kubectl get podmonitor -n <namespace>

常见原因:

  • Prometheus Custom Resources 未创建
  • Target Allocator 未发现 Custom Resources
  • 配置解析错误

4. 如何查看 Target Allocator 分发的 targets?

方法 1:通过 HTTP API

# 获取 Target Allocator Service 名称
TA_SERVICE=$(kubectl get svc -l app.kubernetes.io/name=target-allocator -n <namespace> -o jsonpath='{.items[0].metadata.name}')
# 查询特定 job 的所有 targets
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- \
curl http://$TA_SERVICE:80/jobs/<job_name>/targets
# 查询特定 Collector Pod 的 targets
COLLECTOR_POD=$(kubectl get pod -l app.kubernetes.io/name=opentelemetry-collector -n <namespace> -o jsonpath='{.items[0].metadata.name}')
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- \
curl "http://$TA_SERVICE:80/jobs/<job_name>/targets?collector_id=$COLLECTOR_POD"

方法 2:查看 Target Allocator 日志

kubectl logs -l app.kubernetes.io/name=target-allocator -n <namespace> | grep -i target

5. Target Allocator 发现不了 Prometheus Custom Resources?

检查步骤:

# 检查 Prometheus Operator 是否安装
kubectl get crd | grep prometheus
# 检查 ServiceMonitor/PodMonitor 是否存在
kubectl get servicemonitor -A
kubectl get podmonitor -A
# 检查 Target Allocator 日志
kubectl logs -l app.kubernetes.io/name=target-allocator -n <namespace> | grep -i "discover\|service\|pod"

解决方法:

  • 确保已安装 Prometheus Operator
  • 确保 ServiceMonitor/PodMonitor 的标签选择器正确
  • 检查 Target Allocator 的权限配置

详细故障排查请参考 故障排查文档。

最佳实践

1. 合理设置 Collector 副本数

  • 根据 targets 数量设置合理的副本数
  • 每个 Collector 实例负责的 targets 数量建议在 50-200 之间
  • 使用 HPA 自动调整副本数

2. 使用 Prometheus Custom Resources

  • 优先使用 ServiceMonitor 和 PodMonitor
  • 避免在 Collector 配置中硬编码 targets
  • 利用 Kubernetes 的标签选择器进行动态发现

3. 监控 Target Allocator

  • 监控 Target Allocator 的 CPU 和内存使用
  • 监控 Target Allocator 的日志
  • 设置告警规则

4. 配置资源限制

为 Target Allocator 配置合理的资源限制:

targetAllocator:
enabled: true
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi

5. 使用版本固定的镜像

避免使用 latest 标签:

targetAllocator:
enabled: true
image: ghcr.io/open-telemetry/opentelemetry-operator/target-allocator:v0.100.0

6. 测试 Target 分发

在部署到生产环境之前,测试 Target Allocator 的分发逻辑:

  • 创建测试 targets
  • 验证 targets 是否正确分发
  • 验证 Collector 是否能够抓取 targets

常见问题

1. Target Allocator 和 Prometheus 的区别?

  • Prometheus:完整的监控系统,包含存储、查询、告警等功能
  • Target Allocator:只负责分发 targets,不存储数据
  • Collector:负责抓取指标并导出到后端系统

2. 可以同时使用 Target Allocator 和直接配置吗?

可以,但 Target Allocator 会优先处理 Prometheus receiver 的配置。如果需要在某些 job 中禁用 Target Allocator,需要单独配置。

3. Target Allocator 支持哪些服务发现方式?

Target Allocator 支持所有 Prometheus 支持的服务发现方式,包括:

  • static_configs
  • kubernetes_sd_configs
  • file_sd_configs
  • 以及通过 Prometheus Custom Resources 发现

4. 如何调试 Target Allocator?

# 启用调试日志
kubectl set env deployment/<ta-deployment> LOG_LEVEL=debug -n <namespace>
# 查看详细日志
kubectl logs -l app.kubernetes.io/name=target-allocator -n <namespace> --tail=100 -f

5. Target Allocator 的性能如何?

Target Allocator 的性能通常很好:

  • CPU 使用:< 100m(正常情况)
  • 内存使用:< 128Mi(正常情况)
  • 响应时间:< 100ms(HTTP SD API)

如果发现性能问题,可以:

  • 增加 Target Allocator 的资源限制
  • 减少 targets 数量
  • 优化 Prometheus Custom Resources 配置

下一步

参考资源

在Gitlab上编辑本文档