【 云原生 kubernetes 】- 使用Filebeat采集k8s日志

文章目录

    • 简介
      • 采集流程:
      • 镜像构建
    • Helm部署
    • 配置调整
      • 删除赘余部分
      • 更新Values
      • 挂载文件
    • 主流程
    • 结果

⚡️: 日志采集器Logstash其功能虽然强大,但是它依赖java、在数据量大的时候,Logstash进程会消耗过多的系统资源,这将严重影响业务系统的性能,而filebeat就是一个完美的替代者,它基于Go语言没有任何依赖,配置文件简单,格式明了,

简介

​ 用于转发和集中日志数据的轻量级托运器。filebeat比logstash更加轻量级,所以占用系统资源极少,非常适合安装在生产机器上。这就是推荐使用filebeat,也是 ELK Stack 在 Agent 的第一选择。

采集流程:

  • container log --> Kafka topic

镜像构建

官方拉取的镜像,时区是 UTC ,我们想要获取到 CST 时间,并使用 filebeat 用户访问,就需要我们自己重新打镜像,下面是所用的Dockerfile

FROM elastic/filebeat:8.5.1
MAINTAINER ycloud
USER root

RUN apt-get update && apt-get install -y tzdata && rm -rf /var/lib/apt/lists/*

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

USER filebeat

Helm部署

  • helm repo add elastic https://helm.elastic.co
  • helm install filebeat elastic/filebeat

部署十分简单,但是我们可能需要调整Helm chart配置,所以建议把包拉取到本地调整之后再进行部署,下面是详细流程

[root@ycloud ~]# helm repo add elastic https://helm.elastic.co
"elastic" already exists with the same configuration, skipping
[root@ycloud ~]# helm pull elastic/filebeat
[root@ycloud ~]# tar -zxvf filebeat-8.5.1.tgz 
filebeat/Chart.yaml
filebeat/values.yaml
filebeat/templates/NOTES.txt
filebeat/templates/_helpers.tpl
filebeat/templates/clusterrole.yaml
filebeat/templates/clusterrolebinding.yaml
filebeat/templates/configmap.yaml
filebeat/templates/daemonset.yaml
filebeat/templates/deployment.yaml
filebeat/templates/role.yaml
filebeat/templates/rolebinding.yaml
...
[root@ycloud ~]# cd filebeat/ ; ls
Chart.yaml  examples  Makefile  README.md  templates  values.yaml

配置调整

删除赘余部分

我们刚刚拉取了官方的Chart包,中间默认是指定input到Elastic,所以我们需要调整下Deployment模板

[root@ycloud filebeat]# vim templates/daemonset.yaml 
...
{{- if .Values.extraEnvs | default .Values.daemonset.extraEnvs }}
{{ toYaml ( .Values.extraEnvs | default .Values.daemonset.extraEnvs ) | indent 8 }}
{{- end }}
...
...
        {{- range .Values.secretMounts | default .Values.daemonset.secretMounts }}
        - name: {{ .name }}
          mountPath: {{ .path }}
          {{- if .subPath }}
          subPath: {{ .subPath }}
          {{- end }}
        {{- end }}
...
...
      {{- range .Values.secretMounts | default .Values.daemonset.secretMounts }}
      - name: {{ .name }}
        secret:
          secretName: {{ .secretName }}
      {{- end }}
...

⚡️:这里的secrets是挂的elastic的用户名密码,因为我这边是把数据先推到 kafka 而不是 es中,所以这个secrets 部分可以去掉。大家可以根据自己的情况调节。

更新Values

image 部分改为我们自己新build的镜像名称及tag

其余没什么太大改动的,剩下就是filebeat的配置文件,根据自己的情况进行配置,下面是我的一个配置情况

[root@ycloud filebeat]# vim values.yaml 
...
    filebeat.inputs:
    - type: container
      paths:
        - /var/log/containers/*gstrain*.log
      scan_frequency: 1s
      processors:
        - add_kubernetes_metadata:
            in_cluster: true
            namespace: "gstrain"
            matchers:
              - logs_path:
                  logs_path: "/var/log/containers"
                  identifier: "container.id"
            enrichers:
              - deployment
        - drop_fields:
            fields:
              - "/^kubernetes\\.labels\\..*/"
              - "/^kubernetes\\.namespace_labels\\..*/"
              - "/^kubernetes\\.node\\..*/"
              - "/^(agent\\.name|agent\\.id|agent\\.type)$/"

        - drop_event:
            when:
              or:
                - equals:
                    kubernetes.container.name: "istio-proxy"
                - equals:
                    kubernetes.container.name: "istio-init"

    logging.level: debug
    output.kafka:
      hosts: ["10.189.6.130:9092","10.189.6.131:9092","10.189.6.132:9092"]
      topic: "gstrainpod-devel"
      partition.round_robin:
        reachable_only: true
      required_acks: 1
      compression: gzip
      max_message_bytes: 1000000
