首页
学习
活动
专区
圈层
工具
发布
43 篇文章
1
干货 | Elasitcsearch7.X集群/索引备份与恢复实战
2
干货 | Elasticsearch 运维实战常用命令清单
3
腾讯云Elasticsearch集群运维常用命令详解一(集群篇)
4
腾讯云Elasticsearch集群运维常用命令详解二(节点篇)
5
腾讯云Elasticsearch集群运维常用命令详解三(索引篇)
6
如何系统的学习 Elasticsearch ?
7
Elasitcsearch 开发运维常用命令集锦
8
Elasticsearch集群数据备份与恢复 Snapshot & Restore
9
搭建ELFK日志采集系统
10
Kubernetes Helm3 部署 ElasticSearch & Kibana 7 集群
11
使用 Ansible 部署 Elasticsearch 集群
12
技术角 | 在CentOS 8上使用Elastic Stack: Elasticsearch/Kibana 7.8部署与认证配置
13
在CentOS 8上使用Elastic Stack: Elasticsearch/Kibana 7.8的部署与认证配置
14
Elasticsearch 生产环境集群部署最佳实践
15
ES 7.8 速成笔记(中)
16
ES 7.8 速成笔记(上)
17
如何在CentOS 7上设置生产Elasticsearch集群
18
kubernetes-2:helm实战-1:生产级别的elasticsearch集群部署
19
ElasticSearch 7集群部署
20
在CentOS 7安装ElasticSearch 7.x
21
zabbix 监控 es 集群
22
ELK 日志报警插件 ElastAlert
23
Elasticsearch集群规划最佳实践
24
kubernetes-7:elasticsearch容器化
25
Go Elasticsearch 增删改查(CRUD)快速入门
26
go操作elasticsearch示例
27
在 Kubernetes 上搭建 EFK 日志收集系统
28
一文彻底搞定 EFK 日志收集系统
29
TKE上搭建EFK日志采集系统
30
使用 EFKLK 搭建 Kubernetes 日志收集工具栈
31
腾讯云Elasticsearch集群规划及性能优化实践
32
【干货】Elasticsearch索引性能优化 (2)
33
让Elasticsearch飞起来!——性能优化实践干货
34
【干货】Elasticsearch的索引性能优化(3)
35
Elasticsearch性能优化实战指南
36
ElasticSearch性能优化官方建议
37
Elasticsearch 7.10.1集群压测报告(4核16G*3,AMD)
38
Elasticsearch压测之Esrally压测标准
39
通过 esrally 压测elasticsearch
40
Elasticsearch压测工具esrally部署之踩坑实录(上)
41
Elasticsearch压测工具Esrally部署之踩坑实录(下)
42
Elasticsearch压测工具Esrally部署指南
43
百亿架构之filebeat讲解

百亿架构之filebeat讲解

此系列文章一共分为三部分,分为filebeat部分,logstash部分,es部分。这里会按照每天几百亿条的数据量来考虑,去设计、部署、优化这个日志系统,来最大限度的利用资源,并达到一个最优的性能。本篇主要讲解filebeat这一块

介绍

版本:filebeat-7.12.0

这是关于k8s的日志采集,部署方式是采用DaemonSet的方式,采集时按照k8s集群的namespace进行分类,然后根据namespace的名称创建不同的topic到kafka中

image-20210419115501654

k8s日志文件说明

一般情况下,容器中的日志在输出到标准输出(stdout)时,会以\*-json.log的命名方式保存在/var/lib/docker/containers目录中,当然如果修改了docker的数据目录,那就是在修改后的数据目录中了,例如:

代码语言:txt
复制
# tree /data/docker/containers

/data/docker/containers

├── 009227c00e48b051b6f5cb65128fd58412b845e0c6d2bec5904f977ef0ec604d

│   ├── 009227c00e48b051b6f5cb65128fd58412b845e0c6d2bec5904f977ef0ec604d-json.log

│   ├── checkpoints

│   ├── config.v2.json

│   ├── hostconfig.json

│   └── mounts

这里能看到,有这么个文件: /data/docker/containers/container id/\*-json.log,然后k8s默认会在/var/log/containers/var/log/pods目录中会生成这些日志文件的软连接,如下所示:

代码语言:txt
复制
cattle-node-agent-tvhlq\_cattle-system\_agent-8accba2d42cbc907a412be9ea3a628a90624fb8ef0b9aa2bc6ff10eab21cf702.log

