K8s 搭建 FileBeat+ELK 分布式日志收集系统 以及 KQL 语法介绍

一、K8s FileBeat + ELK 介绍

ELK,即ElasticsearchLogstashKibana三个开源软件的组合,是由Elastic公司提供的一套完整的日志管理解决方案。Elasticsearch是一个高度可扩展的开源全文搜索和分析引擎,它允许你快速地、近乎实时地存储、搜索和分析大量数据。Logstash是一个服务器端数据处理管道,它能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如Elasticsearch等存储库中。Kibana则允许你通过Elasticsearch使用图表和表格直观地展示数据。

ELK主要解决了如何有效地收集、处理、存储和可视化大量的日志数据。优势在于它能够处理和分析大量的日志数据,提供实时的搜索和分析能力,同时它的分布式设计使其具有很高的扩展性。但劣势在于它的配置和维护相对复杂,特别是Logstash,需要编写复杂的配置文件,对系统资源的要求也相对较高。

然而,直接使用ELK栈在数据收集方面可能存在一些问题。例如,Logstash是一个重量级的工具,它在数据收集过程中可能会消耗大量的系统资源,这对于资源有限的环境来说可能是一个问题。此外,Logstash的配置也相对复杂,需要编写大量的配置文件,这对于一些简单的日志收集任务来说可能显得过于繁琐。

为了解决这些问题,Elastic公司推出了FilebeatFilebeat是一个轻量级的日志传输工具,它可以安装在需要收集日志的服务器上,实时读取日志文件,并将这些日志数据发送到指定的输出,如LogstashElasticsearchkafka。它的优势在于轻量级设计,对系统资源的消耗极低,同时它的配置也相对简单,易于管理和维护。通过接入Filebeat,可以有效地解决Logstash在数据收集方面的问题,提高整个ELK栈的性能和稳定性。

在这里插入图片描述

K8s 环境中的 ELK

随着 k8s 的越来越普及化,很多应用都被部署在了 k8s 中,如何在 k8s 中进行 ELK 日志管理呢?首先要搞清楚 k8s 中的日志都存在了哪里,可以主要从下面三个目录入手:

  • /var/lib/docker/containers/ :是Docker守护进程用于存储容器元数据和日志数据的地方。每个容器的日志文件通常以<container_ID>-json.log的形式存储在这个目录下的相应子目录中。这些日志文件包含了容器的stdoutstderr输出,并且是以JSON格式存储的。Filebeat可以直接读取这些文件来收集容器的日志。

  • /var/log/containers/ :是k8s为了便于日志管理而创建的符号链接(symlink)目录。它包含了到/var/lib/docker/containers/目录中日志文件的链接。每个符号链接的名称通常是由Pod名称、容器名称和实例编号组成的。Filebeat可以通过这个目录轻松地访问和收集容器的日志,而不需要直接访问Docker的内部目录。

  • /var/log/pods/ :是 K8s 用于存储Pod日志的地方。每个Pod都会在这个目录下有一个以Pod UID命名的子目录,Pod内的每个容器又有各自以容器名称命名的日志文件。这些日志文件包含了容器的stdoutstderr输出,但是它们是以文本格式而不是JSON格式存储的。这个目录的结构有助于保持Pod和容器日志的隔离性,便于管理和访问。

因此我们可以主要从 /var/log/containers/ 目录入手,FilebeatDaemonSet的方式部署在k8s集群中。DaemonSet可以确保每个节点上都有一个Filebeat实例在运行,通过读取宿主机上的日志文件来收集k8s的日志。

Filebeat 中已经内置了 k8s 的支持,我们可以通过配置 processors.add_kubernetes_metadata 来增强日志数据,将Kubernetes的元数据添加到日志事件中,比如Pod名称、Namespace、容器名称等:

  processors:- add_kubernetes_metadata:default_indexers.enabled: truedefault_matchers.enabled: truematchers:- logs_path:logs_path: "/var/log/containers/"

