云原生日志采集管理方案--Logging Operator

本文涉及的产品
对象存储 OSS,20GB 3个月
阿里云盘企业版 CDE,企业版用户数5人 500GB空间
对象存储 OSS,恶意文件检测 1000次 1年
简介: Logging Operator是BanzaiCloud开源的一个云原生场日志采集方案,它整合了fluent 社区的两个开源日志采集器 FluentBit、Fluentd,以 operator 的方式自动化配置 k8s 日志采集pipeline。

背景

Fluentd/Fluent Bit作为云原生场景的可观测采集器,致力于打造云原生场景下的日志采集方案。Fluentd/Fluent Bit官方虽然提供了一些K8s的采集部署方案,但是总体来说自动化程度不高,操作也比较繁琐。所以也就催生出了各类Operator,比较有名的是Fluent Operator、Logging Operator,本文将重点介绍Logging Operator的原理及实战。

Logging Operator是BanzaiCloud开源的一个云原生场日志采集方案,它整合了fluent 社区的两个开源日志采集器 FluentBit、Fluentd,以 operator 的方式自动化配置 k8s 日志采集pipeline。

Logging Operator原理

Logging operator 可以自动部署和配置Kubernetes 日志采集pipeline。该operator会在每个节点上部署Fluent Bit DaemonSet,用于从节点文件系统中收集容器和应用程序日志;同时,Fluent Bit会查询 Kubernetes API 并使用有关 pod 的元数据丰富日志,并将日志和元数据都传输到 Fluentd。Fluentd接收后,经过过滤处理,最终传输给第三方存储系统。 整个日志的采集、传输过程始终在经过身份验证和加密的通道上传输。

使用者可以配置如下的CRD配置Logging operator:

  • logging:定义了FleuntBit、Fleuntd的基础配置;可以指定controlNamespace。
  • output:定义了namespace级别的日志输出配置。
  • flow:定义了namespaces级别的日志filtersoutputs流
  • clusteroutput:定义了cluster级别的日志输出配置。
  • clusterflow:定义了cluster级别的日志filtersoutputs流

CRD详解

flow/clusterflow

  • 作用:用来处理日志流的,决定了数据从哪里采集、如何过滤、路由分发。
  • match定义了哪些容器的日志会被采集。可以通过select、exclude表示选择或排除;字段可以是namespaces、labels、container_names等。
  • filters为Logging Operator的日志处理插件。常见的有:Parser(支持nginx、apache2、syslog、csv、json等)、Prometheus(可以对日志进行统计)、Tag Normaliser(tag修改器)等。
  • 示例1:将default命名空间下标签为app=nginx的容器日志,采集后按照nginx日志格式解析,最终日志的 tag 在 fluentd 最终汇总时设置为${namespace_name}.${pod_name}.${container_name} 格式。

apiVersion: logging.banzaicloud.io/v1beta1

kind: Flow  

metadata:

 name: default-flow

 namespace: default ##定义收集日志的命名空间

spec:

 filters:  ##定义过滤器,一个flow可以定义一个或者多个

   - parser:

       remove_key_name_field: true

       parse: ##parse支持apache2, apache_error, nginx, syslog, csv, tsv, ltsv, json, multiline, none, logfmt类型解析

         type: nginx

   - tag_normaliser:

       format: ${namespace_name}.${pod_name}.${container_name} ##在fluentd里面使用${namespace_name}.${pod_name}.${container_name}的格式

 localOutputRefs:

   - "elasticsearch-output" ## 定义Output

 match:  ## Kubernetes标签来定义哪些日志需要被采集

   - select:

       labels: ## 使用标签匹配采集日志

         app: nginx

  • 示例2: Prometheus 插件

apiVersion: logging.banzaicloud.io/v1beta1

kind: Flow  

metadata:

 name: default-flow

 namespace: default ##定义收集日志的命名空间

spec:

 filters:

   - parser:

       remove_key_name_field: true

       parse: ##parse支持apache2, apache_error, nginx, syslog, csv, tsv, ltsv, json, multiline, none, logfmt类型解析

         type: nginx ##采集日志按照Nginx格式进行处理

   - prometheus: ##Pormetheus插件

       metrics:

         - desc: The total number of nginx in log. ##指标说明

           name: nginx_log_total_counter  ##指标名称

           type: counter ##指标Prometheus类型

           labels: ## 指标标签

             app: nginx

       labels: ##指标标签

         host: ${hostname}

         tag: ${tag}

         namespace: $.kubernetes.namespaces

   - tag_normaliser:

       format: ${namespace_name}.${pod_name}.${container_name} ##在fluentd里面使用${namespace_name}.${pod_name}.${container_name}的格式

 localOutputRefs:

   - "es-output" ## 定义Output

 match:  ## Kubernetes标签来定义哪些日志需要被采集

   - select:

       labels: ## 使用标签匹配采集日志

         app: nginx

