ELK系列之四---如何通过Filebeat和Logstash优化K8S集群的日志收集和展示

news2024/11/15 17:21:49

前 言

上一篇文章《日志不再乱: 如何使用Logstash进行高效日志收集与存储》介绍了使用ELK收集通用应用的日志,在目前大多应用都已运行在K8S集群上的环境,需要考虑怎么收集K8S上的日志,本篇就介绍一下如何使用现有的ELK平台收集K8S集群上POD的日志。

K8S日志文件说明

一般情况下,容器中的日志在输出到标准输出(stdout)时,会以.log的命名方式保存在/var/log/pods/containerd_ID/目录中,例如:
在这里插入图片描述

K8S默认会在/var/log/containers/目录下创建软链接链接到/var/log/pods/containerd_id/目录下的具体日志文件,并规范化了软连接到文件名称,软链接的命名规范为

[podName]_[nameSpace]_[depoymentName]-[containerId].log

在这里插入图片描述

上面这个是deployment的命名方式,其他的会有些不同,例如:DaemonSet,StatefulSet等,不过所有的都有一个共同点,就是
每个软链接名称都是

*_[nameSpace]_*.log

所以根据这个日志特征我们可以很容易想到可以根据namespace来分别收集不同名称空间的日志。

一、日志收集架构

在ELK Stack组件中,有logstash和filebeat都可以实现日志收集,因为filebeat更轻量化,在K8S集群中通常使用filebeat来收集pod的日志,通过daemonSet控制器在每个K8S每个节点上运行一个filebeat来收集每个节点上的pod日志,filebeat官网图如下,filebeat输出支持对接Elasticsearch、Logstash、Kafka、Redis,本文选择对接Kafka,先缓存filebeat收集的日志,这样可以减少对ES的性能要求。
在这里插入图片描述

filebeat将收集的pod日志保存在K8S集群外的kafka集群,然后通过logstash再从kafka读取、过滤、整理之后再保存到elasticsearch集群中,然后通过kibana可视化管理日志,架构图如下
在这里插入图片描述

此架构中包含了K8S集群、Kafka集群、ElasticSearch集群,具体机器信息如下表

集群主机名IP地址应用
k8s-clusterk8s-master01172.16.1.65k8s-control
k8s-clusterk8s-node01172.16.1.66k8s-work
k8s-clusterk8s-node02172.16.1.67k8s-work
k8s-clusterk8s-node03172.16.1.68k8s-work
kafka-clusterkafka1172.16.1.11zookeeper/kafka/kibana
kafka-clusterkafka2172.16.1.12zookeeper/kafka
kafka-clusterkafka3172.16.1.13zookeeper/kafka
ES-clusteres1172.16.1.101elasticsearch
ES-clusteres2172.16.1.102elasticsearch
ES-clusteres3172.16.1.103elasticsearch
Logstashdeploy172.16.1.70Lostash

二、部署kafka集群

文章《在K8S上部署Cilium组件,看这一篇干货就够了》介绍了k8s-cluster集群的搭建过程,文章《可视化日志分析新境界:手把手教你搭建高效的ElasticSearch集群》介绍了ES-cluster集群的搭建过程

2.1、下载kafka

现在需要搭建kafka-cluster集群,在kafka-cluster集群的三个节点上下载最新版本kafka,下载二进制的压缩包
在这里插入图片描述

在每个节点上创建/opt目录,将kafka压缩包放到/opt目录下,解压并创建软连接
在这里插入图片描述

2.2、搭建zookeeper集群

最新版本kafka的taz包里已经包含了zookeeper的文件,所以在配置kafka之间先配置zookeeper,
三个几点上修改zookeeper配置文件如下
在这里插入图片描述

dataDir       #指定zookeeper的数据目录 
clientPort     #指定zookeeper的监听端口
maxClientCnxns   #限制最大client连接数

修改完成后,3个节点上同时开启zookeeper服务

~# /opt/kafka/bin/zookeeper-server-start.sh -daemon /opt/kafka/config/zookeeper.properties

在这里插入图片描述

查看三个几点都已监听2181端口即表示zookeeper集群搭建成功

2.3、搭建kafka集群

3个节点修改kafka的配置文件,如下图
在这里插入图片描述

broker.id                    #指定kafka的节点IP,每个节点都不相同
listeners                    #指定kafka的监听IP和端口,三个节点分别监听自己的IP
log.dirs                     #指定kafka的数据目录
zookeeper.connect            #指定zookeeper的连接地址,三个地址都写上

