在 Kubernetes 中运行 ELK 堆栈的 Filebeat 不会在日志中捕获 pod 名称

Posted

技术标签:

【中文标题】在 Kubernetes 中运行 ELK 堆栈的 Filebeat 不会在日志中捕获 pod 名称【英文标题】:Filebeat with ELK stack running in Kubernetes does not capture pod name in logs 【发布时间】:2017-08-20 12:10:21 【问题描述】:

我在 Kubernetes (minikube) 环境中使用 ELK 堆栈(elasticsearch、logsash、kibana)进行日志处理和分析。为了捕获日志,我使用了 filebeat。日志成功地从 filebeat 传播到 elasticsearch,并且可以在 Kibana 中查看。

我的问题是我无法获取实际 pod 发出日志记录的 pod 名称。相反,我只得到正在收集日志文件的 filebeat podname,而不是产生日志记录的 pod 的名称。

我可以从 filebeat 获得的信息是(在 Kibana 中查看)

beat.hostname:该字段的值为filebeat pod名称 beat.name: value 是 filebeat pod 名称 host: value 是 filebeat pod 名称

我还可以在 Kibana 中查看/辨别从 filebeat/logstash/elasticsearch 流过的容器信息:

app:值为 log-container-id-json.log 来源:值为/hostfs/var/lib/docker/containers/log-container-id-json.log

如上图,我好像能得到容器的id,但不能得到pod的名字。

为了缓解这种情况,我可能会将 pod-name 嵌入到实际的日志消息中并从那里解析它,但我希望有一个解决方案可以配置 filebeat 以发出实际的 pod 名称。

现在有人如何配置 filebeat(或其他组件)以在他们的日志中捕获 kubernetes (minikube) pod 名称?

我当前的filebeat配置如下:

ConfigMap如下图:

apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat
  namespace: logging
  labels:
    component: filebeat
data:
  filebeat.yml: |
    filebeat.prospectors:

    - input_type: log
      tags:
      - host
      paths:
      - "/hostfs/var/log"
      - "/hostfs/var/log/*"
      - "/hostfs/var/log/*/*"
      exclude_files:
      - '\.[0-9]$'
      - '\.[0-9]\.gz$'

    - input_type: log
      tags:
      - docker
      paths:
      - /hostfs/var/lib/docker/containers/*/*-json.log
      json:
        keys_under_root: false
        message_key: log
        add_error_key: true
      multiline:
        pattern: '^[[:space:]]+|^Caused by:'
        negate: false
        match: after

    output.logstash:
      hosts: ["logstash:5044"]

    logging.level: info

DamemonSet 如下图所示:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: logging
spec:
  template:
    metadata:
      labels:
        component: filebeat
    spec:
      containers:
      - name: filebeat
        image: giantswarm/filebeat:5.2.2
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            cpu: 100m
          requests:
            cpu: 100m
        volumeMounts:
        - name: config
          mountPath: /etc/filebeat
          readOnly: true
        - name: hostfs-var-lib-docker-containers
          mountPath: /hostfs/var/lib/docker/containers
          readOnly: true
        - name: hostfs-var-log
          mountPath: /hostfs/var/log
          readOnly: true
      volumes:
      - name: config
        configMap:
          name: filebeat
      - name: hostfs-var-log
        hostPath:
          path: /var/log
      - name: hostfs-var-lib-docker-containers
        hostPath:
      path: /var/lib/docker/containers

【问题讨论】:

【参考方案1】:

免责声明:我是 Beats 开发者

filebeat 尚不支持您想要做的事情,但毫无疑问,我们希望在这方面付出一些努力,因此您可以期待未来的版本支持这种映射。

同时,我认为您的方法是正确的。您可以将所需的信息附加到日志中,以便在 elasticsearch 中使用

【讨论】:

【参考方案2】:

通过将一组特定的 Pod 分配给一个命名空间,我已经实现了您想要的,现在可以使用命名空间、Pod 名称和容器名称的组合查询我查找的日志,该组合也包含在生成的日志中如您在此处看到的,无需任何额外的努力即可通过文件节拍进行管道传输

【讨论】:

可以分享一下配置吗?【参考方案3】:

对于未来来到这里的人,它现在已经在 filebeat 处理器中到位:

filebeat.prospectors:
  - type: log
    enabled: true
    paths:
      - /var/log/*.log
      - /var/log/messages
      - /var/log/syslog
  - type: docker
    containers.ids:
    - "*"
    processors:
      - add_kubernetes_metadata:
          in_cluster: true
      - drop_event:
          when:
            equals:
              kubernetes.container.name: "filebeat"

舵图默认值:https://github.com/helm/charts/blob/master/stable/filebeat/values.yaml

文档:https://www.elastic.co/guide/en/beats/filebeat/current/add-kubernetes-metadata.html

【讨论】:

以上是关于在 Kubernetes 中运行 ELK 堆栈的 Filebeat 不会在日志中捕获 pod 名称的主要内容,如果未能解决你的问题,请参考以下文章

使用 ELK 堆栈的最佳 Docker 日志记录架构

ELK 堆栈中的 Logstash 和 filebeat

ELK 堆栈和扩展

在 ELK 堆栈中调试 Filebeat

关于使用Spring Boot Microservices设置ELK堆栈

基于弹性堆栈(ELK堆栈)的日志分析存储及展示