output/clusteroutput

  • 作用:表示处理完成的日志应该输出到哪里。
  • 示例:Output-Kafka配置

apiVersion: logging.banzaicloud.io/v1beta1

kind: Output  

metadata:

 name: kafka-output

spec:

 kafka:

   brokers: kafka-headless.kafka.svc.cluster.local:29092 ##kafka地址

   default_topic: topic

   topic_key: kafka-output ##kafka topic名称;

   sasl_over_ssl: false ##是否使用ssl

   format:

     type: json  ##类型

   buffer: ##发送buff配置

     tags: topic

     timekey: 1m

     timekey_wait: 30s

     timekey_use_utc: true

Logging Operator实战:Nginx Access Logs访问日志采集到Kafka

  • 安装logging-operator

$ helm repo add banzaicloud-stable https://kubernetes-charts.banzaicloud.com

$ helm repo update

$ helm upgrade --install --wait --create-namespace --namespace logging logging-operator banzaicloud-stable/logging-operator


$ kubectl get deployment -n logging

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE

logging-operator             1/1     1            1           10h

  • 安装Demo应用

$ helm upgrade --install --wait --create-namespace --namespace logging logging-demo banzaicloud-stable/logging-demo \

 --set "kafka.enabled=True"

  • 部署logging CRD

# 配置

$ kubectl -n logging apply -f - <<"EOF"

apiVersion: logging.banzaicloud.io/v1beta1

kind: Logging

metadata:

 name: default-logging-simple

spec:

 fluentd: {}

 fluentbit: {}

 controlNamespace: logging

EOF


# 结果查看

## 生成DaemonSet的fluentbit

$ kubectl get ds -n logging

NAME                               DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE

default-logging-simple-fluentbit   2         2         2       2            2           <none>          9h


## 生成StatefulSet的fluentd

$ kubectl get statefulset -n logging

NAME                             READY   AGE

default-logging-simple-fluentd   1/1     9h


## pod信息

$ kubectl get pods -n logging

NAME                                                  READY   STATUS      RESTARTS   AGE

default-logging-simple-fluentbit-n9b25                1/1     Running     1          9h

default-logging-simple-fluentbit-rdzqk                1/1     Running     0          9h

default-logging-simple-fluentd-0                      2/2     Running     0          9h


## fluentbit保密字典配置。会将采集的日志输出到default-logging-simple-fluentd中。

$ kubectl get secret default-logging-simple-fluentbit -n logging -o jsonpath='{.data.fluent-bit\.conf}'|base64 --decode

[SERVICE]

   Flush        1

   Grace        5

   Daemon       Off

   Log_Level    info

   Parsers_File parsers.conf

   Coro_Stack_Size    24576

   storage.path  /buffers


