4.安装fluentd用于收集集群内部应用日志
作者
微信:tangy8080
电子邮箱:914661180@qq.com
更新时间:2019-06-13 11:02:14 星期四
欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程中的编写的文章
如您在阅读过程中发现文章错误,可添加我的微信 tangy8080 进行反馈.感谢您的支持。

文章主题
- 在大多数情况下,我们需要集中管理应用的日志.但是我们又不能强制要求开发者直接对日志进行统一输出
对开发者来说这可能是侵入式的,为了统一输出日志,可能导致业务收到影响.
在这种情况下我们可以自己采集日志,采集工具比较多,这里我们选择fluentd,用于收集集群内的日志 - 集群外部日志的收集将在下一节涉及
- 日志收集原则:在任意时刻(由Es高性能索引速度支持)可以实时的查看到某一节点(由physics.hostname支持)的某一服务(由tag支持)的日志
前置条件
- 已经完成了本章节的第一,第二节
安装
开始安装fluentd-elasticsearch
由于我们对fluentd-elasticsearch的定制比较多,所以我们选择使用源码来安装fluentd-elasticsearch
#克隆源码库
cd /usr/local/src/
git clone https://github.com/kiwigrid/helm-charts
cd helm-charts/charts/fluentd-elasticsearch/
#为所有输出添加hostname,physics.hostname,tag字段,方便查找日志
vim /usr/local/src/helm-charts/charts/fluentd-elasticsearch/templates/configmaps.yaml
#在containers.input.conf节点下添加如下配置
<filter **>
@id filter_hostname
@type record_transformer
<record>
hostname "#{Socket.gethostname}"
physics.hostname "#{ENV['K8S_NODE_NAME']}"
tag ${tag}
</record>
</filter>
- 在filter中添加了hostname,该值为k8s中的podName
- physics.hostname标识节点的名称,该值为k8s中节点的名称,在daemonset.yaml中定义默认定义了K8S_NODE_NAME名称
#执行安装
cd /usr/local/src/helm-charts/charts/fluentd-elasticsearch
helm install --name fluentd-elasticsearch --set elasticsearch.host=elasticsearch-client,hostLogDir.dockerContainers=/data/k8s/docker/data/containers .
- hostLogDir.dockerContainers 用于收集docker产生的日志,请按实际情况更改
- stable/fluentd-elasticsearch is deprecated as we move to our own repo (https://kiwigrid.github.io) which will be puplished on hub.helm.sh soon. The chart source can be found here: https://github.com/kiwigrid/helm-charts/tree/master/charts/fluentd-elasticsearch
[按需]卸载fluentd-elasticsearch
helm del --purge fluentd-elasticsearch
采集思路解析
- 我们在每个节点上运行一个fluentd代理(采用DaemonSet),用于采集部署在k8s容器环境中程序和部署在物理主机中程序的日志。
- 对于容器内部应用.它的生命周期是不固定的,所以我们可以把日志放在宿主机上,(也可以使用sidecar容器,https://kubernetes.io/docs/concepts/cluster-administration/logging/),出于性能原因,这里会选择只运行一个fluentd代理)

- pos_file需要放在何处? 需要放在宿主机上的一个稳定位置(通常和设定和path一个目录).它记录了采集进度,假如容器销毁重启后,它依然可以从上次进度的位置开始采集

- 日志轮转问题, 如果应用本身不支持日志轮转.我们需要考虑日志轮转问题.避免日志越来越大
采集实例配置
实例一:运行在物理机器中的Nginx日志
配置挂载目录
vim /usr/local/src/helm-charts/charts/fluentd-elasticsearch/values.yaml
#nginx日志不在/var/log目录下,在文件中最后添加Nginx日志文件挂载
extraVolumes:
- name: nginxlog
hostPath:
path: /usr/local/nginx/logs
extraVolumeMounts:
- name: nginxlog
mountPath: /var/log/nginx
readOnly: true
配置采集数据源
vim /usr/local/src/helm-charts/charts/fluentd-elasticsearch/templates/configmaps.yaml
# service.honeysuckle-log-consumer
<source>
@id honeysuckle-log-consumer.log
@type tail
<parse>
@type regexp
expression /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) (?<thread>.*) (?<level>[a-zA-Z]+) (?<logger>.*) (?<property>\[.*\]) - (?<msg>[\s\S]*)$/
time_key time
</parse>
path /var/log/businesslogs/honeysuckle-log-consumer/Log.txt
pos_file /var/log/businesslogs/honeysuckle-log-consumer/Log.txt.pos
tag service.honeysuckle-log-consumer
</source>
# service.honeysuckle-configmanager-service
<source>
@id honeysuckle-configmanager-service.log
@type tail
<parse>
@type regexp
expression /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) (?<thread>.*) (?<level>[a-zA-Z]+) (?<logger>.*) (?<property>\[.*\]) - (?<msg>[\s\S]*)$/
time_key time
</parse>
path /var/log/businesslogs/honeysuckle-configmanager-service/Log.txt
pos_file /var/log/businesslogs/honeysuckle-configmanager-service/Log.txt.pos
tag service.honeysuckle-configmanager-service
</source>
# Nginx Access Log Source
<source>
@id nginx.accesslog
@type tail
path /var/log/nginx/access.log
pos_file /var/log/access.log.pos
format /^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)"(?:\s+(?<http_x_forwarded_for>[^ ]+))?)?$/
time_format %d/%b/%Y:%H:%M:%S %z
tag nginx
</source>
- nginx默认的日志格式format可以在这里找到
https://docs.fluentd.org/parser/nginx
实例二:运行在容器中的Helloword程序
该项目用于模拟一个服务,它每隔3秒向 /app/App_Data/Logs/Log.txt 写入一条日志
该项目采用Log4net写入日志,应用本身支持日志轮转,最新的日志都在Log.txt中
log4net.config的配置如下:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<!--文本文件appender-->
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
<file value="App_Data/Logs/Log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="1024KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<appender-ref ref="RollingFileAppender" />
<level value="ALL" />
</root>
</log4net>
日志输出的样例类似于:
2019-06-17 07:29:52,038 [5] INFO honeysuckle.log.consumer.HoneysuckleWebModule [(null)] - electronicinvoice_log_queue.BasicConsume 已创建.
2019-06-17 07:31:51,510 [WorkPool-Session#1:Connection(21956434-0138-45f3-be65-848ca544cad3,amqp://honeysuckle.site:5672)] ERROR honeysuckle.log.consumer.HoneysuckleWebModule [(null)] - Error in EventingBasicConsumer.Received
Elasticsearch.Net.UnexpectedElasticsearchClientException: The operation was canceled. ---> System.OperationCanceledException: The operation was canceled.
at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Elasticsearch.Net.HttpConnection.Request[TResponse](RequestData requestData)
at Elasticsearch.Net.RequestPipeline.CallElasticsearch[TResponse](RequestData requestData)
at Elasticsearch.Net.Transport`1.Request[TResponse](HttpMethod method, String path, PostData data, IRequestParameters requestParameters)
--- End of inner exception stack trace ---
at Elasticsearch.Net.Transport`1.Request[TResponse](HttpMethod method, String path, PostData data, IRequestParameters requestParameters)
at Nest.LowLevelDispatch.BulkDispatch[TResponse](IRequest`1 p, SerializableData`1 body)
at Nest.ElasticClient.Nest.IHighLevelToLowLevelDispatcher.Dispatch[TRequest,TQueryString,TResponse](TRequest request, Func`3 responseGenerator, Func`3 dispatch)
at honeysuckle.log.consumer.HoneysuckleWebModule.<>c__DisplayClass10_0.<CreateNewChannel>b__0(Object sender, BasicDeliverEventArgs e) in /src/src/honeysuckle.log.consumer/HoneysuckleWebModule.cs:line 141
基于日志输出格式,我们采用正则表达式插件进行日志解析(表达式在下面的source中可以看到)
可以使用fluentular工具进行表达式的正确性测试
该项目托管在:
http://admin@gitblit.honeysuckle.site/r/public/helloworld.git
如有测试需要.欢迎clone
配置采集数据源
vim /usr/local/src/helm-charts/charts/fluentd-elasticsearch/templates/configmaps.yaml
# service.helloworld.log Log Source
<source>
@id helloworld.log
@type tail
<parse>
@type regexp
expression /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) (?<thread>\[\d+\]) (?<level>[a-zA-Z]+) (?<logger>.*) (?<property>\[.*\]) - (?<msg>.*)$/
time_key time
</parse>
path /var/log/businesslogs/helloworld/Log.txt
pos_file /var/log/businesslogs/helloworld/Log.txt.pos
tag service.helloworld
</source>
查看fluentd是否采集到了数据
待所有组件全部runing之后,可以通过curl查看fluentd是否采集到了数据
curl 'http://10.254.193.78:9200/_cat/indices?v'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open logstash-2019.06.11 _v7q6b4DSt6mLJ_GLDyFUQ 5 1 4112 0 4.6mb 2.2mb
yellow open logstash-2019.06.12 mz3sF15LTbqQwZiXMubdgg 5 1 29394 0 27.9mb 15.2mb
green open logstash-2019.06.13 rtjvfGVWSM-5rLvq72jxlA 5 1 971 0 2.4mb 1.1mb
在Kibana中检查日志收集情况
检查点一:日志是否根据tag正确分类

