4. 日志采集器配置:Promtail安装、scrape_configs详解、静态与动态服务发现

日志采集是Loki可观测性管道的起点。Promtail作为Loki官方推荐的日志采集器,负责从各类目标中抓取日志、添加标签并推送至Loki。本章将深入讲解Promtail的安装部署、核心配置结构以及服务发现机制,帮助你在发布工程自助门户中构建可靠、可扩展的日志采集层。

4.1 Promtail安装与部署

Promtail以单一二进制文件分发,支持多种安装方式。在生产环境中,推荐使用Systemd或容器化部署以确保进程保活与资源隔离。

安装方式 适用场景 关键命令/步骤
二进制直接部署 物理机/虚拟机 wget 下载 → tar -xzf 解压 → 复制到 /usr/local/bin
Systemd服务 生产环境长期运行 编写 .service 单元文件,配置 ExecStart、Restart=always
Docker容器 容器化基础设施 docker run -v /var/log:/var/log grafana/promtail
Kubernetes DaemonSet K8s集群节点日志 使用官方Helm Chart或自定义DaemonSet YAML
最佳实践:在发布工程自助门户中,建议为Promtail单独创建系统用户 promtail,并确保其对日志文件拥有 r 权限,对日志目录拥有 rx 权限。避免以root身份运行。

4.2 scrape_configs 配置结构详解

Promtail的核心配置位于 scrape_configs 块中,它定义了“从哪采集、如何发现、如何转换标签”。每个配置项都是一个独立的job,包含以下关键字段:

字段 类型 说明 示例值
job_name string 任务名称,用于标识和标签 nginx-access
static_configs list 静态目标列表,直接指定文件路径 targets: [localhost]
file_sd_configs list 基于文件的服务发现 files: ['/etc/promtail/targets/*.json']
kubernetes_sd_configs list Kubernetes服务发现 role: pod
relabel_configs list 标签重写规则,用于过滤、修改、创建标签 source_labels: ['__meta_kubernetes_pod_label_app']
pipeline_stages list 日志处理流水线,可进行解析、转换、过滤 regex, json, timestamp

以下是一个典型的 scrape_configs 配置示例,采集Nginx访问日志并添加静态标签:

scrape_configs:
  - job_name: nginx-access
    static_configs:
      - targets:
          - localhost
        labels:
          job: nginx
          env: production
          __path__: /var/log/nginx/access.log
    relabel_configs:
      - source_labels: ['__path__']
        target_label: 'logfile'
        replacement: '$1'
    pipeline_stages:
      - regex:
          expression: '^(?P<remote_addr>\S+) - - \[(?P<time_local>[^\]]+)\] "(?P<request>[^"]*)" (?P<status>\d+) (?P<body_bytes_sent>\d+)'
      - timestamp:
          source: time_local
          format: '02/Jan/2006:15:04:05 -0700'
关键点:__path__ 是Promtail的特殊标签,用于指定日志文件的Glob路径模式。支持通配符如 /var/log/*.log 或递归 /var/log/**/*.log。

4.3 静态服务发现 vs 动态服务发现

服务发现决定了Promtail如何获取日志目标列表。静态发现适用于固定路径,动态发现则适应弹性伸缩的云原生环境。

特性 静态服务发现 动态服务发现
配置方式 直接在 static_configs 中写死路径 通过文件、API、K8s等外部源动态获取
变更响应 需重启Promtail或重载配置 自动感知目标变化,无需重启
适用场景 传统VM、固定日志路径、测试环境 Kubernetes、自动扩缩容、容器化应用
配置复杂度 低,适合快速上手 中高,需理解发现机制和标签元数据
运维成本 手动维护目标列表,易出错 自动化管理,减少人工干预

以下SVG图展示了静态发现与动态发现在采集流程中的位置差异:

静态与动态服务发现对比流程 静态 vs 动态服务发现流程对比 静态服务发现 static_configs 写死路径 变更需重启/重载 采集固定日志文件 动态服务发现 file_sd / k8s_sd 动态获取 自动感知目标变化 采集弹性伸缩日志 VS 选择建议 静态发现:固定路径、少量节点、传统环境 动态发现:K8s集群、自动扩缩容、大规模部署

4.4 基于文件的服务发现(file_sd_configs)

文件服务发现是静态与动态之间的折中方案。Promtail定期读取指定目录下的JSON或YAML文件,文件内容包含目标列表和标签。当文件内容变化时,Promtail自动更新采集目标。

文件格式示例(/etc/promtail/targets/nginx.json):

[
  {
    "targets": ["localhost"],
    "labels": {
      "job": "nginx",
      "env": "staging",
      "__path__": "/var/log/nginx/staging/*.log"
    }
  },
  {
    "targets": ["localhost"],
    "labels": {
      "job": "nginx",
      "env": "production",
      "__path__": "/var/log/nginx/production/*.log"
    }
  }
]