etcd-k8s-master01\_kube-system\_etcd-248e250c64d89ee6b03e4ca28ba364385a443cc220af2863014b923e7f982800.log

然后,会看到这个目录下存在了此宿主机上的所有容器日志,文件的命名方式为:

代码语言:txt
复制
[podName]\_[nameSpace]\_[depoymentName]-[containerId].log

上面这个是deployment的命名方式,其他的会有些不同,例如:DaemonSetStatefulSet等,不过所有的都有一个共同点,就是

代码语言:txt
复制
\*\_[nameSpace]\_\*.log

到这里,知道这个特性,就可以往下来看Filebeat的部署和配置了。

filebeat部署

部署采用的DaemonSet方式进行,这里没有啥可说的,参照官方文档直接部署即可

代码语言:txt
复制
---

apiVersion: v1

data:

  filebeat.yml: |-

    filebeat.inputs:

    - type: containe

      enabled: true

      paths:

      - /var/log/containers/\*\_test-1\_\*log

      fields:

        namespace: test-1

        env: dev

        k8s: cluster-dev

    - type: containe

      enabled: true

      paths:

      - /var/log/containers/\*\_test-2\_\*log

      fields:

        namespace: test-2

        env: dev

        k8s: cluster-dev

    filebeat.config.modules:

      path: ${path.config}/modules.d/\*.yml

      reload.enabled: false

    output.kafka:

      hosts: ["10.0.105.74:9092","10.0.105.76:9092","10.0.105.96:9092"]

      topic: '%{[fields.k8s]}-%{[fields.namespace]}'

      partition.round\_robin:

        reachable\_only: true

kind: ConfigMap

metadata:

  name: filebeat-daemonset-config-test

  namespace: default

---

apiVersion: apps/v1

kind: DaemonSet

metadata:

  name: filebeat

  namespace: kube-system

  labels:

    k8s-app: filebeat

spec:

  selector:

    matchLabels:

      k8s-app: filebeat

  template:

    metadata:

      labels:

        k8s-app: filebeat

    spec:

      serviceAccountName: filebeat

      terminationGracePeriodSeconds: 30

      hostNetwork: true

      dnsPolicy: ClusterFirstWithHostNet

      containers:

      - name: filebeat

        image: docker.elastic.co/beats/filebeat:7.12.0

        args: [

          "-c", "/etc/filebeat.yml",

          "-e",

        ]

        env:

        - name: NODE\_NAME

          valueFrom:

            fieldRef:

              fieldPath: spec.nodeName

        securityContext:

          runAsUser: 0

          # If using Red Hat OpenShift uncomment this:

          #privileged: true

        resources:

          limits:

            memory: 200Mi

          requests:

            cpu: 100m

            memory: 100Mi

        volumeMounts:

        - name: config

          mountPath: /etc/filebeat.yml

          readOnly: true

          subPath: filebeat.yml

        - name: data

          mountPath: /usr/share/filebeat/data

        - name: varlibdockercontainers

          mountPath: /var/lib/docker/containers

          readOnly: true

        - name: varlog

          mountPath: /var/log

          readOnly: true

      volumes:

      - name: config

        configMap:

          defaultMode: 0640

          name: filebeat-config

      - name: varlibdockercontainers

        hostPath:

          path: /var/lib/docker/containers

      - name: varlog

        hostPath:

          path: /var/log

      # data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart

      - name: data

        hostPath:

          # When filebeat runs as non-root user, this directory needs to be writable by group (g+w).

          path: /var/lib/filebeat-data

          type: DirectoryOrCreate

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  name: filebeat

subjects:

- kind: ServiceAccount

  name: filebeat

  namespace: kube-system

roleRef:

  kind: ClusterRole

  name: filebeat

  apiGroup: rbac.authorization.k8s.io

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  name: filebeat

  labels:

    k8s-app: filebeat

rules:

- apiGroups: [""] # "" indicates the core API group

  resources:

  - namespaces

  - pods

  - nodes

  verbs:

  - get

  - watch

  - list

- apiGroups: ["apps"]

  resources:

    - replicasets

  verbs: ["get", "list", "watch"]

---

apiVersion: v1

kind: ServiceAccount

metadata:

  name: filebeat

  namespace: kube-system

  labels:

    k8s-app: filebeat

启动的话直接kubectl apply -f启动即可,部署不是本篇的重点,这里不做过多介绍。

官方部署参考:https://raw.githubusercontent.com/elastic/beats/7.12/deploy/kubernetes/filebeat-kubernetes.yaml

filebeat配置简单介绍

这里先简单介绍下filebeat的配置结构