检查点二:日志否则附加了hostname和physics.hostname属性

处理升级问题
随着业务的需要,我们后期可能会加入其他的服务.这个时候我们可以在配置文件(configmaps.yaml)中添加好采集规则之后,进行升级
cd /usr/local/src/helm-charts/charts/fluentd-elasticsearch
helm upgrade fluentd-elasticsearch .
一些问题的处理方式记录
- failed to read data from plugin storage file path="/var/log/kernel.pos/worker0/storage.json" error_class=Fluent::ConfigError error="Invalid contents (not object) in plugin storage file: '/var/log/kernel.pos/worker0/storage.json
rm /var/log/kernel.pos/worker0/storage.json
引用链接
https://github.com/helm/charts/tree/master/stable/kibana#configuration
4.安装fluentd用于收集集群内部应用日志的更多相关文章
- kubernetes之收集集群的events,监控集群行为
一.概述 线上部署的k8s已经扛过了双11的洗礼,期间先是通过对网络和监控的优化顺利度过了双11并且表现良好.先简单介绍一下我们kubernetes的使用方式: 物理机系统:Ubuntu-16.04( ...
- Redis的安装配置及简单集群部署
最近针对中铁一局项目,跟事业部讨论之后需要我们的KF平台能够接入一些开源的数据库,于是这两天研究了一下Redis的原理. 1. Redis的数据存储原理及简述 1.1Redis简述 Redis是一个基 ...
- 企业运维实践-还不会部署高可用的kubernetes集群?使用kubeadm方式安装高可用k8s集群v1.23.7
关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 文章目录: 0x00 前言简述 ...
- Centos7 安装部署Kubernetes(k8s)集群
目录 一.系统环境 二.前言 三.Kubernetes 3.1 概述 3.2 Kubernetes 组件 3.2.1 控制平面组件 3.2.2 Node组件 四.安装部署Kubernetes集群 4. ...
- 【Nutch2.3基础教程】集成Nutch/Hadoop/Hbase/Solr构建搜索引擎:安装及运行【集群环境】
1.下载相关软件,并解压 版本号如下: (1)apache-nutch-2.3 (2) hadoop-1.2.1 (3)hbase-0.92.1 (4)solr-4.9.0 并解压至/opt/jedi ...
- rabbitmq安装与高可用集群配置
rabbitmq版本:3.6.12 rabbitmq安装 1.安装openssl wget http://www.openssl.org/source/openssl-1.0.0a.tar.gz &a ...
- Linux系统下安装Redis和Redis集群配置
Linux系统下安装Redis和Redis集群配置 一. 下载.安装.配置环境: 1.1.>官网下载地址: https://redis.io/download (本人下载的是3.2.8版本:re ...
- SSD固态盘应用于Ceph集群的四种典型使用场景
在虚拟化及云计算技术大规模应用于企业数据中心的科技潮流中,存储性能无疑是企业核心应用是否虚拟化.云化的关键指标之一.传统的做法是升级存储设备,但这没解决根本问题,性能和容量不能兼顾,并且解决不好设备利 ...
- 完整安装sqlserver always on集群
准备工作 1. 四台已安装windows server 2008 r2 系统的虚拟机,配置如下: CPU : 1核 MEMORY : 2GB DISK : 40GB(未分区) NetAdapter ...
随机推荐
- cut和tr命令的联合使用
cut的-d选项只能是单个字符,而对于多个连续相同字符分隔的字段,单凭cut命令是达不到想要的效果的,特别是多个连续空格分隔时. 但借助tr -s的压缩重复字符功能,可以将多个连续空格压缩为一个空格, ...
- Vue的核心思想
Vue的核心思想主要分为两部分: 1.数据驱动 2.组件系统 1.数据驱动 在传统的前端交互中,我们是通过Ajax向服务器请求数据,然后手动的去操作DOM元素,进行数据的渲染,每当前端数据交互变化时 ...
- mysqlG基于TID模式同步报错 (Last_IO_Errno: 1236)
mysqlG基于TID模式同步报错Last_IO_Errno: 1236 Last_IO_Error: Got fatal error 1236 from master when reading da ...
- pandas模块的使用详解
为什么学习pandas numpy已经可以帮助我们进行数据的处理了,那么学习pandas的目的是什么呢? numpy能够帮助我们处理的是数值型的数据,当然在数据分析中除了数值型的数据还有好多其他类型的 ...
- 【pytest】(十)fixture参数化-巧用params和ids优雅的创建测试数据
我们都知道参数化. 比如我要测试一个查询接口/test/get_goods_list,这个接口可以查询到商品的信息. 在请求中,我可以根据请参数goods_status的不同传值,可以查询到对应状态的 ...
- 微博CacheService架构浅析 对底层协议进行适配
https://mp.weixin.qq.com/s/wPR0j2bmHBF6z0ZjTlz_4A 麦俊生 InfoQ 2014-04-21 微博作为国内最大的社交媒体网站之一,每天承载着亿万用户的服 ...
- django 请求处理流程 链路追踪
class BaseMiddleware: # https://github.com/django/django/blob/master/tests/utils_tests/test_decorato ...
- Linux下编译安装源码包软件 configure ,make, make install, make test/check, make clean 假目标
http://www.360doc7.net/wxarticlenew/541275971.html 一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 ...
- Java并发包源码学习系列:阻塞队列实现之DelayQueue源码解析
目录 DelayQueue概述 类图及重要字段 Delayed接口 Delayed元素案例 构造器 put take first = null 有什么用 总结 参考阅读 系列传送门: Java并发包源 ...
- SpringMVC听课笔记(SpringMVC 表单标签 & 处理静态资源)
1.springmvc表单标签,可以快速开发,表单回显,但是感触不深 2.静态资源的获取,主要是要配置这个