【问题标题】:Filebeat Kubernetes Processor and filteringFilebeat Kubernetes 处理器和过滤
【发布时间】:2018-05-21 10:23:43
【问题描述】:

我正在尝试使用 Filebeat 将我的 K8s pod 日志发送到 Elasticsearch。

我在这里按照在线指南进行操作:https://www.elastic.co/guide/en/beats/filebeat/6.0/running-on-kubernetes.html

一切都按预期工作,但是我想从系统 pod 中过滤掉事件。我更新后的配置如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-prospectors
  namespace: kube-system
  labels:
    k8s-app: filebeat
    kubernetes.io/cluster-service: "true"
data:
  kubernetes.yml: |-
    - type: log
      paths:
        - /var/lib/docker/containers/*/*.log
  multiline.pattern: '^\s'
  multiline.match: after
  json.message_key: log
  json.keys_under_root: true
  processors:
    - add_kubernetes_metadata:
        in_cluster: true
        namespace: ${POD_NAMESPACE}
    - drop_event.when.regexp:
        or:
          kubernetes.pod.name: "weave-net.*"
          kubernetes.pod.name: "external-dns.*"
          kubernetes.pod.name: "nginx-ingress-controller.*"
          kubernetes.pod.name: "filebeat.*"

我试图通过以下方式忽略 weave-netexternal-dnsingress-controllerfilebeat 事件:

- drop_event.when.regexp:
    or:
      kubernetes.pod.name: "weave-net.*"
      kubernetes.pod.name: "external-dns.*"
      kubernetes.pod.name: "nginx-ingress-controller.*"
      kubernetes.pod.name: "filebeat.*"

但它们仍会出现在 Elasticsearch 中。

【问题讨论】:

  • 我使用了另一种效率较低但有效的方法。我的 filebeat 实例将所有数据转发到 logstash 实例,并使用 pod 标签过滤“好”和“坏”日志。如果您有兴趣,我可以发布解决方案作为答案。
  • 是的会很感兴趣!我不确定我目前的方法是最好的......

标签: elasticsearch logging kubernetes kibana filebeat


【解决方案1】:

条件需要是一个列表:

- drop_event.when.regexp:
    or:
      - kubernetes.pod.name: "weave-net.*"
      - kubernetes.pod.name: "external-dns.*"
      - kubernetes.pod.name: "nginx-ingress-controller.*"
      - kubernetes.pod.name: "filebeat.*"

我不确定您的参数顺序是否有效。我的一个工作示例如下所示:

- drop_event:
    when:
      or:
        # Exclude traces from Zipkin
        - contains.path: "/api/v"
        # Exclude Jolokia calls
        - contains.path: "/jolokia/?"
        # Exclude pinging metrics
        - equals.path: "/metrics"
        # Exclude pinging health
        - equals.path: "/health"

【讨论】:

  • 第二个例子看起来有效,谢谢@xeraa
【解决方案2】:

这在 filebeat 6.1.3 中对我有用

        - drop_event.when:
            or:
            - equals:
                kubernetes.container.name: "filebeat"
            - equals:
                kubernetes.container.name: "prometheus-kube-state-metrics"
            - equals:
                kubernetes.container.name: "weave-npc"
            - equals:
                kubernetes.container.name: "nginx-ingress-controller"
            - equals:
                kubernetes.container.name: "weave"

【讨论】:

  • 请注意,如果您想删除所有实例的事件,例如容器名称是最一致和最合适的过滤器变量。 filebeat(与其他答案中的 pod 名称、路径或基于行的正则表达式相比)。
【解决方案3】:

我正在使用另一种方法,即在日志管道中传输的日志数量方面效率较低。

与您的做法类似,我使用守护程序集在我的节点上部署了一个 filebeat 实例。这里没什么特别的,这是我正在使用的配置:

apiVersion: v1
data:
  filebeat.yml: |-
    filebeat.config:
      prospectors:
        # Mounted `filebeat-prospectors` configmap:
        path: ${path.config}/prospectors.d/*.yml
        # Reload prospectors configs as they change:
        reload.enabled: false
      modules:
        path: ${path.config}/modules.d/*.yml
        # Reload module configs as they change:
        reload.enabled: false

    processors:
      - add_cloud_metadata:

    output.logstash:
      hosts: ['logstash.elk.svc.cluster.local:5044']
kind: ConfigMap
metadata:
  labels:
    k8s-app: filebeat
    kubernetes.io/cluster-service: "true"
  name: filebeat-config

这是给探矿者的:

apiVersion: v1
data:
  kubernetes.yml: |-
    - type: log
      paths:
        - /var/lib/docker/containers/*/*.log
      json.message_key: log
      json.keys_under_root: true
      processors:
        - add_kubernetes_metadata:
            in_cluster: true
            namespace: ${POD_NAMESPACE}