代码语言:txt
复制
filebeat.inputs:



filebeat.config.modules:



processors:



output.xxxxx:

结构大概是这么个结构,完整的数据流向简单来说就是下面这个图:

image-20210419225848048

前面也说了,我是根据根据命名空间做分类,每一个命名空间就是一个topic,如果要收集多个集群,同样也是使用命名空间做分类,只不过topic的命名就需要加个k8s的集群名,这样方便去区分了,那既然是通过命名空间来获取日志,那么在配置inputs的时候就需要通过写正则将指定命名空间下的日志文件取出,然后读取,例如:

代码语言:txt
复制
filebeat.inputs:

- type: containe

  enabled: true

  paths:

  - /var/log/containers/\*\_test-1\_\*log

  fields:

    namespace: test-1

    env: dev

    k8s: cluster-dev

这里我的命名空间为bim5d-basic,然后通过正则\*\_test-1\_\*log来获取带有此命名空间名的日志文件,随后又加了个自定义字段,方便下面创建topic时使用。

这里是写了一个命名空间,如果有多个,就排开写就行了,如下所示:

代码语言:txt
复制
filebeat.inputs:

- type: containe

  enabled: true

  paths:

  - /var/log/containers/\*\_test-1\_\*log

  fields:

    namespace: test-1

    env: dev

    k8s: cluster-dev

- type: containe

  enabled: true

  paths:

  - /var/log/containers/\*\_test-2\_\*log

  fields:

    namespace: test-2

    env: dev

    k8s: cluster-dev

这种写法有一个不好的地方就是,如果命名空间比较多,那么整个配置就比较多,不要着急,**文章下面有更简洁的写法**

**注意**: 日志的类型,要设置成container

上面说了通过命名空间创建topic,我这里加了一个自定义的字段namespace,就是后面的topic的名称,但是这里有很多的命名空间,那在输出的时候,如何动态去创建呢?

代码语言:txt
复制
output.kafka:

  hosts: ["10.0.105.74:9092","10.0.105.76:9092","10.0.105.96:9092"]

  topic: '%{[fields.namespace]}'

  partition.round\_robin:

    reachable\_only: true

注意这里的写法:%{[fields.namespace]}

那么完整的配置如下所示:

代码语言:txt
复制
apiVersion: v1

data:

  filebeat.yml: |-

    filebeat.inputs:

    - type: containe

      enabled: true

      paths:

      - /var/log/containers/\*\_test-1\_\*log

      fields:

        namespace: test-1

        env: dev

        k8s: cluster-dev

    - type: containe

      enabled: true

      paths:

      - /var/log/containers/\*\_test-2\_\*log

      fields:

        namespace: test-2

        env: dev

        k8s: cluster-dev

    filebeat.config.modules:

      path: ${path.config}/modules.d/\*.yml

      reload.enabled: false

    output.kafka:

      hosts: ["10.0.105.74:9092","10.0.105.76:9092","10.0.105.96:9092"]

      topic: '%{[fields.k8s]}-%{[fields.namespace]}'

      partition.round\_robin:

        reachable\_only: true

kind: ConfigMap

metadata:

  name: filebeat-daemonset-config-test

  namespace: default

如果是不对日志做任何处理,到这里就结束了,但是这样又视乎在查看日志的时候少了点什么? 没错!到这里你仅仅知道日志内容,和该日志来自于哪个命名空间,但是你不知道该日志属于哪个服务,哪个pod,甚至说想查看该服务的镜像地址等,但是这些信息在我们上面的配置方式中是没有的,所以需要进一步的添砖加瓦。

这个时候就用到了一个配置项,叫做: processors, 看下官方的解释

You can define processors in your configuration to process events before they are sent to the configured output

简单来说就是处理日志

下面来重点讲一下这个地方,非常有用和重要

filebeat的processors使用介绍

添加K8s的基本信息

在采集k8s的日志时,如果按照上面那种配置方式,是没有关于pod的一些信息的,例如:

* Pod Name

* Pod UID

* Namespace

* Labels

* 等等等等

那么如果想添加这些信息,就要使用processors中的一个工具,叫做: add\_kubernetes\_metadata, 字面意思就是添加k8s的一些元数据信息,使用方法可以先来看一段示例:

代码语言:txt
复制
processors:

  - add\_kubernetes\_metadata:

      host: ${NODE\_NAME}

      matchers:

      - logs\_path:

          logs\_path: "/var/log/containers/"