其他选项默认即可
3个节点同时启动kafka

~# /opt/kafka/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

在这里插入图片描述

3个几点同时监听2181和9092两个端口即搭建成功

2.4、测试验证kafka

kafka有一个客户端工具OffsetExplorer,可链接kafka
在这里插入图片描述

创建连接时填入任意一个kafka节点的IP即可连接,连接显示绿色表示集群状态正常
可以通过kafka的命令行客户端测试数据的写入的读取

#创建一个topic
~# /opt/kafka/bin/kafka-topic.sh --crate --topic quick-events --bootstrap-server 172.16.1.12:9092 
#写入数据
~# /opt/kafka/bin/kafka-console-producer.sh --topic quick-events --bootstrap-server 172.16.1.12:9092
#读取数据
~# /opt/kafka/bin/kafka-console-consumer.sh --topic quick-events --bootstrap-server 172.16.1.12:9092

在这里插入图片描述

在OffsetExplorer上也可以看到刚才创建的topic和写入的数据
在这里插入图片描述

三、部署filebeat

在K8S集群上使用DaemonSet控制器部署filebeat,可以通过ELK Stack官网下载filebeat的部署文件filebeat-kubernetes.yaml

curl -L -O https://raw.githubusercontent.com/elastic/beats/8.15/deploy/kubernetes/filebeat-kubernetes.yaml

下载完成后修改yaml文件,添加创建elfk名称空间的指令,并修改下面所有资源的namespace为elfk

apiVersion: v1
kind: Namespace
metadata:
  name: elfk
  labels:
    name: elfk

修改ConfigMap部分,指定了按namespace收集

apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-config
  namespace: elfk
  labels:
    k8s-app: filebeat
