解决方案:KubeSphere 多行日志采集方案深度探索

优采云 发布时间: 2022-11-24 02:34

  解决方案:KubeSphere 多行日志采集方案深度探索

  ❝

  作者:大飞哥,CVTE视源股份运维工程师,KubeSphere用户委员会广州站主任,KubeSphere大使。

  采集

订单记录

  日志采集通常采用EFK架构,即ElasticSearch、Filebeat、Kibana。这是一个非常成熟的主机日志采集

方案,但是容器日志采集

的整体方案要复杂得多。我们现在面临的需求是采集

容器中的存储日志。

  容器日志有两种类型:标准输出日志和刷新日志。应用程序在容器的标准输出STDOUT中打印日志,标准输出日志由容器运行时(Docker或Containerd)写入容器日志文件,最后由采集

器导出。本日志打印合集是业界推荐的方案。但是,对于日志直接放到磁盘而不打印标准输出的情况,业界最常见的解决方案是使用Sidecar将日志采集

到磁盘,将日志打印到容器的标准输出,然后使用标准输出日志采集

方式输出。

  对于KubeSphere用户,只需要两步:首先在项目中开启卷上的日志采集

,其次在工作负载中配置磁盘文件的路径。具体操作如下图所示。

  以上两步会自动将Filebeat Sidecar作为logging-agent注入到容器中,并在容器的标准输出中打印出磁盘日志。可以通过 ConfigMap 修改 Filebeat 配置。

  $ kubectl get cm -n kubesphere-logging-system logsidecar-injector-configmap -o yaml<br />

  ## Filebeat 配置<br />filebeat.inputs:<br />- type: log<br />  enabled: true<br />  paths:<br />  {{range .Paths}}<br />  - {{.}}<br />  {{end}}<br />output.console:<br />  codec.format:<br />    string: '%{[log.file.path]} %{[message]}'<br />logging.level: warning<br />

  接入第三方日志服务

  KubeSphere默认将日志采集