host: 指定要对filebeat起作用的节点,防止无法准确检测到它,比如在主机网络模式下运行filebeat

matchers: 匹配器用于构造与索引创建的标识符相匹配的查找键

logs\_path: 容器日志的基本路径,如果未指定,则使用Filebeat运行的平台的默认日志路径

加上这个k8s的元数据信息之后,就可以在日志里面看到k8s的信息了,看一下添加k8s信息后的日志格式:

代码语言:txt
复制
{

  "@timestamp": "2021-04-19T07:07:36.065Z",

  "@metadata": {

    "beat": "filebeat",

    "type": "\_doc",

    "version": "7.11.2"

  },

  "log": {

    "offset": 377708,

    "file": {

      "path": "/var/log/containers/test-server-85545c868b-6nsvc\_test-1\_test-server-885412c0a8af6bfa7b3d7a341c3a9cb79a85986965e363e87529b31cb650aec4.log"

    }

  },

  "fields": {

    "env": "dev",

    "k8s": "cluster-dev"

    "namespace": "test-1"

  },

  "host": {

    "name": "filebeat-fv484"

  },

  "agent": {

    "id": "7afbca43-3ec1-4cee-b5cb-1de1e955b717",

    "name": "filebeat-fv484",

    "type": "filebeat",

    "version": "7.11.2",

    "hostname": "filebeat-fv484",

    "ephemeral\_id": "8fd29dee-da50-4c88-88d5-ebb6bbf20772"

  },

  "ecs": {

    "version": "1.6.0"

  },

  "stream": "stdout",

  "message": "2021-04-19 15:07:36.065  INFO 23 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration",

  "input": {

    "type": "container"

  },

  "container": {

    "image": {

      "name": "hub.test.com/test/test-server:3.3.1-ent-release-SNAPSHOT.20210402191241\_87c9b1f841c"

    },

    "id": "885412c0a8af6bfa7b3d7a341c3a9cb79a85986965e363e87529b31cb650aec4",

    "runtime": "docker"

  },

  "kubernetes": {

    "labels": {

      "pod-template-hash": "85545c868b",

      "app": "geip-gateway-test"

    },

    "container": {

      "name": "test-server",

      "image": "hub.test.com/test/test-server:3.3.1-ent-release-SNAPSHOT.20210402191241\_87c9b1f841c"

    },

    "node": {

      "uid": "511d9dc1-a84e-4948-b6c8-26d3f1ba2e61",

      "labels": {

        "kubernetes\_io/hostname": "k8s-node-09",

        "kubernetes\_io/os": "linux",

        "beta\_kubernetes\_io/arch": "amd64",

        "beta\_kubernetes\_io/os": "linux",

        "cloudt-global": "true",

        "kubernetes\_io/arch": "amd64"

      },

      "hostname": "k8s-node-09",

      "name": "k8s-node-09"

    },

    "namespace\_uid": "4fbea846-44b8-4d4a-b03b-56e43cff2754",

    "namespace\_labels": {

      "field\_cattle\_io/projectId": "p-lgxhz",

      "cattle\_io/creator": "norman"

    },

    "pod": {

      "name": "test-server-85545c868b-6nsvc",

      "uid": "1e678b63-fb3c-40b5-8aad-892596c5bd4d"

    },

    "namespace": "test-1",

    "replicaset": {

      "name": "test-server-85545c868b"

    }

  }

}

可以看到kubernetes这个key的value有关于pod的信息,还有node的一些信息,还有namespace信息等,基本上关于k8s的一些关键信息都包含了,非常的多和全。

但是,问题又来了,这一条日志信息有点太多了,有一半多不是我们想要的信息,所以,我们需要去掉一些对于我们没有用的字段

删除不必要的字段

代码语言:txt
复制
processors:

  - drop\_fields:

      #删除的多余字段

      fields:

        - host

        - ecs

        - log

        - agent

        - input

        - stream

        - containe

      ignore\_missing: true

元信息:@metadata是不能删除的

添加日志时间

通过上面的日志信息,可以看到是没有单独的一个关于日志时间的字段的,虽然里面有一个@timestamp,但不是北京时间,而我们要的是日志的时间,message里面倒是有时间,但是怎么能把它取到并单独添加一个字段呢,这个时候就需要用到script了,需要写一个js脚本来替换。