data:
  filebeat.yml: |-
    filebeat.inputs:
    - type: container
      enabled: true
      paths:
        - /var/log/containers/*_kube-system_*log
      fields:
        log_topic: kube-system
        env: dev
      multiline.pattern: '(^\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}\])|(^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3})|(^[0-9]{2}:[0-9]{2}:[0-9]{2})'
      multiline.negate: true
      multiline.match: after
      multiline.max_lines: 100

    - type: container
      enabled: true
      paths:
        - /var/log/containers/*_elfk_*log
      fields:
        log_topic: elfk
        env: dev
      multiline.pattern: '(^\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}\])|(^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3})|(^[0-9]{2}:[0-9]{2}:[0-9]{2})'
      multiline.negate: true
      multiline.match: after
      multiline.max_lines: 100
  
    - type: container
      enabled: true
      paths:
        - /var/log/containers/*_defaulte_*log
      fields:
        log_topic: defaulte
        env: dev
      multiline.pattern: '(^\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}\])|(^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3})|(^[0-9]{2}:[0-9]{2}:[0-9]{2})'
      multiline.negate: true
      multiline.match: after
      multiline.max_lines: 100
 
    - type: container
      enabled: true
      paths:
        - /var/log/containers/*_metallb-system_*log
      fields:
        log_topic: metallb-system
        env: dev
      multiline.pattern: '(^\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}\])|(^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3})|(^[0-9]{2}:[0-9]{2}:[0-9]{2})'
      multiline.negate: true
      multiline.match: after
      multiline.max_lines: 100
  
    - type: container
      enabled: true
      paths:
        - /var/log/containers/*_redis_*log
      fields:
        log_topic: redis
        env: dev
      multiline.pattern: '(^\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}\])|(^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3})|(^[0-9]{2}:[0-9]{2}:[0-9]{2})'
      multiline.negate: true
      multiline.match: after
      multiline.max_lines: 100
    filebeat.config.modules:
      path: ${path.config}/modules.d/*.yml
      reload.enabled: false

    processors:
    #添加k8s元数据信息
    - add_kubernetes_metadata:
        host: ${NODE_NAME}
        matchers:
        - logs_path:
            logs_path: "/var/log/containers/"
  
     #移除多余的字段
    - drop_fields:
        fields:
          - host
          - ecs
          - log
          - agent
          - input
          - stream
          - container
          - 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
  
    - script:
        lang: javascript
        id: format_time
        tag: enable
        source: |
          function process(event) {
            var str = event.Get("message");

            // 用括号提取时间戳
            var regex = /^\[(.*?)\]/;
            var match = str.match(regex);
            if (match && match.length > 1) {
              var time = match[1]; //提取的不带括号的时间戳
              event.Put("time", time);
            }

			// 提取不带括号的时间戳
            var regex2 = /^\d{2}:\d{2}:\d{2}/;
            var match2 = str.match(regex2);
            if (match2) {
              time = match2[0]; // Extracted timestamp
              event.Put("time", time);
            }
          }
  
     #优化层级结构
    - 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);
          }
    #添加时间,可以在logstash处理
    - 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'

修改daemonset部分,添加k8s-control-plan容忍,允许在master节点上运行filebeat

    spec:
      tolerations:
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule

部署filebeat

~# kubectl apply -f filebeat-kubernetes.yaml

在这里插入图片描述

检查资源运行情况

~# kubectl get all -n elfk -o wide

在这里插入图片描述

4个节点上都运行filebeat的pod即表示部署成功

四、部署Logstash

4.1、检查kafka上topic

先通过OffsetExlporer查看kafka上是否成功收到了数据,产生了topic
在这里插入图片描述

上图可以看到以namespace为名称产生了topic,说明数据已经成功对接到了kafka集群
在kafka集群上不可很好的查看和检索日志数据,现在需要将kafka上的日志传输到ES集群上,这里需要使用Logstash对日志进行转发和过滤

4.2、部署Logstash

这里复用上一篇里部署的Logstash,新写一份对接kafka的配置文件即可,如下图
在这里插入图片描述

input                   #写入kafka集群的一个节点地址
topics                  #写入kafka集群上已经产生的topic
codec                  #使用json插件解码,生成多个日志字段
output                 #写入ES集群的连接地址
index                   #写入index名称

可以先测试一下配置文件是否正确

~# /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/kafka-to-es.conf -t

重启logstash

~# systemctl restart logstash

在这里插入图片描述

4.3、检查ES上数据

可以通过elasticsearch head插件或者cerebro插件查看ES-cluster集群上数据是否成功产生
在这里插入图片描述

可以看到ES-cluster上产生jnlikai-k8s-container-log开头的index表示k8s的日志数据已经被转发到了ES集群

五、在Kibana上检索日志

在Kibana上创建数据视图
在这里插入图片描述

创建成功后可以看到此视图下有很多k8s的日志字段,检索日志时可以根据这些字段进行任意筛选检索
在这里插入图片描述

查看视图时也可以看到K8S上的节点、名称空间都是单独字段
在这里插入图片描述

在这里插入图片描述

                                         欢迎关注作者的公众号,公众号每天分享运维干货文章 

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2109984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新型供应链攻击手法 — “Revival Hijack”

JFrog 的网络安全研究人员发现了一种名为“Revival Hijack”的新型 PyPI 攻击技术,该技术利用包删除策略绕过安全检查。据统计,超过 22,000 个程序包处于风险之中,可能会影响数十万名用户。 JFrog 的网络安全研究人员发现了一种用于攻击 Pyth…

易灵思时钟输出问题记录

在添加 GPIO时,设置Mode为clkout,并在output Clock中输入时钟名。 这里需要 注意的是, 1. 时钟名不能从core直接输出,而只能使用interface中使用的时钟,如PLL输出的时钟或者GCLK输入的时钟。 2. 易灵思输出时钟不能做其他用途&a…

2024中国产业园区运营商50强榜单揭晓:行业洗牌加速,数智化是关键!

近日,备受瞩目的“2024年度中国产业园区运营商50强”榜单正式揭晓,不仅照亮了行业内的领军之星,更为我们揭示了产业园区运营管理平台在推动经济转型升级中的关键力量与未来趋势的璀璨图景。 从以上产业园区运营商 50 强的角度来看&#xff0…

30岁程序员的焦虑:转行还是继续死磕?现在什么方向更有前景?

最适合转入AI大模型的莫过于程序员和在读大学生了吧。 对于程序员来说,码农之路并不是一帆风顺。对于每一个入行IT业的社会青年来说,谁不是抱着想要成为最高峰的技术大咖或者跃进管理岗的小目标? 然而往往更多的人并非互联网吹捧的如此耀眼…

云原生技术:‌引领数字化转型的新浪潮

云原生技术:‌引领数字化转型的新浪潮 在数字化转型的时代背景下,‌企业面临着前所未有的挑战与机遇。‌随着云计算技术的飞速发展,‌云原生技术作为一种新型的应用程序开发和部署方式,‌正逐步成为构建高可用、‌可扩展应用程序…

MySQL复习1

基本概念 OLTP OLTP(On-Line transaction processing)翻译为联机事物处理;主要对数据库增删改查。 OLTP 主要用来记录某类业务事件的发生;数据会以增删改查的方式在数据库中更新处理操作,要求实施性强,稳…

OS_程序的装入与链接

2024.09.05:操作系统程序的装入与链接学习笔记 第12节 程序的装入与链接 2.1 程序的装入2.1.1 绝对装入方式2.1.2 可重定位装入方式(静态重定位)2.1.3 动态运行时装入方式(动态重定位) 2.2 程序的链接2.2.1 静态链接方…

LIN总线CAPL函数—— 检查LIN报头的时间(ChkStart_LINHeaderToleranceViolation

🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe&…

高级算法设计与分析 学习笔记3 哈希表

首先我们要讨论一个把n个数据放到列表S里面的问题: 但很显然,这些数据的范围有多大这个T就得有多大,而实际上要放的数字可能就几个(比如就放一个1和一个10000000,那我还是要准备一个巨大的T),不…

【STM32】cubemx配置GPIO

直接使用STM32CubeMX点灯 使用之前的工程 配置GPIO 对四个灯设置GPIO输出 close后直接打开keil 演示

基于LangChain+LLM的相关技术研究及初步实践

0 1 概述 大模型概述 大模型是指具有大规模参数和复杂计算结构的机器学习模型。这些模型通常由深度神经网络构建而成,拥有数十亿甚至数千亿个参数。大模型的设计目的是为了提高模型的表达能力和预测性能,能够处理更加复杂的任务和数据。大模型在各种领…

提高 Facebook 参与度的 8个技巧

在社交媒体中,Facebook仍然是企业与受众建立联系的重要渠道。无论你是刚刚建立 Facebook 业务主页,还是经验丰富的营销人员,都必须了解人们如何跟你的主页互动。 一、什么是 Facebook 参与度? Facebook的参与度是指用户对你的 F…

潜望长焦+快充:vivo X200系列,小尺寸手机的大突破

在智能手机市场日益激烈的竞争中,厂商们不断推陈出新,以满足消费者多样化的需求。vivo作为中国知名的智能手机品牌,一直以其创新的设计和强大的功能赢得市场的认可。 近日,vivo X200系列的即将发布引起了广泛关注,特别…

开学季装机必备软件 向日葵远程控制,手机也能变电脑

暑假转眼结束,又来到了9月开学季。 这个时间点,不少同学会选择为自己购置一台电脑,放置在宿舍使用。 一台全新的PC电脑该安装哪些软件呢?基本的办公全家桶不用多说,steam、epic等游戏娱乐平台更是无需多言。除此之外…

Spring Cloud Gateway学习记录

Spring中文网 https://springdoc.cn/spring-cloud-gateway/ Spring官网 https://spring.io/projects/spring-cloud-gateway 网关简介 大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢? 如果…

如何恢复格式化的 Android 智能手机

如何恢复Android手机上格式化的数据 格式化智能手机的存储卡后,您想恢复图片、视频、音乐吗?您想从 Android 手机中恢复已删除的文本吗?格式化存储卡后,如何恢复存储卡上的图片? 使用奇客数据恢复,这款特…

可解释人工智能(XAI)领域的全面概述

AI 模型,尤其是深度学习模型,由于其黑盒性质,在安全关键领域(如医疗保健、金融和自动驾驶汽车)中面临着重大挑战。用户无法理解模型的内部逻辑和决策过程,这导致了缺乏信任、透明度和问责制。XAI 通过提供模…

C的温故而知新:The Last(C Primer Plus第十六、十七章)

The Last 想必是后面的内容超出大一课程规定的内容了,后面的文章数据惨的可怜。搜一下就能看见,好多人主张这本书后面几张可以不看。咋讲呢,对于这个观点来说,我本人是不认同的,我呢,粗略的看了看后两章的…

降Compose十八掌之『羝羊触蕃』| Handle Platform Lifecycles

公众号「稀有猿诉」 原文链接 降Compose十八掌之『羝羊触蕃』| Handle Platform Lifecycles Jetpack Compose是一个独立的声明式UI框架,它并不受限于任何操作系统平台,从框架定位的角度来讲,它是跨平台的,也应该要跨平台。…

Mail PHP: 如何设置SMTP服务器以发送邮件?

Mail PHP的功能怎么有效配置?Mail PHP的性能如何优化? 无论是用户注册确认、密码重置,还是系统通知,邮件发送功能都是不可或缺的。在PHP中,使用SMTP服务器发送邮件是一种高效且可靠的方式。AokSend将详细介绍如何在Ma…