Skip to content

K8s Alloy 采集 Pod 控制台日志

1d2d6e59-d559-42d8-bff0-750e0e613033

1. 目标架构

Readme

Loki 的集群在k8s集群外部,不在k8s 内部,关于 Loki 的部署可参考:https://opforge.srebro.cn/project/log/loki/01.html

K8s 集群内部署 Alloy DaemonSet,每个节点一个 Alloy Pod。Alloy 通过 Kubernetes API 采集本节点 Pod 的 stdout/stderr 控制台日志,然后推送到集群外现有 Loki Gateway。

整体架构图

2. 部署前确认

确认 K8s 节点或 Pod 网络能访问你的 Loki Gateway:

bash
kubectl run curl-test -n default --rm -it --image=curlimages/curl -- \
  curl -v http://192.168.1.100:3100/ready

如果 Loki Gateway 有防火墙或安全组,需要放通 K8s Pod 网段或 Node 网段到 3100 端口。

3. 当前 YAML 里的关键配置

alloy-k8s-loki-logs.yaml文件在,https://cnb.cool/sre-demo/k8s-demo/-/blob/main/yaml/v1.32/loki/alloy-k8s-loki-logs.yaml

当前 alloy-k8s-loki-logs.yaml 已经按本环境配置好:

text
Loki Gateway: 192.168.1.100:3100
Loki push URL: http://192.168.1.100:3100/loki/api/v1/push
Tenant: tenant1
Cluster label: xxx-k8s

对应 Alloy 配置:

alloy
loki.write "default" {
  endpoint {
    url       = "http://192.168.1.100:3100/loki/api/v1/push"
    tenant_id = "tenant1"
  }
}

集群标签配置:

alloy
stage.static_labels {
  values = {
    cluster  = "xxx-k8s",
    platform = "kubernetes",
    agent    = "alloy",
  }
}

说明:

  • cluster="xxx-k8s" 用来区分这批日志来自当前 K8s 集群。
  • tenant_id="tenant1" 需要和 Grafana Loki 数据源里的 X-Scope-OrgID 保持一致。
  • 如果未来接入多个 K8s 集群,可以给不同集群设置不同 cluster 标签,例如 prod-k8stest-k8s

4. 部署 Alloy

执行:

bash
kubectl apply -f alloy-k8s-loki-logs.yaml

查看 DaemonSet:

bash
kubectl -n monitoring get ds alloy
kubectl -n monitoring get pod -l app.kubernetes.io/name=alloy -o wide

每个 K8s 节点应该有一个 Alloy Pod。

5. 查看 Alloy 运行日志

bash
kubectl -n monitoring logs -l app.kubernetes.io/name=alloy --tail=100 -f

如果配置正确,通常能看到 discovery、tail pod logs、push Loki 的相关日志。

6. 验证 Loki 是否收到日志

在 Grafana Explore 里选择 Loki 数据源,查询:

logql
{cluster="xxx-k8s", platform="kubernetes"}

按命名空间查询:

logql
{cluster="xxx-k8s", namespace="default"}

按 Java 微服务查询:

logql
{cluster="xxx-k8s", app="your-java-service"}

按日志级别查询:

logql
{cluster="xxx-k8s", level="ERROR"}

按命名空间、服务和日志级别组合查询:

logql
{cluster="xxx-k8s", namespace="xxx", app="srebro-uc", level="INFO"}

如果你的 Pod 没有 appapp.kubernetes.io/name 标签,可以先用:

logql
{cluster="xxx-k8s"} |~ "关键字"

image-20260615095904582

8. level 标签说明

K8s 采集的是 Pod 控制台输出,没有这种文件目录结构,所以 level 需要从日志正文里解析。当前 YAML 在 loki.process "pod_logs" 里配置了:

alloy
stage.regex {
  expression         = "(?i)\\b(?P<level>TRACE|DEBUG|INFO|WARN|WARNING|ERROR|FATAL)\\b"
  labels_from_groups = true
}

只要 Java 控制台日志里出现以下关键字,就会生成对应的 Loki 标签:

text
TRACE
DEBUG
INFO
WARN
WARNING
ERROR
FATAL

例如日志正文:

text
2026-06-11 16:30:00.123 INFO  [srebro-uc] user login success
2026-06-11 16:31:00.456 ERROR [srebro-uc] call remote service failed

会被打上:

text
level="INFO"
level="ERROR"

注意:level 标签只会对修改 Alloy 配置后新采集的日志生效,历史日志不会自动补标签。

9. app 标签说明

传统部署里,app 是从日志文件路径第一级目录提取的:

alloy
rule {
  source_labels = ["__path__"]
  regex         = "/home/application/logs/([^/]+)/[^/]+/.*\\.log"
  target_label  = "app"
  replacement   = "$1"
}

K8s 采集 Pod 控制台日志时没有这种日志目录结构,所以当前配置改为从 Deployment 名称提取 app 标签。

Deployment 创建 Pod 的链路通常是:

text
Deployment: srebro-uc
  -> ReplicaSet: srebro-uc-6dccfd4db
  -> Pod: srebro-uc-6dccfd4db-l2zsv

当前 Alloy 配置使用 Pod 的 controller 元数据,把 ReplicaSet 名里的最后一段 hash 去掉:

alloy
rule {
  source_labels = ["__meta_kubernetes_pod_controller_kind", "__meta_kubernetes_pod_controller_name"]
  regex         = "ReplicaSet;(.+)-[a-f0-9]{8,10}"
  action        = "replace"
  target_label  = "app"
  separator     = ";"
  replacement   = "$1"
}

这样最终会得到:

text
app="srebro-uc"

同时保留了 workload 标签,用于查看原始 controller 名称:

text
workload="srebro-uc-6dccfd4db"

如果未来有非 Deployment 类型的工作负载,例如 StatefulSet 或 Job,可以按同样思路增加对应规则。

可选:仍然建议给 Java 微服务 Deployment 增加标准标签,方便 K8s 资源管理和其他监控系统识别:

yaml
metadata:
  labels:
    app.kubernetes.io/name: order-service
    app.kubernetes.io/part-of: business-platform
spec:
  template:
    metadata:
      labels:
        app.kubernetes.io/name: order-service
        app.kubernetes.io/part-of: business-platform

这样 Grafana 查询会更稳定:

logql
{cluster="xxx-k8s", namespace="prod", app="order-service"}

10. 排除不想采集的 Pod

当前 YAML 支持通过注解排除采集。给 Pod template 加:

yaml
metadata:
  annotations:
    loki.grafana.com/scrape: "false"

例如某个 Deployment:

yaml
spec:
  template:
    metadata:
      annotations:
        loki.grafana.com/scrape: "false"
最近更新

采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 运维小弟