痛点:遥测采集组件碎片化,运维成本越来越高
一个典型的可观测性栈,你可能同时跑着:
- Grafana Agent 采集 metrics
- Promtail 收日志发到 Loki
- Grafana Agent Traces 收 traces 转发到 Tempo
- 可能还有 OpenTelemetry Collector 处理 OTLP 数据
每个组件独立配置、独立升级、独立排障。配置格式不统一(YAML、River、TOML 各来一套),监控采集器本身就成了运维负担。
2024 年 4 月,Grafana Labs 正式发布 Alloy —— 一个统一的、OpenTelemetry 原生的遥测采集器,直接替代上面所有组件。Grafana Agent 进入维护模式,官方明确推荐迁移到 Alloy。
如果你正在用 Grafana 生态做可观测性,现在是迁移的最佳时机。
方案:Alloy 是什么,凭什么能统一
Grafana Alloy 的核心设计:
| 特性 | 说明 |
|---|---|
| 统一采集 | Metrics、Logs、Traces、Profiles 四合一,单二进制搞定 |
| Alloy 配置语法 | 基于 HCL 风格的声明式语法(原 River),组件化、可组合、支持条件逻辑 |
| OpenTelemetry 原生 | 内置 OTLP receiver/exporter,兼容 OTel Collector 的 receiver/processor |
| Prometheus 兼容 | 完整支持 prometheus.scrape、服务发现、relabel,配置可一键转换 |
| 内置 UI | 自带 DAG 可视化界面(默认 :12345),实时查看数据流向和组件状态 |
| 集群模式 | 多实例自动分片采集目标,无需外部协调器 |
一句话总结:Alloy = Grafana Agent + Promtail + OTel Collector 的合体,配置更直观,功能更强。
实操:3 步从 Grafana Agent 迁移到 Alloy
第 1 步:安装 Alloy
Debian/Ubuntu:
# 添加 Grafana APT 源(如果已有可跳过)
sudo apt-get install -y apt-transport-https software-properties-common
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
# 安装 Alloy
sudo apt-get update && sudo apt-get install -y alloy
# 验证安装
alloy --version
Docker 方式(推荐测试环境):
docker run -d --name alloy \
-p 12345:12345 \
-p 4317:4317 \
-p 4318:4318 \
-v /etc/alloy:/etc/alloy \
grafana/alloy:latest \
run /etc/alloy/config.alloy
第 2 步:编写 Alloy 配置(同时采集 Metrics + Logs)
创建 /etc/alloy/config.alloy:
// ===== Metrics 采集:替代 Prometheus Agent =====
// 服务发现:抓取本机 node_exporter
prometheus.scrape "node" {
targets = [{
__address__ = "localhost:9100",
}]
forward_to = [prometheus.remote_write.mimir.receiver]
scrape_interval = "15s"
}
// Kubernetes Pod 自动发现(K8s 环境启用)
// prometheus.kubernetes "pods" {
// role = "pod"
// }
// prometheus.scrape "k8s_pods" {
// targets = prometheus.kubernetes.pods.targets
// forward_to = [prometheus.remote_write.mimir.receiver]
// }
// 远程写入到 Mimir / Prometheus
prometheus.remote_write "mimir" {
endpoint {
url = "http://mimir:9009/api/v1/push"
// 如需认证:
// basic_auth {
// username = "admin"
// password = env("MIMIR_PASSWORD")
// }
}
}
// ===== 日志采集:替代 Promtail =====
// 采集本机系统日志
local.file_match "syslog" {
path_targets = [{
__path__ = "/var/log/syslog",
job = "syslog",
host = constants.hostname,
}]
}
loki.source.file "syslog" {
targets = local.file_match.syslog.targets
forward_to = [loki.write.default.receiver]
}
// 采集容器日志(Docker 环境)
// loki.source.docker "containers" {
// host = "unix:///var/run/docker.sock"
// targets = discovery.docker.linux.targets
// forward_to = [loki.write.default.receiver]
// }
// 写入 Loki
loki.write "default" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
// ===== OTLP 接收:替代 OTel Collector =====
otelcol.receiver.otlp "default" {
grpc {
endpoint = "0.0.0.0:4317"
}
http {
endpoint = "0.0.0.0:4318"
}
output {
traces = [otelcol.exporter.otlp.tempo.input]
metrics = [otelcol.exporter.prometheus.mimir.input]
}
}
// Traces 转发到 Tempo
otelcol.exporter.otlp "tempo" {
client {
endpoint = "tempo:4317"
tls {
insecure = true
}
}
}
// OTLP Metrics 转 Prometheus 格式写入
otelcol.exporter.prometheus "mimir" {
forward_to = [prometheus.remote_write.mimir.receiver]
}
配置语法解读:
- 每个 block 是一个组件,通过
forward_to/output连接成 DAG - 组件间解耦,新增采集源只需加 block + 连线,不影响已有配置
- 支持
env()函数引用环境变量,敏感信息不硬编码
第 3 步:启动并验证
# 启动服务
sudo systemctl enable --now alloy
# 检查状态
sudo systemctl status alloy
# 查看日志确认无报错
journalctl -u alloy -f --no-pager | head -50
# 打开内置 UI 查看组件 DAG 和数据流
echo "访问 http://<your-ip>:12345 查看 Alloy UI"
验证数据链路:
# 确认 metrics 正在被抓取
curl -s http://localhost:12345/metrics | grep alloy_component_controller_running_components
# 确认 OTLP 端口可达
curl -s http://localhost:4318/v1/traces -X POST -H "Content-Type: application/json" -d '{}'
# 应返回 200 或 protobuf 相关响应,而非 connection refused
从 Grafana Agent 迁移的快捷方式
如果你已有 Grafana Agent 的 YAML 配置,Alloy 提供一键转换工具:
# 将 Grafana Agent Flow 配置转换为 Alloy 格式
alloy convert --source-format=flow --output=config.alloy agent-config.river
# 将 Grafana Agent Static 配置转换
alloy convert --source-format=static --output=config.alloy agent-config.yaml
# 将 Promtail 配置转换
alloy convert --source-format=promtail --output=promtail.alloy promtail.yaml
# 将 OpenTelemetry Collector 配置转换
alloy convert --source-format=otelcol --output=otel.alloy otel-config.yaml
转换后review 一下生成的配置,大多数场景可以直接使用。
避坑指南
坑 1:配置语法从 River 更名为 Alloy,旧文档别照抄
Alloy 1.0 之前叫 Grafana Agent Flow,用 River 语法。正式发布后语法名改为 Alloy syntax,关键字和结构不变,但文件后缀是 .alloy,不是 .river。搜到的旧教程如果写 grafana-agent run --config.file=xxx.river,需要改用 alloy run config.alloy。
坑 2:集群模式下 target 分片需要显式启用
Alloy 支持多实例自动分片(类似 Prometheus Operator 的 sharding),但需要配置集群 block:
// 启用集群分片
cluster "default" {
enabled = true
// 使用 Kubernetes headless service 发现其他实例
join_addresses = ["alloy-headless.monitoring.svc:7946"]
}
不加这段配置,多副本部署会导致每个实例都抓全量 target,造成重复数据。
坑 3:内存默认无上限,生产环境必须设 limiter
Alloy 默认不限内存,大量采集目标场景下可能 OOM。生产配置必加:
// 全局内存限制,到达 80% 时开始丢弃数据而非 OOM
otelcol.processor.memory_limiter "default" {
check_interval = "1s"
limit = "512MiB" // 根据实际调整
}
同时 systemd unit 中设置 MemoryMax=:
# /etc/systemd/system/alloy.service.d/override.conf
[Service]
MemoryMax=768M
总结
| 维度 | 迁移前(碎片化) | 迁移后(Alloy) |
|---|---|---|
| 组件数 | 3-4 个独立进程 | 1 个二进制 |
| 配置格式 | YAML + River + TOML | 统一 Alloy syntax |
| OTel 支持 | 需额外部署 Collector | 内置原生支持 |
| 排障 | 多处日志交叉排查 | 单一 UI + DAG 可视化 |
| 升级 | 各组件版本矩阵 | 单版本统一发布 |
迁移建议:
- 新项目直接用 Alloy,不要再装 Grafana Agent
- 存量环境用
alloy convert转换配置,逐节点灰度替换 - 生产环境务必配置内存限制 + 集群分片
- 善用内置 UI(:12345)排查数据流向问题
Grafana Agent 已进入维护模式,不再接受新功能。Alloy 是 Grafana 可观测性栈的标准采集层,早迁早受益。