...
  • filebeat.inputs参数指定要监视的输入类型。在这个配置中,Filebeat监视Docker容器日志,并根据给定的路径来查找所有符合条件(包含“gstrain”字符串的)的容器日志文件。
  • scan_frequency参数设置Filebeat扫描容器日志文件的频率。
  • processors参数指定应该对事件进行的任何预处理步骤。在这个配置中,有几个处理器被定义,包括添加Kubernetes元数据,删除某些字段和事件过滤器等。
  • add_kubernetes_metadata处理器通过查询Kubernetes API来添加Kubernetes标签和注释等元数据信息,使得在后续处理流程中可以更好地对日志进行分类和分析。
  • drop_fields处理器通过正则表达式删除日志事件中不需要的字段,比如Kubernetes相关的字段。
  • drop_event处理器可以丢弃事件,例如当事件来自特定容器时,此处当事件来源于Istio Sidecar容器(istio-proxy和istio-init)时将其丢弃。
  • logging.level参数设置Filebeat的日志级别,这里设置为debug。
  • output.kafka参数定义要将收集的日志数据发送到Kafka的设置。在这个配置中,输出Kafka的地址以及要使用的主题名称等信息都被指定。还可以看到诸如轮询分区、压缩等其他设置。

挂载文件

❌: 这里有一点需要注意,这也是我疑惑的地方,filebeat采集日志,但是配置中的paths路径确实容器内部的路径,也可能中间哪些步骤没有了解清楚,我暂时是将宿主机目录挂载到Pod中,暂时解决这个问题

⭕️: 还有一个地方需要注意,了解的朋友可能知道 /var/log/containers 其实是个软连接,如果我们调整了容器日志的存储路径,也记得要把更改的路径挂上去,不然查询不到实际日志。

下面给出挂载案例,以Docker为 Runtime为例,并且日志路径为 /data/docker/

[root@ycloud filebeat]# vim template/DaemonSet.yaml
...
          volumeMounts:
            - mountPath: /usr/share/filebeat/filebeat.yml
              name: filebeat-config
              readOnly: true
              subPath: filebeat.yml
            - mountPath: /var/log/
              name: log
              readOnly: true
            - mountPath: /data/docker/containers
              name: dockerlog
              readOnly: true
...
...
      volumes:
        - configMap:
            defaultMode: 384
            name: filebeat-filebeat-deployment-config
          name: filebeat-config
        - hostPath:
            path: /var/log/
            type: ''
          name: log
        - hostPath:
            path: /data/docker/containers
            type: ''
          name: dockerlog
...

主流程

【 云原生 kubernetes 】- 使用Filebeat采集k8s日志_第1张图片

✌️: 我们filebaet采集Pod日志就可以正常运行了,不过我们前面也说了,我这边根据业务实际情况,将日志采集到Kafka 队列中去,通过现有日志系统中的Logstash将日志转发到 ES 中去。

下面就十分简易了,就直接贴个配置好了

input {
    kafka {
        id => "pod_k2e_id"
        bootstrap_servers => "192.168.100.10:9092,192.168.100.20:9092,192.168.100.30:9092"
        topics => "pod"
        auto_offset_reset => "earliest"
        group_id => "group_pod"
        consumer_threads => 90
        codec => json { charset => "UTF-8" }
    }
}

filter {
                        json {
                                source => "message"
                        }

                        mutate {
                                remove_field => ["tags","host","^host.*"]

                        }

                        ruby {
                                code => "event.set('index_day', event.get('@timestamp').time.localtime.strftime('%Y.%m.%d'))"
                        }   

                        mutate {
                                convert => {
                                "index_day" => "string"
                                }   
                        }
}

output {
    if ( [kubernetes][deployment][name] == "ycloud") {
        elasticsearch {
                id => "es_pod_id"
                hosts => ["http://192.168.100.10:9200","http://192.168.100.20:9200","http://192.168.100.30:9200"]
                index => "ycloud_crawl-%{index_day}"
                user => "elastic"
                password => "xxxxxxxxxx"
                codec => json { charset => "UTF-8" }
        }
    }else {
        elasticsearch {
                id => "es_pod2_id"
                hosts => ["http://192.168.100.10:9200","http://192.168.100.20:9200","http://192.168.100.30:9200"]
                index => "ycloud_pod-%{index_day}"
                user => "elastic"
                password => "xxxxxxxxxx"
                codec => json { charset => "UTF-8" } 
        }
    }  
}

结果

这里我们就可以成功采集到我们想要的日志了,不需要的字段也跟使用过滤器来delete掉。

你可能感兴趣的:(云原生,云原生,kubernetes,容器)