kind: ConfigMap
metadata:
  labels:
    k8s-app: filebeat
    kubernetes.io/cluster-service: "true"
  name: filebeat-prospectors

守护进程规范:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  labels:
    k8s-app: filebeat
    kubernetes.io/cluster-service: "true"
  name: filebeat
spec:
  selector:
    matchLabels:
      k8s-app: filebeat
      kubernetes.io/cluster-service: "true"
  template:
    metadata:
      labels:
        k8s-app: filebeat
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - args:
        - -c
        - /etc/filebeat.yml
        - -e
        command:
        - /usr/share/filebeat/filebeat
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        image: docker.elastic.co/beats/filebeat:6.0.1
        imagePullPolicy: IfNotPresent
        name: filebeat
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        securityContext:
          runAsUser: 0
        volumeMounts:
        - mountPath: /etc/filebeat.yml
          name: config
          readOnly: true
          subPath: filebeat.yml
        - mountPath: /usr/share/filebeat/prospectors.d
          name: prospectors
          readOnly: true
        - mountPath: /usr/share/filebeat/data
          name: data
        - mountPath: /var/lib/docker/containers
          name: varlibdockercontainers
          readOnly: true
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      volumes:
      - configMap:
          name: filebeat-config
        name: config
      - hostPath:
          path: /var/lib/docker/containers
          type: ""
        name: varlibdockercontainers
      - configMap:
          defaultMode: 384
          name: filebeat-prospectors
        name: prospectors
      - emptyDir: {}
        name: data

基本上,来自所有容器的所有日志的所有数据都会转发到 logstash,可在服务端点访问:logstash.elk.svc.cluster.local:5044(“elk”命名空间中称为“logstash”的服务)。

为简洁起见,我将只为您提供 logstash 的配置(如果您需要更具体的 kubernetes 帮助,请在 cmets 中询问):

logstash.yml 文件非常基础:

http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline

只是表示我挂载管道配置文件的目录的挂载点,如下:

10-beats.conf: 声明 filebeat 的输入(端口 5044 必须使用名为“logstash”的服务公开)

input {
  beats {
    port => 5044
    ssl => false
  }
}

49-filter-logs.conf: 这个过滤器基本上会丢弃来自没有“elk”标签的 pod 的日志。对于确实具有“elk”标签的 pod,它会保留来自 pod 的“elk”标签中命名的容器的日志。例如,如果一个 Pod 有两个容器,分别称为“nginx”和“python”,放置一个值为“nginx”的标签“elk”只会保留来自 nginx 容器的日志并删除 python 的。日志的类型设置为 Pod 运行所在的命名空间。 这可能不适合所有人(您将在 elasticsearch 中为属于命名空间的所有日志创建一个索引)但它对我有用,因为我的日志是同源的。

filter {
    if ![kubernetes][labels][elk] {
        drop {}
    }
    if [kubernetes][labels][elk] {
        # check if kubernetes.labels.elk contains this container name
        mutate {
          split => { "kubernetes[labels][elk]" => "." }
        }
        if [kubernetes][container][name] not in [kubernetes][labels][elk] {
          drop {}
        }
        mutate {
          replace => { "@metadata[type]" => "%{kubernetes[namespace]}" }
          remove_field => [ "beat", "host", "kubernetes[labels][elk]", "kubernetes[labels][pod-template-hash]", "kubernetes[namespace]", "kubernetes[pod][name]", "offset", "prospector[type]", "source", "stream", "time" ]
          rename => { "kubernetes[container][name]" => "container"  }
          rename => { "kubernetes[labels][app]" => "app"  }
        }
    }
}

配置的其余部分是关于日志解析的,与此上下文无关。 唯一重要的部分是输出:

99-output.conf: 向elasticsearch发送数据:

output {
  elasticsearch {
    hosts => ["http://elasticsearch.elk.svc.cluster.local:9200"]
    manage_template => false
    index => "%{[@metadata][type]}-%{+YYYY.MM.dd}"
    document_type => "%{[@metadata][type]}"
  }
}

希望你明白这里的意思。

这种方法的优点

  • 一旦部署了filebeat和logstash,只要你不需要解析新类型的日志,你不需要更新filebeat和logstash的配置来获取kibana中的新日志。您只需在 pod 模板中添加标签即可。
  • 默认情况下,所有日志文件都会被删除,只要您没有明确放置标签。

这种方法的缺点

  • 来自所有 pod 的所有日志都来自 filebeat 和 logstash,并且仅在 logstash 中被丢弃。这对 logstash 来说是很多工作,并且可能会消耗资源,具体取决于集群中的 pod 数量。

我确信有更好的方法来解决这个问题,但我认为这个解决方案非常方便,至少对于我的用例而言。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-12
    • 2022-11-09
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 2012-06-04
    • 1970-01-01
    相关资源
    最近更新 更多