当前位置: 首页 > news >正文

kubernetes日志收集 fluent-operator 动态索引名的实现

文章目录

    • 按照服务名区分索引名
      • 1.修改fluent-operator,让其支持logstash_prefix_key
      • 2.让它能获取app name作为服务名
      • 3. 拼接索引名
      • 4. 应用变更

发自个人博客: https://uublog.com/article/20230510/kubernetes-fluent-operator-dynamic-index-name/

日志收集,考虑到我们没有主动上报日志,格式也不太统一,容器化的时候,对于我们而言采集容器标准输出的日志是更快捷达到目的的方式。

大致对比了filebeat、fluentd、fluentbit、vector、logstash后,锁定了flientbit。

虽然它功能不是最强大的,但是基本功能能满足我们的业务需求,采集输入端多样化,也能做简单的filter,支持output的端也很丰富。其次,它吃资源比较少,性能也不错。

我们只需要它收集标准输出的日志,输出到es即可。

而在k8s中,有kubesphere共献给fluent的fluent-operator。该opeator提供了fluentbit only、fluentd only、fluentbit+fluentd 这几种采集方式。对于我们而言,就fluentbit 就够了。

我选择了helm方式安装,下载了它chart (https://github.com/fluent/fluent-operator/releases/download/v2.2.0/fluent-operator.tgz)包,解压到/app/fluent-operator/ ,直接修改里面values.yaml,这样好方便未来管理自己的部署配置。

简单按照文档,修改了fluentbit的input和output后,直接安装即可

helm upgrade --install fluent-operator --create-namespace -n fluent /app/fluent-operator/ --set containerRuntime=containerd

按照服务名区分索引名

日志是能收集了,但是所有的服务的日志,当天都放到一个索引,类似 “k8s-logs-<yyyy.mm.dd>” 这样的索引中。本地还好,如果生产环境的话,那一天单个索引就十分庞大了。而且对于不同服务日志保留天数做差异化保留的时候也不好处理,也不好直观展示各个服务日志大小。

所以能按照k8s-<service-name>-<yyyy.mm.dd>格式的话,对我们会更为理想点。截止目前的版本,没有现成的配置可以实现这个。经过研究,可以利用fluentbit的 logstash_prefix_key 这个来实现。logstash_prefix是固定的前缀,logstash_prefix_key则可以动态读取 key来作为索引名。

1.修改fluent-operator,让其支持logstash_prefix_key

经过测试,fluent-operator当前版本的模板并没有对该字段进行处理,所以要进行修改让它支持这个字段。

我需要output到es,所以我就修改了es相关的output,其它输出源的可以自己检查下。

修改 ./templates/fluentbit-output-elasticsearch.yaml

在Values.fluentbit.output.es.logstashPrefix之后增加 .Values.fluentbit.output.es.logstashPrefixKey 这段的配置,如下:

{{- if .Values.fluentbit.output.es.logstashPrefix }}logstashPrefix: {{ .Values.fluentbit.output.es.logstashPrefix | default "ks-logstash-log" | quote }}
{{- end }}
{{- if .Values.fluentbit.output.es.logstashPrefixKey }}logstashPrefixKey: {{ .Values.fluentbit.output.es.logstashPrefixKey | default "ks-logstash-log-key" | quote }}
{{- end }}

2.让它能获取app name作为服务名

./values.yaml 修改fluentbit部分,开启kubernetes labels,因为labels的app标签就是我们的服务名。

filter:kubernetes:enable: truelabels: true

3. 拼接索引名

由于logstash_prefix_key只能接受 key,且不支持嵌套的对象的key。

举个直观的例子,假设你的对象是这样的:

{"file": "systemd.log","kubernetes": {"labels": {"app": "demo-service"}}
}

k8s-$kubernets["labels"]["app"] 和 像 $kubernets["labels"]["app"] 这样的值,是取不到任何内容的。像上面的例子,只接受 $file 这个值。

所以这里要实现我们的目标,我们得自己拼接出一个新的key,作为索引名。类似下面:

{"file": "systemd.log","app_name": "k8s-demo-service","kubernetes": {"labels": {"app": "demo-service"}}
}

我是这样实现的,利用lua的filter,通过取出kubernetes的labels,拼接新的值。

我修改的是 cat ./templates/fluentbit-containerd-config.yaml 增加了一个 add_k8s_app_name_field 函数

{{- if .Values.Kubernetes -}}
{{- if .Values.fluentbit.enable -}}
{{- if .Values.fluentbit.filter.containerd.enable -}}
apiVersion: v1
kind: ConfigMap
metadata:name: fluent-bit-containerd-config
data:containerd.lua: |function containerd( tag, timestamp, record)if(record["logtag"]~=nil)thentimeStr = os.date("!*t",  timestamp["sec"])t = string.format("%4d-%02d-%02dT%02d:%02d:%02d.%sZ",timeStr["year"], timeStr["month"], timeStr["day"],timeStr["hour"], timeStr["min"], timeStr["sec"],timestamp["nsec"]);record["time"] = t;record["log"] = record["message"];record["message"] =  nil;return 1, timestamp, recordelsereturn 0,timestamp,recordendendfunction add_k8s_app_name_field(tag, timestamp, record)retcode = 0prefix = 'k8s' app_name = record['kubernetes']['labels']['app']if  app_name ~= nil thenapp_name = prefix .. '-' .. app_nameif app_name ~= nil thenrecord['app_name'] = app_nameretcode = 2endendreturn retcode, timestamp, recordend
{{- end }}
{{- end }}
{{- end }}

修改 templates/fluentbit-clusterfilter-kubernetes.yaml 增加新增的lua filter函数 对kubernetes标签进行处理

cat templates/fluentbit-clusterfilter-kubernetes.yaml

{{- if .Values.Kubernetes -}}
{{- if .Values.fluentbit.enable -}}
{{- if .Values.fluentbit.filter.kubernetes.enable -}}
apiVersion: fluentbit.fluent.io/v1alpha2
kind: ClusterFilter
metadata:name: kuberneteslabels:fluentbit.fluent.io/enabled: "true"fluentbit.fluent.io/component: logging
spec:match: kube.*filters:- kubernetes:kubeURL: https://kubernetes.default.svc:443kubeCAFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtkubeTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token{{- $params := omit .Values.fluentbit.filter.kubernetes "enable" }}{{- if .Values.fluentbit.output.stdout.enable }}{{- $_ := set $params "k8sLoggingExclude" true -}}{{- end }}{{- with $params }}{{- . | toYaml | nindent 6 }}{{- end }}- lua:script:key: containerd.luaname: fluent-bit-containerd-configcall: add_k8s_app_name_fieldtimeAsTable: true- nest:operation: liftnestedUnder: kubernetesaddPrefix: kubernetes_- modify:rules:- remove: stream- remove: kubernetes_pod_id- remove: kubernetes_docker_id- remove: kubernetes_container_hash- remove: kubernetes_labels- nest:operation: nestwildcard:- kubernetes_*nestUnder: kubernetesremovePrefix: kubernetes_
{{- end }}
{{- end }}
{{- end }}

主要增加了

- lua:script:key: containerd.luaname: fluent-bit-containerd-configcall: add_k8s_app_name_fieldtimeAsTable: true

到这里基本就满足所有的条件了,为了不影响systemd的日志收集和归类,也给它的lua filter增加app_name字段.

./templates/fluentbit-lua-config.yaml

new_record["app_name"] = "systemd"

经过前面的修改后,只要在values.yaml 设置 fluentbit.output.es.logstashPrefixKey=”$app_name” 即可

4. 应用变更

我修改过的values.yaml,去除了无关部分后主要如下:

Kubernetes: true
fluentbit:crdsEnable: trueenable: trueimage:repository: "hub.xxxx.com/library/fluent-bit"tag: "v2.0.11"input:tail:enable: truerefreshIntervalSeconds: 10memBufLimit: 50MBpath: "/var/log/containers/*.log"skipLongLines: falsesystemd:enable: truepath: "/var/log/journal"includeKubelet: trueoutput:es:enable: true# 如果多个host的话,用hostshost: "es.xxx.local"port: 9200logstashFormat: truelogstashPrefixKey: "$app_name"filter:kubernetes:enable: truelabels: trueannotations: falsek8sLoggingExclude: truecontainerd:enable: truesystemd:enable: true

再来helm更新一下,搞定

helm upgrade --install fluent-operator --create-namespace -n fluent /app/fluent-operator/ --set containerRuntime=containerd

效果如下:

yellow open k8s-kiali-2023.05.10                iWEHK0gKR6GoPKjO3gH6Eg 1 1      30      0 105.9kb 105.9kb
yellow open k8s-nginx-deploy-2023.05.10         OCzPIKWgRneSn27J-o4k9g 1 1      16      0  76.3kb  76.3kb
yellow open k8s-istiod-2023.05.10               GlA1dI7aQDqPFD-5ZMX6iw 1 1     797      0 329.5kb 329.5kb
yellow open k8s-reviews-2023.05.10              41Ifiq3cTQGBKdJ4Fn2MJQ 1 1      18      0  86.6kb  86.6kb

相关文章:

kubernetes日志收集 fluent-operator 动态索引名的实现

文章目录 按照服务名区分索引名1.修改fluent-operator&#xff0c;让其支持logstash_prefix_key2.让它能获取app name作为服务名3. 拼接索引名4. 应用变更 发自个人博客&#xff1a; https://uublog.com/article/20230510/kubernetes-fluent-operator-dynamic-index-name/ 日志…...

pip换源

windows环境下&#xff1a; 比如windows账号是 admin 那么建立 admin主目录下的 pip子目录&#xff0c;在此pip子目录下建立pip的配置文件&#xff1a;pip.ini c:\users\admin\pip\pip.ini # coding: GBK [global] index-url https://pypi.tuna.tsinghua.edu.cn/simple [ins…...

7.(数据结构)堆

7.1 相关概念 堆&#xff08;Heap&#xff09;在计算机科学中是一种特殊的数据结构&#xff0c;它通常被实现为一个可以看作完全二叉树的数组对象。以下是一些关于堆的基本概念&#xff1a; 数据结构&#xff1a; 堆是一个优先队列的抽象数据类型实现&#xff0c;通过完全二叉树…...

AWS Elastic Beanstalk通过应用负载均衡配置https

接上一篇&#xff0c;今天说说怎么通过AWS Elastic Beanstalk提供的应用负载均衡配置https。 首先创建应用和环境&#xff0c;这里应用可以使用上一篇文章中使用的demo应用&#xff08;只需要package.json和app.js文件&#xff09; 创建环境的时候&#xff0c;确认下面两个参…...

AC自动机:文本搜索的加速器

在数字化时代&#xff0c;文本数据的海洋浩瀚无垠。我们经常需要在这些数据中迅速找到特定的信息&#xff0c;比如在日志文件中查找异常、在海量文本中检索关键词&#xff0c;或是在编译代码时识别语法结构。这时候&#xff0c;AC自动机&#xff08;Aho-Corasick自动机&#xf…...

备战蓝桥杯---基础算法刷题1

最近在忙学校官网上的题&#xff0c;就借此记录分享一下有价值的题&#xff1a; 1.注意枚举角度 如果我们就对于不同的k常规的枚举&#xff0c;复杂度直接炸了。 于是我们考虑换一个角度&#xff0c;我们不妨从1开始枚举因子&#xff0c;我们记录下他的倍数的个数sum个&#…...

探索 Flutter 中的动画:使用 flutter_animate

在移动应用开发中&#xff0c;动画是提升用户体验和吸引用户注意力的关键要素之一。Flutter 作为一种跨平台的移动应用开发框架&#xff0c;提供了丰富而灵活的动画支持。其中&#xff0c;flutter_animate 是一个强大的库&#xff0c;它为 Flutter 开发者提供了简单易用的方式来…...

装机容量对光伏发电量的影响有多大?如何通过装机容量计算发电量?

光伏行业得益于全球对环保和可持续发展的重视&#xff0c;得到了快速的发展。众所周知&#xff0c;光伏电站的收益受发电量的影响&#xff0c;发电量越大收益越高&#xff0c;但发电量其实受装机容量的影响。 一、装机容量对发电量的影响 光伏发电的核心就是发电板&#xff0…...

软考37-上午题-【数据库】-数据模型、数据库的三级模式和二级映像

一、考情简介 上午题&#xff1a;6分——6道选择题 下午题&#xff1a;15分——一道分析题 E-R图、关系模式&#xff1a;下午考试必考&#xff01;&#xff01;&#xff01;&#xff08;编制也要考&#xff01;&#xff09; 二、数据模型 数据模型是对现实世界数据特征的抽象…...

06 分频器设计

分频器简介 实现分频一般有两种方法&#xff0c;一种方法是直接使用 PLL 进行分频&#xff0c;比如在 FPGA 或者 ASIC 设计中&#xff0c;都可以直接使用 PLL 进行分频。但是这种分频有时候受限于 PLL 本身的特性&#xff0c;无法得到频率很低的时钟信号&#xff0c;比如输入 …...

力扣hot100题解(python版7-9题)

7、接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,…...

ECMAScript 6+ 新特性 ( 四 ) 迭代器 与 生成器

2.14.迭代器 2.14.1.for…of for...of 是 JavaScript ES6 引入的一种新的循环结构&#xff0c;&#xff0c;用于遍历可迭代对象&#xff08;Iterable objects&#xff09;的每个元素。 它可以自动调用目标对象的迭代器接口&#xff0c;并按顺序逐个访问集合中的每个值。 它…...

【MySQL】事务的一致性究竟怎么理解?

众所周知&#xff0c;事务有四大特性&#xff1a;原子性、一致性、隔离性、持久性&#xff0c;除了一致性&#xff0c;其他三类特性都很好理解。而关于一致性的解释有点让人头疼&#xff0c;我查了很多文章&#xff0c;大多类似&#xff1a;事务的执行必须使数据库处于一致状态…...

证件照(兼容H5,APP,小程序)

证件照由uniappuyui开发完成&#xff0c;并同时兼容H5、App、微信小程序、支付宝小程序&#xff0c;其他端暂未测试。 先看部分效果图吧具体可以下方复制链接体验demo 首页代码 <template><view class""><view class"uy-m-x-30 uy-m-b-20"…...

pytorch-textregression,中文文本回归实践,支持多值输出

pytorch-textregression&#xff0c;中文文本回归实践&#xff0c;支持多值输出 pytorch-textregression是一个以pytorch和transformers为基础&#xff0c;专注于中文文本回归的轻量级自然语言处理工具&#xff0c;支持多值回归等。 目录 数据使用方式paper参考 项目地址 py…...

go语言学而思【持续更新】

问题&#xff1a;在Go语言中nil是什么意思&#xff1f; 答&#xff1a;在Go语言中&#xff0c;nil是一个预声明的标识符&#xff0c;用于表示某些类型的零值。它可以被用作以下类型的零值&#xff1a; 指针&#xff08;Pointer&#xff09;切片&#xff08;Slice&#xff09;…...

LVS-NAT之VMNET环境搭建

目录 搭建拓扑图 搭建规划 VMNET0 搭建 VMNET2 搭建 LVS端增加网卡 搭建拓扑图: 搭建规划: CLIENT(servera): VMNET0 LVS(serverb): VMNET0 VMNET2 WEB1(serverd): VMNET2 WEB2(servere): VMNET2 VMNE…...

[TCP] TCP/IP 基础知识词典(2)

我想统计一下&#xff0c;TCP/IP 尤其是TCP协议&#xff0c;能搜到的常见的问题&#xff0c;整理起来&#xff0c;关键词添加在目录中&#xff0c;便于以后查阅。 目前预计整理共3篇&#xff1a; [TCP] TCP/IP 基础知识问答 &#xff1a;基础知识 [TCP] TCP/IP 基础知识问答&…...

【牛牛送书 | 第四期】《高效使用Redis:一书学透数据存储与高可用集群》带你快速学习使用Redis

前言&#xff1a; 当今互联网技术日新月异&#xff0c;随着数据量的爆炸式增长&#xff0c;如何高效地存储和管理数据成为了每个公司都必须面对的挑战。与此同时&#xff0c;用户对于应用程序的响应速度和稳定性要求也越来越高。在这个背景下&#xff0c;Redis 作为一个…...

Threejs 实现3D影像地图,Json地图,地图下钻

1.使用threejs实现3D影像地图效果&#xff0c;整体效果看起来还可以&#xff0c;底层抽象了基类&#xff0c;实现了通用&#xff0c;对任意省份&#xff0c;城市都可以只替换数据&#xff0c;即可轻松实现效果。 效果如下&#xff1a; 链接https://www.bilibili.com/video/BV1…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...