当数据发送给到 logstash 时,直接可以通过 [kubernetes][namespace][kubernetes][container][name] 获取到 k8s 中的元数据信息,因此可以利用 logstash 动态创建不同应用的动态日志索引,针对每个命名空间下不同的应用创建单独的索引记录日志,这样更便于后期对日志的排查。例如 logstash.conf 可以这样配置:

output { if [kubernetes][namespace] and [kubernetes][container][name] {elasticsearch { hosts => ["http://elasticsearch:9200"] index => "k8s-%{[kubernetes][namespace]}-%{[kubernetes][container][name]}-%{+YYYY.MM.dd}"}} else {elasticsearch { hosts => ["http://elasticsearch:9200"] index => "k8s-%{+YYYY.MM.dd}"}}
} 

下面开始实践在 k8s 中部署 FileBeat+ELK 分布式日志系统,实验采用版本均为 7.14.0

创建命名空间

这里首先创建一个命名空间,后续所有操作均在该空间下:

kubectl create ns elk

创建测试服务

在开始前这里创建一个 SpringBoot 项目,项目名称为 elk-demo ,用来打印不同级别的日志,用来验证是否能被收集,以及收集的索引是否动态创建。

创建测试接口:

@Slf4j
@RestController
public class TestController {@GetMapping("/t1")public void t1() {log.info("this is test, level: info");log.warn("this is test, level: warn");log.debug("this is test, level: debug");log.error("this is test, level: err", new RuntimeException("Err detail!"));}}

编写 Dockerfile 文件:

FROM java:8
MAINTAINER bxc
WORKDIR /app
ENV TZ=Asia/Shanghai
ADD target/elk-demo-0.0.1-SNAPSHOT.jar /app/app.jar
CMD ["java", "-jar", "app.jar"]

构建镜像并上传至私服 harbor 中,如果没有 harbor 仓库也可以将镜像上传至每个 k8s node 节点中,然后使用 docker load 到本地镜像仓库中。

# 打包成 jar 包
mvn clean package
# 构建镜像
cd elk-demo
docker build -t elk-demo:1.0 .
# 上传至 harbor
docker tag elk-demo:1.0 11.0.1.150/image/elk-demo:1.0 .
docker push 11.0.1.150/image/elk-demo:1.0

k8s 部署测试服务

vi elk-demo.yml
apiVersion: v1
kind: Service
metadata:name: elk-demonamespace: elklabels:app: elk-demo
spec:type: NodePortports:- port: 8080name: clientnodePort: 31880targetPort: 8080selector:app: elk-demo---
apiVersion: apps/v1
kind: Deployment
metadata:name: elk-demonamespace: elk
spec:replicas: 3selector:matchLabels:app: elk-demotemplate:metadata:labels:app: elk-demospec:containers:- name: elk-demoimage: elk-demo:1.0ports:- containerPort: 8080name: serverenv:- name: TZvalue: Asia/Shanghai
kubectl apply -f elk-demo.yml

二、K8s 部署 FileBeat+ELK

2.1 部署 ES 集群和 Kibana

ES 集群和 kibana 的部署过程可以参考下面这篇文章:

K8s 部署 elasticsearch-7.14.0 集群 及 kibana 客户端

这里我 ESService 名称为 elasticsearch ,所以后面 ES 的访问地址可以写成 :http://elasticsearch:9200

2.2 部署 logstach