配置引用方式:

scrape_configs:
  - job_name: nginx-file-sd
    file_sd_configs:
      - files:
          - '/etc/promtail/targets/*.json'
        refresh_interval: 30s
注意:refresh_interval 控制文件检查频率,默认5分钟。在发布工程自助门户中,建议设置为30秒以平衡实时性与IO开销。文件内容变更时,Promtail不会重启,仅重新加载目标列表。

4.5 Kubernetes服务发现(kubernetes_sd_configs)

在Kubernetes环境中,Promtail通常以DaemonSet方式运行在每个节点上,通过K8s API自动发现Pod、Service、Node等资源,并采集其日志。这是发布工程自助门户中日志采集的核心模式。

关键配置参数:

参数 说明 常用值
role 发现角色:pod/service/node/endpoints/ingress pod
selectors 标签选择器,过滤目标 role: pod, label: app=nginx
namespaces 限定命名空间 names: ['production', 'staging']

以下是一个完整的K8s服务发现配置示例,采集所有带有 app=nginx 标签的Pod日志:

scrape_configs:
  - job_name: kubernetes-pods
    kubernetes_sd_configs:
      - role: pod
        selectors:
          - role: pod
            label: 'app=nginx'
    relabel_configs:
      - action: keep
        source_labels: ['__meta_kubernetes_pod_label_app']
        regex: 'nginx'
      - action: replace
        source_labels: ['__meta_kubernetes_pod_name']
        target_label: 'pod'
      - action: replace
        source_labels: ['__meta_kubernetes_namespace']
        target_label: 'namespace'
      - action: replace
        source_labels: ['__meta_kubernetes_pod_container_name']
        target_label: 'container'
      - action: replace
        source_labels: ['__meta_kubernetes_pod_node_name']
        target_label: 'node'
      - action: replace
        replacement: '/var/log/pods/*$1/*.log'
        source_labels: ['__meta_kubernetes_pod_uid', '__meta_kubernetes_pod_container_name']
        separator: '/'
        target_label: '__path__'
元数据标签:K8s服务发现会注入大量 __meta_kubernetes_* 标签,如 __meta_kubernetes_pod_label_app、__meta_kubernetes_namespace 等。通过 relabel_configs 可以将这些元数据转换为最终日志标签,实现多维度的日志检索。

4.6 标签重写(relabel_configs)实战

标签重写是Promtail配置中最灵活、也最容易出错的部分。它决定了日志最终携带哪些标签,直接影响Loki的查询效率和存储成本。

常用动作(action)说明:

动作 作用 示例
keep 保留匹配规则的目标,删除不匹配的 只保留 app=nginx 的Pod
drop 删除匹配规则的目标 排除 namespace=default 的日志
replace 替换或创建标签 将 __meta_* 转为业务标签
labelmap 复制匹配的标签到新标签 将 __meta_kubernetes_pod_label_* 映射为 label_*
labeldrop 删除匹配的标签 删除所有 __meta_* 临时标签

以下SVG图展示了标签重写在Promtail采集流水线中的位置与作用:

Promtail标签重写流水线 Promtail标签重写流水线 服务发现 获取原始目标 relabel_configs keep/drop/replace 标签过滤与转换 pipeline_stages 日志解析/转换 提取时间戳/字段 推送Loki 携带最终标签 标签重写最佳实践 1. 优先使用 keep 过滤无关目标,减少采集压力 2. 使用 labelmap 保留K8s标签,便于按应用/环境检索 3. 避免高基数标签(如Pod IP、请求ID)直接作为Loki标签 ⚠ 高基数标签警告 避免将 pod、container_id 等作为Loki索引标签

4.7 发布工程自助门户中的配置实践

在发布工程自助门户中,日志采集配置需要兼顾灵活性、安全性和可观测性。以下是经过生产验证的配置建议:

  • 统一标签规范:所有日志至少携带 job、env、service、host 四个标签,便于全局检索。
  • 使用文件服务发现管理非K8s目标:将目标列表写入JSON文件,由CMDB或发布系统自动更新,避免手动修改Promtail配置。
  • K8s环境启用 selectors:只采集带有特定标签的Pod,减少API调用和内存占用。
  • 配置 pipeline_stages 进行日志结构化:使用 regex 或 json 解析器提取关键字段,降低Loki查询时的解析开销。
  • 设置合理的 scrape_timeout 和 scrape_interval:默认10s采集间隔适用于大多数场景,对于高吞吐日志可缩短至5s。
故障排查提示:当Promtail无法采集日志时,首先检查 __path__ 通配符是否匹配实际文件路径。使用 promtail --dry-run 可以预览采集结果和标签,是调试配置的利器。