代码语言:txt
复制
processors:

  - script:

      lang: javascript

      id: format\_time

      tag: enable

      source: >

        function process(event) {

            var str=event.Get("message");

            var time=str.split(" ").slice(0, 2).join(" ");

            event.Put("time", time);

        }

  - timestamp:

      field: time

      timezone: Asia/Shanghai

      layouts:

        - '2006-01-02 15:04:05'

        - '2006-01-02 15:04:05.999'

      test:

        - '2019-06-22 16:33:51'

添加完成后,会多一个time的字段,在后面使用的时候,就可以使用这个字段了。

重新拼接k8s源信息

实际上,到这个程度就已经完成了我们的所有需求了,但是添加完k8s的信息之后,多了很多无用的字段,而我们如果想去掉那些没用的字段用drop\_fields也可以,例如下面这种写法:

代码语言:txt
复制
processors:

  - drop\_fields:

      #删除的多余字段

      fields:

        - kubernetes.pod.uid

        - kubernetes.namespace\_uid

        - kubernetes.namespace\_labels

        - kubernetes.node.uid

        - kubernetes.node.labels

        - kubernetes.replicaset

        - kubernetes.labels

        - kubernetes.node.name

      ignore\_missing: true

这样写也可以把无用的字段去掉,但是结构层级没有变化,嵌套了很多层,最终结果可能变成这个样子

代码语言:txt
复制
{

  "@timestamp": "2021-04-19T07:07:36.065Z",

  "@metadata": {

    "beat": "filebeat",

    "type": "\_doc",

    "version": "7.11.2"

  },

  "fields": {

    "env": "dev",

    "k8s": "cluster-dev"

    "namespace": "test-1"

  },

  "message": "2021-04-19 15:07:36.065  INFO 23 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration",

  "kubernetes": {

    "container": {

      "name": "test-server",

      "image": "hub.test.com/test/test-server:3.3.1-ent-release-SNAPSHOT.20210402191241\_87c9b1f841c"

    },

    "node": {

      "hostname": "k8s-node-09"

    },

    "pod": {

      "name": "test-server-85545c868b-6nsvc"

    },

    "namespace": "test-1"

  }

}

这样在后面使用es创建template的时候,就会嵌套好多层,查询起来也很不方便,既然这样那我们就优化下这个层级结构,继续script这个插件

代码语言:txt
复制
processors:

  - script:

      lang: javascript

      id: format\_k8s

      tag: enable

      source: >

        function process(event) {

            var k8s=event.Get("kubernetes");

            var newK8s = {

                podName: k8s.pod.name,

                nameSpace: k8s.namespace,

                imageAddr: k8s.container.name,

                hostName: k8s.node.hostname

            }

            event.Put("k8s", newK8s);

        }

这里单独创建了一个字段k8s,字段里包含:podName, nameSpace, imageAddr, hostName等关键信息,最后再把kubernetes这个字段drop掉就可以了。最终结果如下:

代码语言:txt
复制
{

  "@timestamp": "2021-04-19T07:07:36.065Z",

  "@metadata": {

    "beat": "filebeat",

    "type": "\_doc",

    "version": "7.11.2"

  },

  "fields": {

    "env": "dev",

    "k8s": "cluster-dev"

    "namespace": "test-1"

  },

  "time": "2021-04-19 15:07:36.065",

  "message": "2021-04-19 15:07:36.065  INFO 23 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration",

  "k8s": {

      "podName": "test-server-85545c868b-6nsvc",

      "nameSpace": "test-1",

      "imageAddr": "hub.test.com/test/test-server:3.3.1-ent-release-SNAPSHOT.20210402191241\_87c9b1f841c",

      "hostName": "k8s-node-09"

  }

}

这样看起来就非常清爽了。但是还是有些繁琐,因为如果后面要加新的命名空间,那么每加一次就需要再改一次配置,这样也是非常的繁琐,那么还有没有更好的方式呢?答案屎有的。

最终优化

既然通过output.kafka来创建topic的时候,可以通过指定字段,那么利用这一点,我们就可以这样设置:

代码语言:txt
复制
    output.kafka:

      hosts: ["10.0.105.74:9092","10.0.105.76:9092","10.0.105.96:9092"]

      topic: '%{[fields.k8s]}-%{[k8s.nameSpace]}'  # 通过往日志里注入k8s的元信息来获取命名空间

      partition.round\_robin:

        reachable\_only: true

之前还在fields下面创建了一个k8s的字段,用来区分来自不通的k8s集群,那么这样,我们就可以把这个配置文件优化成最终这个样子

代码语言:txt
复制
apiVersion: v1