vi logstach.yml
apiVersion: v1 
kind: Service
metadata: name: logstashnamespace: elklabels:app: logstash
spec: ports: - port: 5044name: logstash  targetPort: 5044    selector: app: logstash type: ClusterIP--- 
apiVersion: v1 
kind: ConfigMap 
metadata: name: logstash-conf namespace: elk
data: logstash.conf: |- input {beats { port => 5044 } } filter {grok {match => { "message" => "(%{TIMESTAMP_ISO8601:logdatetime}  %{LOGLEVEL:level} %{GREEDYDATA:logmessage})|%{GREEDYDATA:logmessage}" }remove_field => [ "logmessage" ]}}output { if [kubernetes][namespace] and [kubernetes][container][name] {elasticsearch { hosts => ["http://elasticsearch:9200"] index => "k8s-%{[kubernetes][namespace]}-%{[kubernetes][container][name]}-%{+YYYY.MM.dd}"}} else {elasticsearch { hosts => ["http://elasticsearch:9200"] index => "k8s-%{+YYYY.MM.dd}"}}} ---
apiVersion: v1 
kind: ConfigMap 
metadata: name: logstash-yml namespace: elk labels: type: logstash 
data: logstash.yml: |-http.host: "0.0.0.0"xpack.monitoring.elasticsearch.hosts: http://elasticsearch:9200---
apiVersion: apps/v1 
kind: Deployment
metadata:name: logstash namespace: elk
spec: selector: matchLabels: app: logstash template: metadata: labels: app: logstash spec: containers: - image: elastic/logstash:7.14.0name: logstash ports: - containerPort: 5044 name: logstash command: - logstash - '-f' - '/usr/share/logstash/config/logstash.conf' volumeMounts: - name: config-volume mountPath: /usr/share/logstash/config/logstash.confsubPath: logstash.conf- name: config-yml-volume mountPath: /usr/share/logstash/config/logstash.ymlsubPath: logstash.ymlresources:limits: cpu: 1000m memory: 2048Mi requests: cpu: 512m memory: 128Mi volumes: - name: config-volume configMap: name: logstash-conf - name: config-yml-volume configMap: name: logstash-yml 
kubectl apply -f logstach.yml

查看启动 pod

kubectl get pods -n elk

在这里插入图片描述

观察 logstash 日志,是否启动成功:

kubectl logs -f logstash-84d8d7cd55-rcfgs -n elk

在这里插入图片描述

2.3 部署 filebeta

注意,由于 filebeta 需要获取 k8s 中的信息,这里需要创建 ServiceAccount 并授权获取信息的权限。

