4. 日志采集架构:Promtail与Alloy配置,多环境(蓝/绿)日志标签设计
在蓝绿发布场景下,日志采集架构面临的核心挑战是:如何将同一套应用代码在不同环境(蓝/绿)中产生的日志流,准确、隔离、可追溯地写入Loki。Promtail 和 Grafana Alloy 是两种主流的采集器,本章将深入讲解它们的配置差异、多环境标签设计原则以及生产级部署要点。
4.1 采集器选型:Promtail vs Alloy
| 对比维度 | Promtail | Grafana Alloy |
|---|---|---|
| 定位 | Loki 原生日志采集器,轻量、专注 | 统一可观测性采集器(日志+指标+链路) |
| 配置语言 | YAML,结构简单 | River(声明式),支持更复杂的处理管道 |
| 日志处理 | 支持 pipeline stages(正则、json、template) | 支持 stages + 更丰富的转换和过滤 |
| 多环境支持 | 通过文件发现 + 标签重写实现 | 内置服务发现 + 标签动态注入 |
| 资源占用 | 低(约 10-30MB 内存) | 中等(约 50-100MB 内存,含多管道) |
| 适用场景 | 纯日志采集,Kubernetes DaemonSet 部署 | 需要同时采集 metrics/traces 的融合场景 |
选型建议: 如果团队仅关注日志治理,且集群规模较大(>100 节点),优先使用 Promtail 以降低资源开销;如果正在构建统一可观测性平台,Alloy 的单一 Agent 模式能减少运维复杂度。
4.2 多环境标签设计原则
蓝绿发布的核心标签设计必须满足:隔离性(蓝/绿日志不混淆)、可追溯性(能快速定位某次发布的日志)、可聚合性(支持跨环境全局查询)。
推荐标签结构如下:
# 强制标签(由采集器注入,不可被应用覆盖)
__meta_kubernetes_namespace: production
__meta_kubernetes_pod_name: api-blue-v1-7d8f9c
# 业务标签(用于查询和聚合)
env: blue # 环境标识:blue / green
release_id: v1.2.3 # 发布版本号
deployment_strategy: blue-green # 发布策略标识
service: api-gateway # 服务名
team: platform # 归属团队
避坑指南: 不要将 Pod 名称或 IP 作为唯一标签,否则会导致 Loki 索引爆炸。始终使用
env + service 作为主标签组合,Pod 信息通过 __meta_ 前缀保留在元数据中。
4.3 Promtail 配置实战:蓝绿环境日志采集
以下配置展示了如何在 Promtail 中通过 relabel_configs 动态注入蓝绿标签:
# promtail-config.yaml
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
# 保留原始命名空间和 Pod 名
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
# 关键:从 Pod 标签中提取 env 和 release
- source_labels: [__meta_kubernetes_pod_label_env]
target_label: env
action: replace
- source_labels: [__meta_kubernetes_pod_label_release_id]
target_label: release_id
action: replace
# 丢弃不需要的元数据标签,减少存储开销
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- action: drop
regex: __meta_kubernetes_pod_annotation_.+
pipeline_stages:
- cri: {} # 解析 CRI 日志格式
- regex:
expression: '^(?P<level>\w+)\s+(?P<message>.*)$'
- labels:
level: # 将日志级别提取为标签
4.4 Alloy 配置实战:融合采集与标签注入
Alloy 使用 River 语法,支持更灵活的管道组合。以下配置实现蓝绿日志采集并自动添加环境标签:
// alloy-config.river
local.file_match "logs" {
path_targets = ["/var/log/pods/*/*/*.log"]
}
loki.source.file "application" {
targets = local.file_match.logs.targets
forward_to = [loki.process.add_env_labels.receiver]
// 从文件路径解析命名空间和 Pod 名
encoding = "utf-8"
}
loki.process "add_env_labels" {
forward_to = [loki.write.default.receiver]
stage.regex {
expression = "^(?P<namespace>[^_]+)_(?P<pod>[^_]+)_.*$"
source = "filename"
}
stage.labels {
values = {
env = "blue", // 静态注入,实际应从环境变量读取
service = "api",
namespace = "",
pod = "",
}
}
stage.static_labels {
deployment_strategy = "blue-green"
}
}
loki.write "default" {
endpoint {
url = "http://loki-gateway:3100/loki/api/v1/push"
}
}
关键差异: Alloy 的
stage.static_labels 可以注入固定标签(如部署策略),而 Promtail 依赖 relabel_configs 的静态替换。Alloy 的管道式处理更适合复杂的数据清洗场景。
4.5 蓝绿环境标签设计架构图
下图展示了从 Pod 日志产生到 Loki 存储的完整标签注入链路:
4.6 标签设计检查清单
- 必选标签:
env(blue/green)、service、namespace、release_id - 可选标签:
team、deployment_strategy、cluster - 禁止作为标签: Pod IP、容器 ID、时间戳、随机 UUID
- 标签值规范: 统一小写,使用连字符(
-)而非下划线,长度不超过 64 字符 - 标签数量控制: 每个日志流不超过 10 个标签,避免索引膨胀
生产建议: 在 Promtail 或 Alloy 的配置中,使用
action: keep 或 stage.drop 显式丢弃不需要的元数据标签。例如,丢弃 __meta_kubernetes_pod_annotation_* 可以显著减少 Loki 的索引大小。
4.7 多环境日志查询示例
完成标签设计后,在 Grafana Explore 中可以使用以下 LogQL 查询快速定位:
# 查询蓝环境所有服务的错误日志
{env="blue"} |= "ERROR"
# 查询某次发布版本的蓝环境日志
{env="blue", release_id="v1.2.3"}
# 对比蓝绿环境的请求延迟(需结合日志中的 duration 字段)
rate({env="blue", service="api-gateway"} | json | duration > 1s [5m])
/
rate({env="green", service="api-gateway"} | json | duration > 1s [5m])
通过上述标签设计,蓝绿环境的日志在 Loki 中实现了物理隔离(不同标签组合对应不同流)和逻辑关联(通过 service 标签可跨环境聚合),为后续的日志治理与压缩优化奠定了坚实基础。