到集群内置的Elasticsearch中,数据存储周期为7天,显然无法满足生产服务180天的日志存储需求。企业运维团队会建立一个集中的日志服务,将集群中的日志接入第三方日志服务是必然的选择。让我们看看它是如何工作的。

  上面提到,当容器运行时,标准输出日志会写入到集群节点的日志文件中。Linux系统默认为/var/log/containers/*.log。KubeSphere 使用 FluentBit 以 DemonSet 的形式采集

每个集群节点上的日志,由 FluentBit 输出到 ElasticSearch 服务。具体配置请参考以下两个配置:

  $ kubectl get Input -n kubesphere-logging-system tail -o yaml<br />$ kubectl get Output -n kubesphere-logging-system es -o yaml<br />

  如果我们将日志导出到第三方日志服务,我们需要自定义 FluentBit 输入和输出。使用tail插件采集

/var/log/containers/flux-wms-*.log文件中的日志输出到Kafka。可以参考如下配置:

  

" />

  ---<br />apiVersion: logging.kubesphere.io/v1alpha2<br />kind: Input<br />metadata:<br />  labels:<br />    logging.kubesphere.io/component: logging<br />    logging.kubesphere.io/enabled: "true"<br />  name: kafka-flux-wms<br />  namespace: kubesphere-logging-system<br />spec:<br />  tail:<br />    db: /fluent-bit/tail/pos.db<br />    dbSync: Normal<br />    memBufLimit: 5MB<br />    path: /var/log/containers/flux-wms-*.log<br />    refreshIntervalSeconds: 10<br />    tag: fluxwms.*<br />---<br />apiVersion: logging.kubesphere.io/v1alpha2<br />kind: Output<br />metadata:<br />  annotations:<br />    kubesphere.io/creator: admin<br />  labels:<br />    logging.kubesphere.io/component: logging<br />    logging.kubesphere.io/enabled: "true"<br />  name: kafka-flux-wms<br />  namespace: kubesphere-logging-system<br />spec:<br />  kafka:<br />    brokers: xxx.xxx.xxx.xxx:9092<br />    topics: my-topic<br />  match: fluxwms.*<br />

  ❝

  值得注意的是,目前 FluentBit 不支持 Kafka 身份验证。

  多行日志的尴尬

  本来以为到此为止一切都还好,结果在消费kafka日志的时候,突然看到有些日志被拆解了,不忍心看。为了支持多行日志,直观的想法是一个组件一个组件地向前检查。

  ❝

  前面有坑,请仔细阅读。

  配置 FluentBit 以支持多行日志

  FluentBit支持多行日志,需要配置Parser,通过parserFirstline指定日志Parser,解析出多行日志块的第一行。官方参考文档[1],Parser regular expression,取决于Filebeat日志输出格式,可以参考上面或者直接看这段:string: '%{[log.file.path]} %{[message] }'。

  ---<br />apiVersion: logging.kubesphere.io/v1alpha2<br />kind: Input<br />metadata:<br />  labels:<br />    logging.kubesphere.io/component: logging<br />    logging.kubesphere.io/enabled: "true"<br />  name: kafka-flux-wms<br />  namespace: kubesphere-logging-system<br />spec:<br />  tail:<br />    db: /fluent-bit/tail/pos.db<br />    dbSync: Normal<br />    memBufLimit: 5MB<br />    path: /var/log/containers/flux-wms-*.log<br />    multiline: true<br />    parserFirstline: kafka-flux-wms<br />    refreshIntervalSeconds: 10<br />    tag: fluxwms.*<br />---<br />apiVersion: logging.kubesphere.io/v1alpha2<br />kind: Parser<br />metadata:<br />  labels:<br />    logging.kubesphere.io/component: logging<br />    logging.kubesphere.io/enabled: "true"<br />  name: kafka-flux-wms<br />  namespace: kubesphere-logging-system<br />spec:<br />  regex:<br />    regex: '^\/data\/business-logs\/[^\s]*'<br />

  配置Filebeat支持多行日志

  查看 Kakfka 消息,多行日志仍然是拆分的。Filebeat 不支持多行日志吗?在整个投递日志采集链中,只要有一个环节不支持多行日志,结果就不会像预期的那样。查看项目原创

日志文件,发现多行日志以时间格式开头,于是Filebeat增加了如下配置:

  filebeat.inputs:<br />- type: log<br />  enabled: true<br />  paths:<br />  {{range .Paths}}<br />  - {{.}}<br />  {{end}}<br />  multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'<br />  multiline.negate: true<br />  multiline.match: after<br />  multiline.max_lines: 100<br />  multiline.timeout: 10s<br />output.console:<br />  codec.format:<br />    string: '%{[log.file.path]} %{[message]}'<br />logging.level: warning<br />

  进入Sidecar容器,使用如下命令测试Filebeat输出,确认多行日志分割正确。

  $ filebeat -c /etc/logsidecar/filebeat.yaml<br />

  不容忽视的容器运行时

  按理说FluentBit和Filebeat都支持多行日志,Kafka应该也能正确输出多行日志,但结果却令人失望。必须有另一个链接被遗漏了。在登录集群节点主机查看容器的标准输出日志时,发现了这个被忽略的点!

  ## 此处直接查看你的项目容器<br />$ tail -f /var/log/containers/*.log<br />

  你会发现日志都是JSON格式的,日志是一行一行输出的,也就是不支持多行日志块。本地kubernetes集群使用Docker作为容器运行时,查看其配置:

  

" />

  {<br />  "log-driver": "json-file",<br />  "log-opts": {<br />    "max-size": "100m",<br />    "max-file": "3"<br />  },<br />  "max-concurrent-downloads": 10,<br />  "max-concurrent-uploads": 10,<br />  "bip": "192.168.100.1/24",<br />  "storage-driver": "overlay2",<br />  "storage-opts": ["overlay2.override_kernel_check=true"]<br />}<br />

  log-driver配置为json-file,也是官方默认配置。请参考官方说明[2]。除了json格式,还支持以下格式:

  显然其他格式并不理想,而且对于生产环境来说,切换容器运行时日志格式影响不小。到目前为止,这条路的难度太高,风险太大。我会暂时搁置,等身体和精神都舒服了再继续打。

  去掉中间人,直奔Kafka

  既然以上路径行不通,那就换个思路。Filebeat也是一个logging-agent,支持向Kafka输出日志。为什么不跳过中间环节,直奔主题呢?

  $ kubectl edit cm -n kubesphere-logging-system logsidecar-injector-configmap<br />

  filebeat.inputs:<br />- type: log<br />  enabled: true<br />  paths:<br />  {{range .Paths}}<br />  - {{.}}<br />  {{end}}<br />  multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'<br />  multiline.negate: true<br />  multiline.match: after<br />  multiline.max_lines: 100<br />  multiline.timeout: 10s<br />output.kafka:<br />  enabled: true<br />  hosts:<br />    - XXX.XXX.XXX.XXX:9092<br />  topic: sycx-cmes-app<br />## output.console:<br />##   codec.format:<br />##     string: '%{[log.file.path]} %{[message]}'<br />logging.level: warning<br />

  当我看到 Kafka 消费者输出完美的多行日志块时,多巴胺在我脑后涌动!再看一下架构图,总结一下吧!

  总结

  刚开始去KubeSphere社区论坛搜索日志采集相关的帖子时,有朋友说不可能。看到他的回复,我心里一阵绝望。现在看来,从某种角度来说,他的回答是正确的。他只是说这条路不行,但他没有详细说明可以走哪条路。这篇文章对这个问题给出了满意的解决方案。

  引用链接[1]

  官方参考文件:

  [2]

  考试官方说明:

  KubeSphere()是一个构建在Kubernetes之上的开源容器平台,提供全栈IT自动化运维能力,简化企业的DevOps工作流程。

  KubeSphere已被Aqara智能家居、爱立信、原创

生活、东软、华云、新浪、三一重工、华夏银行、川航、国药集团、微众银行、杭州树泡科技、紫金保险、去哪儿、中通、中国人民银行采用、中国银行、中国人保人寿、中国太平保险、中国移动、中国联通、中国电信、天翼云、中移金科、Radore、ZaloPay等*敏*感*词*数万家企业。KubeSphere提供了对开发者友好的向导式操作界面和丰富的企业级功能,包括Kubernetes多云多集群管理、DevOps(CI/CD)、应用生命周期管理、边缘计算、微服务治理(ServiceMesh)、多-租户管理、可观察性、存储和网络管理,

  ✨GitHub:官网(中国站):‍‍微信群:请搜索加群助手微信kubesphere企业服务:e.cloud

  非常有效:Dedecms有效防止采集的两个实用办法

  现在采集

无处不在,尤其是一些原创网站。真正受够这些采集

的人,如何预防和预防采集

,站长们!今天,我们就来说说dedecms的反催收手段。

  1.随机模板

  方法:你复制N多模板,在body标签附近稍微修改一下

  只要你有足够的模板,人们就会失去耐心,放过你

  缺点:复制N多个模板比较麻烦

  2.反采集

混淆

  方法:在正文表示中插入大量容易混淆的字符,其他人也会采集

这些容易混淆的字符。

  

" />

  缺点:可能会影响SEO。对于图片网站来说,如果别人不在意你的乱码,他们还是会采集

,别人会下载你的图片,给你带来太多的流量。

  这是我最好的解决方案:

  方法:靠近body标签

  变成

  注意是空格+{dede:field.id/},

  这样,div的类就没有变了。于是他产生了

  或者在html标签中插入id={dede:field.id/},比如

  

" />

  注意,如果当前html标签已有ID,最好不要插入。

  让采集器

在写规矩的时候没有办法找到一样的,所以写不出来。如果他连

  如果你也采集

它,你将在

  在上课的前一个地方做同样的事情。

  当然别人可以用过滤规则去除,但是加我在所有类中插入文档ID,或者插入id=文档ID。然后他采集

整个页面,然后过滤它。

  缺点:如果插入的{dede:field.id/}不够多,其他人可以使用过滤规则过滤掉。

  源自GreenInternet虚拟主机推荐博客

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线