云采集(Logging:LoggingOperator的文章(图):容器化)
优采云 发布时间: 2022-01-12 01:02云采集(Logging:LoggingOperator的文章(图):容器化)
前言:
Logging Operator 的文章 去年拖了很久,本以为不会有进展。不过,最近在我的 KubeGems 项目中遇到需要处理日志可观察性部分的时候,重新研究了一下,所以就用这个系列的第三篇。
Logging Operator 是 BanzaiCloud 下云原生场景的开源 log采集 解决方案。2020年3月重构为v3版本,高效的fluentbit和丰富的底层插件flunetd,Logging Operator几乎完美适配kubernetes模式下的log采集场景。预计。去年偶然发现Rancher在2.5版本之后也采用了Logging Operator作为统一的日志解决方案,足以说明它正在被一些以Kubernetes为中心的管理平台所接受,并融入到内部(包括小白)。库贝宝石)。
作为前两篇文章的延续,本文主要讲小白最近使用Logging Operator解决用户需求的案例和感受,所以不打算花篇幅来描述它的架构和使用。有兴趣的同学可以通过小白的文章去Flip。
关于指标
在应用容器化的过程中,由于容器文件系统的临时性,开发者总是面临着将自己的日志文件放在磁盘上并输出stdout的困境。当研发将应用日志管理权交给平台时,意味着平台需要做的事情远比应用*敏*感*词*复杂得多采集。在众多需求中,有一天一位 SRE 同学问:“我们可以看到阿里云日志采集的实时率,我们需要为此定制质量监控指标。” 这个问题也让我警醒。当我们在私有云上工作时,从平台外部观察 log采集 管道内部一直处于信息缺失的盲点。幸运的是,
首先,我们定义日志的时候,可以让fluent bit(d)打开prometheus的采集
spec:
fluentdSpec:
metrics:
serviceMonitor: true
serviceMonitorConfig:
honorLabels: true // 打开honorLabels主要是为了保持组件原有的label,避免标签被覆盖。
fluentbitSpec:
metrics:
serviceMonitor: true
这里可以看到Logging Operator在采集端主要依赖ServiceMonitor进行服务发现。这里需要在集群内部运行 Prometheus Operator 来支持 CRD。如果集群内部没有改变资源类型,也可以使用Prometheus自带的服务发现机制完成指标发现和采集。
但是,这里只声明了 采集 端的指标条目。默认情况下,仅收录 Fluent bit(d) 的基本运行状态。如果要进一步监控日志率,则需要使用 Flunetd。早些年在谷歌的GKE采集器上还是用Fluentd做日志的时候,无意中看到的一个Prometheus插件配置(故意抄袭)引起了我的兴趣
@type prometheus
type counter
name logging_entry_count
desc Total number of log entries generated by either application containers or system components
container: $.kubernetes.container_name
pod: $.kubernetes.pod_name
该规则将匹配所有进入 Fluentd 的日志,并进入 Prometheus 的过滤器进行计数处理。统计信息被命名为logging_entry_count,日志中的一些元数据信息作为指标的标签来区分不同的容器。
由于需要解析日志的kubernetes元数据,所以需要Fluentd的kubernetes-metadata-filter插件来提取容器元数据。在 Logging Operator 中,Kubernetes 的元数据在 Fluent Bit 中解析,无需在 Fluentd 中添加此插件。
尽管 Google GKE 现在也将日志 采集器 替换为 Fluent Bit,但上述配置在 Logging Operator 中并没有“过时”。结合之前的经验,我们可以在租户的日志采集器(Flow / ClusterFlow)中引入Prometheus插件来分析日志率。其中最简单的做法如下:
apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: default
namespace: demo
spec:
- prometheus:
labels:
container: $.kubernetes.container_name
namespace: $.kubernetes.namespace_name
node: $.kubernetes.host
pod: $.kubernetes.pod_name
metrics:
- desc: Total number of log entries generated by either application containers
or system components
name: logging_entry_count
type: counter
globalOutputRefs:
- containers-console
match:
- select:
labels:
what.you.want: collect
上述指标存入 Prometheus 后,我们可以通过这条语句找出当前集群下日志采集器的应用率
sum by (pod) (rate(logging_entry_count[1m]))
此时,如果云平台是基于多租户多环境的架构,你甚至可以按租户环境和租户级别聚合日志率。
以上只是对日志整体速率的监控。如果我们需要统计日志中的具体内容或者日志的字节数,需要结合其他插件。目前Logging Operator支持的插件远不如Fluentd丰富,但是我们可以参考官方文档编写需要的插件并集成到Operator中。记录操作员开发人员手册
对于日志组件内部的监控和告警,Logging Operator 有自己的一套规则,可以在日志 CR 中启用。
spec:
fluentbitSpec:
metrics:
prometheusRules: true
fluentdSpec:
metrics:
prometheusRules: true
这里的prometheusRules也是Prometheus Operator管理的资源。如果集群中没有这样的资源类型,可以手动配置Prometheus的Rules
回到原来的问题,如果需要用日志的采集率作为应用的量化指标,可以使用logging_entry_count。
关于抽样
大多数情况下,日志架构不应该对业务日志采取一些不可控的策略,导致应用日志不完整,比如采样。显然,我也不建议您在现有架构中启用此功能。然而,有时,或者当一些魔术师无法有效控制“狂野之力”而疯狂输出时,平台可以为这种漂亮的应用程序采样解决方案。毕竟,保证整个日志通道的可用性是平台的第一要务。要考虑的因素。
Logging Operator 在日志采样中使用 Throttle 插件速率限制器。一句话总结这个插件,它为每个进入过滤器日志的管道引入了漏桶算法,允许它丢弃超过速率限制的日志。
apiVersion: logging.banzaicloud.io/v1beta1
kind: Flow
metadata:
name: default
namespace: demo
spec:
- throttle:
group_bucket_limit: 3000
group_bucket_period_s: 10
group_key: kubernetes.pod_name
globalOutputRefs:
- containers-console
match:
- select:
labels:
what.you.want: collect
日志的采样率由公式 group_bucket_limit / group_bucket_period_s 计算得出。当 group_key 中的 log rate 超过该值时,后续的日志将被丢弃。
由于 Throttle 没有使用令牌桶算法,所以不会有突发处理日志量 采集 的突发情况。关于日志放置
如前所述,对于所有基于容器的应用程序,日志记录的最佳实践是将日志定向到 stdout 和 stderr,但并非所有“魔术师”都遵循此约定,将文件记录到磁盘仍然是当今大多数研发的选择。. 虽然理论上容器的标准(错误)输出也是将日志流重定位到/var/log/containers下的日志文件,但还是受限于运行时配置或其他硬盘原因造成的不可控因素。
对于日志放置的场景,目前业界还没有统一的解决方案,但总结起来,其实有两种实现方式:
可以看出,上述两种方案中,都与Logging Operator无关。确实,目前的社区并没有针对这种场景的有效解决方案,但是按照它的思路,我们可以将日志文件转换成标准(错误)输出流,变相处理这个问题。
用tail给出一个直观的例子来说明上面的方案。
...
containers:
- args:
- -F
- /path/to/your/log/file.log
command:
- tail
image: busybox
name: stream-log-file-[name]
volumeMounts:
- mountPath: /path/to/your/log
name: mounted-log
...
虽然tail是一种极其简单粗暴的方法,无法解决日志轮转等问题,但它确实为Logging Operator在日志放置场景下提供了一种新的解决方案。虽然看起来和 sidecar 一样,但最大的不同是这个方案无缝兼容了 Logging Operator 现有的日志管道,日志经过 采集 后仍然可以在 flow 阶段进行处理。
总结
从自动化运维的角度来看,Logging Operator 确实有效解决了 Kubernetes 场景下复杂的日志架构和应用日志采集 问题,虽然目前对放置日志的支持还不够全面。但随着连接用户数量的增长,未来可能会有更好的解决当前问题的方法。然而,它确实是目前最好的云原生日志架构之一。