vi filebeta.yml
apiVersion: v1 
kind: ServiceAccount
metadata: name: filebeat-accountnamespace: elklabels: app: filebeat
--- 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole 
metadata: name: filebeat-crlabels: app: filebeat 
rules: 
- apiGroups: [""] resources: - namespaces - pods - nodesverbs: ["get", "watch", "list"]
--- 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding 
metadata: name: filebeat-crb
subjects: 
- kind: ServiceAccount name: filebeat-account namespace: elk 
roleRef: kind: ClusterRole name: filebeat-cr apiGroup: rbac.authorization.k8s.io ---
apiVersion: v1 
kind: ConfigMap 
metadata: name: filebeat-config namespace: elk
data: filebeat.yml: |- filebeat.inputs: - type: container enable: true paths: - /var/log/containers/*.log multiline: pattern: '^\d{4}-\d{1,2}-\d{1,2}'negate: truematch: aftermax_lines: 100timeout: 5sprocessors:- add_kubernetes_metadata:default_indexers.enabled: truedefault_matchers.enabled: truematchers:- logs_path:logs_path: "/var/log/containers/"output.logstash:  hosts: ["logstash:5044"] enabled: true #output.kafka:  # 输出到 kafka 示例#  hosts: ["kafka-01:9092", "kafka-02:9092", "kafka-03:9092"] #  topic: 'topic-log' #  version: 2.0.0 
--- 
apiVersion: apps/v1 
kind: DaemonSet  
metadata: name: filebeat namespace: elklabels: app: filebeat 
spec: selector: matchLabels: app: filebeat template: metadata: labels: app: filebeat spec: serviceAccountName: filebeat-accountcontainers: - name: filebeat image: elastic/filebeat:7.14.0args: [ "-c", "/etc/filebeat.yml", "-e", "-httpprof","0.0.0.0:6060" ] securityContext: runAsUser: 0 # If using Red Hat OpenShift uncomment this: #privileged: true resources: limits: memory: 1000Mi cpu: 1000m requests: memory: 100Mi cpu: 128m volumeMounts: - name: filebeat-config  mountPath: /etc/filebeat.yml subPath: filebeat.yml - name: filebeat-datamountPath: /usr/share/filebeat/data - name: docker-containers mountPath: /var/lib/docker/containersreadOnly: true - name: pods-logmountPath: /var/log/pods readOnly: true - name: containers-logmountPath: /var/log/containersreadOnly: true volumes: - name: filebeat-config configMap: name: filebeat-config - name: filebeat-data hostPath: path: /data/filebeat-data type: DirectoryOrCreate - name: docker-containers hostPath: path: /var/lib/docker/containers- name: pods-log hostPath: path: /var/log/pods- name: containers-log hostPath: path: /var/log/containers
kubectl apply -f filebeta.yml

查看 Pod

在这里插入图片描述
由于我测试环境的 k8s node 有三台,所以这里起了三个 filebeat

观察其中某个 filebeta 日志,是否启动成功:
在这里插入图片描述

三、ELK 环境测试

访问测试服务,产生日志:http://{k8s node ip}:31880/t1

然后查询当下所有 k8s 开头的索引:

GET /_cat/indices/k8s*?h=index

在这里插入图片描述

可以看到测试服务的索引已经生成。

3.1 kibana 日志查询

  1. 点击侧边栏 Discover

    在这里插入图片描述

  2. 然后在 Index patternsCreate an index pattern

    在这里插入图片描述

  3. 这里输入测试服务的索引 k8s-elk-elk-demo-2024.05.17 ,注意改成你环境下的名字,然后点击 Next step :

    在这里插入图片描述

  4. 然后时间字段可以选择 @timestamp :

    在这里插入图片描述

  5. 然后再次点击侧边栏 Discover 进到查询页面,使用介绍如下:

    在这里插入图片描述

  6. 例如查询包含 ERROR 的日志:

    在这里插入图片描述

    这里的 KQL 语法,在文章最后给了出常用语法说明。

3.2 kibana 日志监测

  1. 点击侧边栏 logs

    在这里插入图片描述

  2. 点击修改配置:

    在这里插入图片描述

  3. 增加 k8s-* 的监测,然后点击最后的 Apply

在这里插入图片描述

  1. 然后在 Stream 中可以查看日志:

    在这里插入图片描述

3.3 kibana 使用 ES DSL 查询日志

查询错误日志:

GET /k8s-elk-elk-demo-2024.05.17/_search
{"query": {"match": {"message": "java.lang.RuntimeException"}},"sort": [{"@timestamp": {"order": "desc"}}]
}

在这里插入图片描述

四、KQL 语法介绍

KQLKibana Query Language)是Kibana中用于搜索和过滤数据的查询语言。它是一种简单的、易于学习的语法,允许用户在不熟悉Elasticsearch的复杂查询DSL的情况下,也能够执行有效的数据搜索和过滤操作。

注意:KQL默认是大小写不敏感的。

4.1 关键字查询

例如:查询 message 字段中包括 hello word 的:

message:"hello word"

如果想要分词,可以不加双引号,这样包含 helloword 的也可以被检索出来:

message:hello word

4.2 逻辑查询

支持 orandnot查询,and的优先级高于or

message:error and kubernetes.pod.name: "elk-demo-6f8b4b7fd7-4xskf"
message:error and (kubernetes.node.hostname:node1 or kubernetes.node.name:node1)

4.3 范围查询

支持对数字和日志类型使用 < <= > >=

log.offset > 881576

4.4 Wildcard 查询

message:*error*

4.5 字段存在查询

message:*

4.6 字段不存在

not _exists_:level

或者

not level:*

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

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

相关文章

力扣654. 最大二叉树

Problem: 654. 最大二叉树 文章目录 题目描述思路复杂度Code 题目描述 思路 对于构造二叉树这类问题一般都是利用先、中、后序遍历&#xff0c;再将原始问题分解得出结果 1.定义递归函数build&#xff0c;每次将一个数组中的最大值作为当前子树的根节点构造二叉树&#xff1b;…

牛客NC391 快乐数【simple 模拟法 Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/293b9ddd48444fa493dd17da0feb192d 思路 直接模拟即可Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值…

Linux-应用编程学习笔记(二、文件I/O、标准I/O)

一、文件I/O基础 文件 I/O 指的是对文件的输入/输出操作&#xff0c;就是对文件的读写操作。Linux 下一切皆文件。 1.1 文件描述符 在 open函数执行成功的情况下&#xff0c; 会返回一个非负整数&#xff0c; 该返回值就是一个文件描述符&#xff08;file descriptor&#x…

解禁谷歌等浏览器禁止网站使用麦克等媒体设备

1、浏览器地址栏输入chrome://flags/ 微软的chromium内核的edge浏览器&#xff0c;既可以输入&#xff1a;chrome://flags/ &#xff0c;也可以输入edge://flags/ 2、打开后&#xff0c;界面如下 3、输入搜索&#xff0c;unsafe&#xff0c;并启用、输入需要启用的网址

对AI 感兴趣的小伙伴

如图&#xff0c;欢迎来玩儿&#xff01; 欢迎来玩儿

Python异常处理:打造你的代码防弹衣!

Hi&#xff0c;我是阿佑&#xff0c;上文咱们讲到——揭秘Python的魔法&#xff1a;装饰器的超能力大揭秘 ‍♂️✨&#xff0c;阿佑将带领大家通过精准捕获异常、使用with语句和上下文管理器、以及异常链等高级技巧来增强代码的健壮性。就像为代码穿上防弹衣&#xff0c;保护它…

生活小区火灾预警新篇章:泵吸式可燃气体报警器的检定与运用

在现代化的生活小区中&#xff0c;燃气设备广泛应用于居民的日常生活之中&#xff0c;但同时也带来了潜在的火灾风险。 可燃气体报警器作为一种安全监测设备&#xff0c;能够及时检测到燃气泄漏等安全隐患&#xff0c;并在达到预设的阈值时发出警报&#xff0c;提醒居民采取相…

SpringBoot Redis 扩展高级功能

环境&#xff1a;SpringBoot2.7.16 Redis6.2.1 1. Redis消息发布订阅 Spring Data 为 Redis 提供了专用的消息传递集成&#xff0c;其功能和命名与 Spring Framework 中的 JMS 集成类似。Redis 消息传递大致可分为两个功能区域&#xff1a; 信息发布 信息订阅 这是一个通常…

北斗短报文终端 | 什么是北斗短报文功能?如何实现北斗短报文通信?

北斗短报文功能是指通过北斗卫星进行短报文通信的功能。这种功能允许用户在没有移动通信信号覆盖的偏远山区、海洋、沙漠等地带&#xff0c;通过北斗短报文终端发送和接收文本信息&#xff0c;进行基本的数据通信。 北斗短报文功能是指北斗卫星导航系统特有的双向报文通信功能。…

urllib_post请求_百度翻译

打开百度翻译&#xff0c;并打开控制台&#xff0c;输入spider&#xff0c;然后在网络中找到对应的接口&#xff0c;可以看出&#xff0c;该url是post请求 在此案例中找到的接口为sug&#xff0c;依据为&#xff1a; 可以看到&#xff0c;传递的数据为kw : XXX&#xff0c; 所…

[Linux]服务管理

一.服务的概念&#xff0c;状态&#xff0c;查看系统服务 服务(service)本质就是进程 如(mysqld&#xff0c;sshd 防火墙等) 是运行在后台的&#xff0c;通常都会监听某个端口&#xff0c;等待其它程序的请求 -------比如mysqld&#xff0c;防火墙等&#xff0c;因此我们又称为…

3D瓦片地图组件上线|提供DEM数据接入,全方位呈现三维地图地形!

在用户调研中&#xff0c;我们了解到很多用户自身的可视化项目&#xff0c;需要在垂直空间上表现一些业务&#xff0c;例如&#xff1a;3D地形效果&#xff0c;数据底板建设等&#xff0c;而传统的地图效果不满足此用户需求。瓦片地图能够无限加载大地图&#xff0c;以更三维的…

【Linux】在Ubuntu 16.04上安装Gerrit + PostgreSQL + Apache服务

Gerrit是一个基于Git版本控制系统的运行于Web浏览器上的Code Review工具&#xff0c;本文叙述如何在Ubuntu 16.04上安装Gerrit服务。&#xff08;当然安装Gerrit的方法有很多&#xff0c;本文只是其中之一&#xff09; 文章目录 前提安装PostgreSQL数据库并创建用户下载、配置和…

【飞舞的花瓣】飞舞的花瓣代码||樱花代码||表白代码(完整代码)

关注微信公众号「ClassmateJie」有完整代码以及更多惊喜等待你的发现。 简介/效果展示 这段代码是一个HTML页面&#xff0c;其中包含一个canvas元素和相关的JavaScript代码。这个页面创建了一个飘落花瓣的动画效果。 代码【获取完整代码关注微信公众号「ClassmateJie」回复“…

一步将 CentOS 7.X 原地升级并迁移至 RHEL 7.9

《OpenShift / RHEL / DevSecOps 汇总目录》 在《在离线环境中将 CentOS 7.X 原地升级并迁移至 RHEL 7.9》一文中为了实现从 CentOS 7.X 原地升级并迁移至 RHEL 7.9&#xff0c;我们第一步先将一个测试环境 CentOS 7.5 升级到 CentOS 7.9&#xff0c;然后在第二步使用 convert2…

抖音运营_如何开抖店

截止20年8月&#xff0c;抖音的日活跃数高达6亿。 20年6月&#xff0c;上线抖店 &#xff08;抖音官方电商&#xff09; 一 抖店的定位和特色 1 一站式经营 帮助商家进行 商品交易、店铺管理、客户服务 等全链路的生意经营 2 多渠道拓展 抖音、今日头条、西瓜、抖音火山版…

【Python】用于发送电子邮件的标准库smtplib和构建邮件主体、添加附件、设置收件人的email

欢迎来到《小5讲堂》 这是《Python》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 插件介绍邮件代码扩展知识点文章推荐 插件介绍 smtplib 是 Pytho…

海外媒体发稿的关键步骤和投稿策略:如何撰写高质量的新闻稿?国外软文发布平台有哪些?

发布国外新闻稿件是一个涉及多步骤的过程&#xff0c;旨在确保您的新闻稿能够有效覆盖目标受众。以下是一些关键步骤和实用的技巧&#xff0c;帮助你实现海外媒体发稿。 1. 明确目标和受众 首先&#xff0c;明确您发布新闻稿的目标&#xff0c;是为了增加品牌曝光、推出新产品…

惊呆了!企业数字化转型竟如工厂生产?

在众多使用蚓链数字化生态系统解决方案实现数字化转型的企业&#xff0c;你能想象吗&#xff1f;如今的企业数字化转型&#xff0c;就如同一家工厂的生产过程&#xff01;数据成为了原材料&#xff0c;而数据资源则是场景化的零件&#xff0c;最终生产出满足市场需求的数据产品…

基于Kafka的日志采集

目录 前言 架构图 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 启动 二、部署filebeat 部署filebeat 添加配置文件 启动 三、部署kibana 部署kibana 修…