data:

  filebeat.yml: |-

    filebeat.inputs:

    - type: containe

      enabled: true

      paths:

      - /var/log/containers/\*.log

      multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}|^[1-9]\d\*\.[1-9]\d\*\.[1-9]\d\*\.[1-9]\d\*'

      multiline.negate: true

      multiline.match: afte

      multiline.timeout: 10s

    filebeat.config.modules:

      path: ${path.config}/modules.d/\*.yml

      reload.enabled: false

    processors:

      - drop\_event.when.regexp:

          or:

            kubernetes.pod.name: "filebeat.\*"

            kubernetes.pod.name: "external-dns.\*"

            kubernetes.pod.name: "coredns.\*"

            kubernetes.pod.name: "eureka.\*"

            kubernetes.pod.name: "zookeeper.\*"

      - script:

          lang: javascript

          id: format\_time

          tag: enable

          source: >

            function process(event) {

                var str=event.Get("message");

                var time=str.split(" ").slice(0, 2).join(" ");

                event.Put("time", time);

            }

      - timestamp:

          field: time

          timezone: Asia/Shanghai

          layouts:

            - '2006-01-02 15:04:05'

            - '2006-01-02 15:04:05.999'

          test:

            - '2019-06-22 16:33:51'

      # 下面这个脚本配置可以忽略,本意是想通过获取timestamp的时间转化为时间戳,然后再转换为本地时间

      - script:

          lang: javascript

          id: format\_time\_utc

          tag: enable

          source: >

            function process(event) {

                var utc\_time=event.Get("@timestamp");

                var T\_pos = utc\_time.indexOf('T');

                var Z\_pos = utc\_time.indexOf('Z');

                var year\_month\_day = utc\_time.substr(0, T\_pos);

                var hour\_minute\_second = utc\_time.substr(T\_pos+1, Z\_pos-T\_pos-1);

                var new\_time = year\_month\_day + " " + hour\_minute\_second;

                timestamp = new Date(Date.parse(new\_time));

                timestamp = timestamp.getTime();

                timestamp = timestamp/1000;

                var timestamp = timestamp + 8\*60\*60;

                var bj\_time = new Date(parseInt(timestamp) \* 1000 + 8\* 3600 \* 1000);

                var bj\_time = bj\_time.toJSON().substr(0, 19).replace('T', ' ');

                event.Put("time\_utc", bj\_time);

            }

      - timestamp:

          field: time\_utc

          layouts:

            - '2006-01-02 15:04:05'

            - '2006-01-02 15:04:05.999'

          test:

            - '2019-06-22 16:33:51'

      - add\_fields:

          target: ''

          fields:

            env: prod

      - add\_kubernetes\_metadata:

          default\_indexers.enabled: true

          default\_matchers.enabled: true

          host: ${NODE\_NAME}

          matchers:

          - logs\_path:

              logs\_path: "/var/log/containers/"

      - script:

          lang: javascript

          id: format\_k8s

          tag: enable

          source: >

            function process(event) {

                var k8s=event.Get("kubernetes");

                var newK8s = {

                    podName: k8s.pod.name,

                    nameSpace: k8s.namespace,

                    imageAddr: k8s.container.name,

                    hostName: k8s.node.hostname,

                    k8sName: "sg-saas-pro-hbali"

                }

                event.Put("k8s", newK8s);

            }

      - drop\_fields:

          #删除的多余字段

          fields:

            - host

            - tags

            - ecs

            - log

            - prospecto

            - agent

            - input

            - beat

            - offset

            - stream

            - containe

            - kubernetes

          ignore\_missing: true

    output.kafka:

      hosts: ["10.127.91.90:9092","10.127.91.91:9092","10.127.91.92:9092"]

      topic: '%{[k8s.k8sName]}-%{[k8s.nameSpace]}'

      partition.round\_robin:

        reachable\_only: true

kind: ConfigMap

metadata:

  name: filebeat-daemonset-config

  namespace: default

做了一些调整,需要记住这里创建topic时的方式%{[k8s.k8sName]}-%{[k8s.nameSpace]},后面使用logstash时还会用到。

总结

个人认为让filebeat在收集日志的第一层做一些处理,能缩短整个过程的处理时间,因为瓶颈大多在es和logstash,所以一些耗时的操作尽量在filebeat这块去处理,如果处理不了在使用logstash,另外一个非常容易忽视的一点就是,对于日志内容的简化,这样能显著降低日志的体积,我做过测试,同样的日志条数,未做简化的体积达到20G,而优化后的体积不到10G,这样的话对于整个es集群来说可以说是非常的友好和作用巨大了。


举报
领券