[INPUT]

   Name         tail

   DB  /tail-db/tail-containers-state.db

   Mem_Buf_Limit  5MB

   Parser  docker

   Path  /var/log/containers/*.log

   Refresh_Interval  5

   Skip_Long_Lines  On

   Tag  kubernetes.*

[FILTER]

   Name        kubernetes

   Buffer_Size  0

   Kube_CA_File  /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

   Kube_Tag_Prefix  kubernetes.var.log.containers

   Kube_Token_File  /var/run/secrets/kubernetes.io/serviceaccount/token

   Kube_URL  https://kubernetes.default.svc:443

   Match  kubernetes.*

   Merge_Log  On

   Use_Kubelet  Off


[OUTPUT]

   Name          forward

   Match         *

   Host          default-logging-simple-fluentd.logging.svc.cluster.local

   Port          24240


   Retry_Limit  False

  • 配置output、flow CRD

$ kubectl -n logging apply -f - <<"EOF"

apiVersion: logging.banzaicloud.io/v1beta1

kind: Output

metadata:

name: kafka-output

spec:

kafka:

  brokers: kafka-headless.kafka.svc.cluster.local:29092

  default_topic: topic

  format:

    type: json

  buffer:

    tags: topic

    timekey: 1m

    timekey_wait: 30s

    timekey_use_utc: true

EOF


$ kubectl -n logging apply -f - <<"EOF"

apiVersion: logging.banzaicloud.io/v1beta1

kind: Flow

metadata:

 name: kafka-flow

spec:

 filters:

   - tag_normaliser: {}

   - parser:

       remove_key_name_field: true

       reserve_data: true

       parse:

         type: nginx

 match:

   - select:

       labels:

         app.kubernetes.io/name: log-generator

 localOutputRefs:

   - kafka-output

EOF


// 进入fluentd容器,查看配置文件。说明已经完整转发到kafka的配置。

$ cat fluentd/app-config/fluentd.conf

<source>

 @type forward

 @id main_forward

 bind 0.0.0.0

 port 24240

</source>

<label @bd16f9a1a7328cf1691828de4bc6fc89>

 <match kubernetes.**>

   @type tag_normaliser

   @id flow:logging:kafka-flow:0

   format ${namespace_name}.${pod_name}.${container_name}

 </match>

 <filter **>

   @type parser

   @id flow:logging:kafka-flow:1

   key_name log

   remove_key_name_field true

   reserve_data true

   <parse>

     @type nginx

   </parse>

 </filter>

 <match **>

   @type kafka2

   @id flow:logging:kafka-flow:output:logging:kafka-output

   brokers .....

   default_topic logging-operator-test

   sasl_over_ssl false

   <buffer topic>

     @type file

     chunk_limit_size 8MB

     path /buffers/flow:logging:kafka-flow:output:logging:kafka-output.*.buffer

     retry_forever true

     timekey 1m

     timekey_use_utc true

     timekey_wait 30s

   </buffer>

   <format>

     @type json

   </format>

 </match>

</label>

...

  • 部署demo

kubectl -n logging apply -f - <<"EOF"

apiVersion: apps/v1

kind: Deployment

metadata:

name: log-generator

spec:

selector:

  matchLabels:

    app.kubernetes.io/name: log-generator

replicas: 1

template:

  metadata:

    labels:

      app.kubernetes.io/name: log-generator

  spec:

    containers:

    - name: nginx

      image: banzaicloud/log-generator:0.3.2

EOF

  • 结果验证

参考资料

Logging Operator官方文档

漫谈三种k8s日志架构以及开源选择

Logging Operator - 优雅的云原生日志管理方案

Rancher 2.6 全新 Logging 快速入门


关于iLogtail

iLogtail作为阿里云SLS提供的可观测数据采集器,可以运行在服务器、容器、K8s、嵌入式等多种环境,支持采集数百种可观测数据(日志、监控、Trace、事件等),已经有千万级的安装量。目前,iLogtail已正式开源,欢迎使用及参与共建。

GitHub:https://github.com/alibaba/ilogtail

社区版文档:https://ilogtail.gitbook.io/ilogtail-docs/about/readme

企业版官网:https://help.aliyun.com/document_detail/65018.html

钉钉群:iLogtail社区

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
18天前
|
消息中间件 存储 监控
微服务日志监控的挑战及应对方案
【10月更文挑战第23天】微服务化带来模块独立与快速扩展,但也使得日志监控复杂。日志作用包括业务记录、异常追踪和性能定位。
|
1月前
|
存储 数据采集 分布式计算
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
44 1
|
2月前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
3月前
|
存储 Prometheus Kubernetes
在K8S中,如何收集K8S日志?有哪些方案?
在K8S中,如何收集K8S日志?有哪些方案?
|
3月前
|
存储 Kubernetes Java
在k8S中,容器内日志是怎么采集的?
在k8S中,容器内日志是怎么采集的?
|
3月前
|
数据采集 监控 Kubernetes
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
Job类日志采集问题之iLogtail以减小容器发现和开始采集的延时如何优化
|
3月前
|
数据采集 Kubernetes Java
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
Job类日志采集问题之在日志中添加容器的元信息标签,如何操作
|
3月前
|
存储 容器
Job类日志采集问题之DaemonSet采集方式的参数以减小采集延时如何调整
Job类日志采集问题之DaemonSet采集方式的参数以减小采集延时如何调整
|
3月前
|
容器
Job类日志采集问题之ECI产品采集方式对于弹性扩缩容是如何支持的
Job类日志采集问题之ECI产品采集方式对于弹性扩缩容是如何支持的
|
3月前
|
存储 数据采集 容器
Job类日志采集问题之DaemonSet采集方式在Job日志采集上如何表现
Job类日志采集问题之DaemonSet采集方式在Job日志采集上如何表现

相关产品

  • 日志服务