容器内应用日志收集方案

容器化应用日志收集挑战

应用日志的收集、分析和监控是日常运维工作重要的部分,妥善地处理应用日志收集往往是应用容器化重要的一个课题。

Docker处理日志的方法是通过docker engine捕捉每一个容器进程的STDOUT和STDERR,通过为contrainer制定不同log driver 来实现容器日志的收集,缺省json-file log driver是将容器的STDOUT/STDERR 输出保存在磁盘上,然后用户就能使用docker logs <container>来进行查询。

在部署一个传统的应用的时候,应用程序记录日志的方式通常记录到文件里, 一般(但不一定)会记录到/var/log目录下。应用容器化后,不同于以往将所有日志放在主机系统的统一位置,日志分散在很多不同容器的相互隔离的环境中。

如何收集应用写在容器内日志记录,有以下挑战:

1) 资源消耗

如果在每个容器运行一个日志收集进程, 比如logstatsh/fluentd 这类的日志工具,在主机容器密度高的时候,logstatsh/fluentd这类日志采集工具会消耗大量的系统资源。上面这种方法是最简单直观的,也是最消耗资源的。

2) 应用侵入

一些传统应用,特别是legacy 系统,写日志机制往往是没法配置和更改的,包括应用日志的格式,存放地址等等。日志采集机制,要尽量避免要求修改应用。

3) 日志来源识别

采用统一应用日志收集方案,日志分散在很多不同容器的相互隔离的环境中,需要解决日志的来源识别问题。

日志来源识别的功能借助了rancher平台为container_name的命名的规则特性,可以做到即使一个容器在运行过程中被调度到另外一台主机,也可以识别日志来源。

容器化应用日志收集方案

下面是我们设计的一个低资源资源消耗、无应用侵入、可以清楚识别日志来源的统一日志收集方案,该方案已经在睿云智合的客户有成功实施案例。

图片描述

在该方案中,会在每个host 部署一个wise2c-logger,wise2C会listen docker engine的event,当有新容器创建和销毁时,会去判断是否有和日志相关的local volume 被创建或者销毁了,根据lables,wise2c-logger 会动态配置logstatsh的input、filter 和output,实现应用日志的收集和分发。

1) 应用如何配置

应用容器化时候,需要在为应用容器挂载一个专门写有日志的volume,为了区别该volume 和容器其它数据volume,我们把该volume 定义在容器中,通过volume_from 指令share 给应用容器,下面是一个例子:demo应用的docker-compose file

图片描述

web-data 容器使用一个local volume,mount到/var/log目录(也可以是其它目录),在web-data中定义了几个标签, io.wise2c.logtype说明这个容器中包含了日志目录,标签里面的值elasticsearch、kafka可以用于指明log的output或者过滤条件等。

那么我们现在来看下wiselogger大致的工作流程:

图片描述

监听新的日志容器->获取日志容器的type和本地目录->生成新的logstash配置:

1)wise2c-looger 侦听docker events 事件, 检查是否有一个日志容器创建或者被销毁;

2)当日志容器被创建后(通过container label 判断), inspect 容器的volume 在主机的path;

3)重新配置wise2c-logger 内置的logstatsh 的配置文件,设置新的input, filter 和output 规则。

图片描述

这里是把wise2c-logger在rancher平台上做成catalog需要的docker-compose.yml的截图,大家可以配合上面的流程描述一起看一下。

优化

目前我们还在对Wise2C-logger 作进一步的优化:

1)收集容器的STDOUT/STDERR日志

特别是对default 使用json-file driver的容器,通过扫描容器主机的json-file 目录,实现容器STDIN/STDERR日志的收集。

2)更多的内置日志收集方案

目前内置缺省使用logstatsh 作日志的收集,和过滤和一些简单的转码逻辑。未来wise2C-logger 可以支持一些更轻量级的日志收集方案,比如fluentd、filebeat等。

Q & A

Q:有没有做过性能测试?我这边模块的日志吞吐量比较大。比如在多少量级的日志输出量基础上,主要为logger模块预留多少系统资源,保证其正常稳定工作?

A:没有做过很强的压力,但是我们现在正常使用倒没碰上过性能上的瓶颈。我们现在没有对logger做资源限制,但是能占用300~400M内存,因为有logstash的原因。

Q:「生成日志容器」是指每个应用容器要对应一个日志容器?这样资源消耗不会更大吗?k8s那种日志采集性能消耗会比这样每个应用容器对应一个日志容器高么?

A:是指每个应用容器对应一个日志容器。虽然每个应用有一个日志容器,但是,日志容器是start once的,不会占用运行时资源。

Q:你说的start once是什么意思?我说占资源是大量日志来的时候,那么多日志容器要消耗大量io的吧,CPU使用率会上升,不会影响应用容器使用CPU么?

A:不会,日志容器只生成一下,不会持续运行。

Q:怎么去监听local volume?

A:可以监听文件目录,也可以定时请求docker daemon。

Q:直接用syslog driver,能做到对应用无侵入么?

A:启动容器的时候 注明使用Syslog driver的参数即可,这样几乎没有额外资源占用。

Q:这种方案是不是要保证应用容器日志要输出到/var/log下啊?

A:不是,可以随意定义,logstah可以抓syslog。

Q:syslog driver能收集容器内的日志文件么?容器内不同流向的日志能区分么?

A:容器内应用的本地日志syslog可以收集,分流同样可以完成,但是容器内的本地日志这个我个人觉得跟容器环境下的应用无本地化、无状态化相悖吧。

Q:最后你说到,重新配置logstash中配置文件,看上去感觉你又是通过wiselog这个容器去采集所有日志的?只不过是动态配置logstash里面参数。

A:是的,现在收集工作是logstash来完成的,单纯的文件收集,可选的方案还挺多的,也没有必要再造轮子了。

Q:那这个方案其实有个疑问,为什么不学k8s那种,直接固定那目录,通过正则表达式去采集日志文件,而要动态这么做?有什么好处吗?目前我感觉这两套方案几乎一样。

A:为了减少对应用的侵入。因为很多用户的现有系统不能再修改了,这样做也是为了减少用户现有程序的修改,为了最重要的“兼容现有”。

Q:除了kibana还有没别的可视化方案?

A:针对es来说,还没有别的更好的方案。

Q:如果是挂载log目录,logstash就可以去宿主机收集了,还需要别的插件做什么?

A:通过容器可以识别出来这个应用的业务上的逻辑,可以拿到service名称。

Q:有的应用输出的log名都是一样的,不会有冲突吗,比如我启动2个容器在一个宿主机上,都往xx.log里写入会有问题。

A:不会,给每一个应用容器配一个日志卷容器就可以解决这个问题。这个问题也是我们出方案时一个棘手的问题。所以这个方案的一个好处就是,每一个应用的都可以随意设置日志目录,不用考虑和别的应用冲突,也不会和同宿主机同一应用冲突。

Q:上次听别人说全部把日志扔到标准输出里,不知道靠谱不?

A:有人报过这种处理方式,日志量大时,docker daemon会崩溃。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python统计行号_利用Python进行数据分析(第三篇上)

上一篇文章我记录了自己在入门 Python 学习的一些基础内容以及实际操作代码时所碰到的一些问题。这篇我将会记录我在学习和运用 Python 进行数据分析的过程&#xff1a;介绍 Numpy 和 Pandas 两个包运用 Numpy 和 Pandas 分析一维、二维数据数据分析的基本过程实战项目【用 Pyt…

lnmp架构搭建—源码编译(nginx、mysql、php)

含义及理解&#xff1a; LNMP LinuxNginxMysqlPHP&#xff1a;LNMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写。L指Linux&#xff0c;N指Nginx&#xff0c;M一般指MySQL&#xff0c;也可以指MariaDB&#xff0c;P一般指PHP&#xff0c;也可以指P…

Java PipedInputStream available()方法与示例

PipedInputStream类的available()方法 (PipedInputStream Class available() method) available() method is available in java.io package. available()方法在java.io包中可用。 available() method is used to return the number of available bytes left that can be read …

解析xml_Mybatis中mapper的xml解析详解

上一篇文章分析了mapper注解关键类MapperAnnotationBuilder&#xff0c;今天来看mapper的项目了解析关键类XMLMapperBuilder。基础介绍回顾下之前是在分析configuration的初始化过程&#xff0c;已经进行到了最后一步mapperElement(root.evalNode("mappers"))&#x…

lnmp—MemCache的作用

含义及理解&#xff1a; 1 . memcache是一个高性能的分布式的内存对象缓存系统&#xff0c;用于动态web应用以减轻数据库负担。通过在内存里维护一个统一的巨大的hash表&#xff0c;来存储经常被读写的一些数组与文件&#xff0c;从而极大的提高网站的运行效率。 memcache是一…

Java ListResourceBundle getKeys()方法与示例

ListResourceBundle类的getContents()方法 (ListResourceBundle Class getContents() method) getContents() method is available in java.util package. getContents()方法在java.util包中可用。 getContents() method is used to return an enumeration of all the keys tha…

orale用户密码过期处理

使用具有管理权限的用户登录1、查看用户的proifle是哪个&#xff0c;一般是default&#xff1a;SELECT username,PROFILE FROM dba_users;2、查看指定概要文件&#xff08;如default&#xff09;的密码有效期设置&#xff1a;sql>SELECT * FROM dba_profiles s WHERE s.prof…

python字典怎么设置_在python中设置字典中的属性

在python中设置字典中的属性是否可以在python中从字典创建一个对象&#xff0c;使每个键都是该对象的属性&#xff1f;像这样的东西&#xff1a;d { name: Oscar, lastName: Reyes, age:32 }e Employee(d)print e.name # Oscarprint e.age 10 # 42我认为这几乎与这个问题相反…

Java ObjectInputStream readByte()方法与示例

ObjectInputStream类readByte()方法 (ObjectInputStream Class readByte() method) readByte() method is available in java.io package. readByte()方法在java.io包中可用。 readByte() method is used to read a byte (i.e. 8 bit) of data from this ObjectInputStream. re…

openresty—实现缓存前移

含义及理解&#xff1a; OpenResty(又称&#xff1a;ngx_openresty) 是一个基于 NGINX 的可伸缩的 Web 平台&#xff0c;由中国人章亦春发起&#xff0c;提供了很多高质量的第三方模块。 其目标是让Web服务直接跑在Nginx服务内部&#xff0c;充分利用Nginx的非阻塞I/O模型&am…

Nginx+Keepalived+Tomcat之动静分离的web集群

NginxKeepalivedTomcat之动静分离的web集群 博客分类&#xff1a; webserverNginxKeepalivedTomcat之动静分离的web集群为小公司提供大概一天持续在100万/日之间访问的高性能、高可用、高并发访问及动静分离的web集群方案NginxKeepalived 高可用、反向代理NginxPHP …

安装完成后的配置_cent os7 默认安装后的一般配置

在安装cent os7后&#xff0c;进入系统会出现一些命令无法执行。这是因为最小化没有安装包含的软件包。这时候先要配置一下基本的IP参数&#xff0c;(包括动态&#xff0c;静态&#xff0c;或者是双网卡绑定)。我们在虚拟机中模拟操作一下&#xff0c;配置文件在/etc/sysconfig…

Java Integer类lowerOneBit()方法与示例

整数类lowerOneBit()方法 (Integer class lowestOneBit() method) lowestOneBit() method is available in java.lang package. minimumOneBit()方法在java.lang包中可用。 lowestOneBit() method is used to find at most only single 1’s bit from the rightmost side one b…

lnmp构架——对tomcat详解

tomcat的安装部署 安装jdk和tomcat tar zxf jdk-7u79-linux-x64.tar.gz -C /usr/local/ tar zxf apache-tomcat-7.0.37.tar.gz -C /usr/local/做好软连接便于访问 cd /usr/local ln -s jdk1.7.0_79/ java ln -s apache-tomcat-7.0.37/ tomcat配置环境变量 vim /etc/profile…

Linux 查找文件

find 查找目录 -name "文件名"find / -name "php.ini"locate 文件名locate php.ini 一&#xff1a;locate命令 locate命令用于查找文件&#xff0c;它比find命令的搜索速度快&#xff0c;它需要一个数据库&#xff0c;这个数据库由每天的例行工作&#xff…

Java GregorianCalendar hashCode()方法与示例

GregorianCalendar类的hashCode()方法 (GregorianCalendar Class hashCode() method) hashCode() method is available in java.util package. hashCode()方法在java.util包中可用。 hashCode() method is used to returns the hash code for this GregorianCalendar. hashCode…

python元组为什么不可变_为什么python字符串和元组是不可变的?

我不知道为什么字符串和元组是不可变的&#xff1b;使它们不可变的优点和缺点是什么&#xff1f;除了Python解释器的内部实现&#xff0c;这种设计在编写程序上是否有很好的意义&#xff1f;(例如&#xff0c;如果元组和字符串是可变的&#xff0c;会更容易吗&#xff1f;)如果…

InnoDB事务结构体代码变量列表

事务结构 struct trx_t 写在前面 InnoDB是MySQL的一个存储引擎&#xff0c;支持事务&#xff0c;支持非堵塞的一致性读&#xff0c;物理存储结构是Page&#xff0c;每个事务都有回滚日志&#xff0c;重做日志&#xff0c;事务还会有死锁检测&#xff0c;各种各样不同的锁等等等…

对cookie与session的理解

cookie&#xff1a; 在网站中&#xff0c;http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后&#xff0c;第二次请求服务器依然不能知道当前请求是哪个用户。 cookie的出现就是为了解决这个问题&#xff0c; 第一次登录后服务器返回一些数据&#xff08;…

ubutun 更换网络源_Ubuntu 更换源

1.切换到root用户# su root备份源文件 目录&#xff1a;/etc/apt# cd /etc/apt/# cp sources.list sources.list.bk3.更换源 阿里源 清华源# >sources.list # 清空源# vim sources.list # 选择一个源&#xff0c;复制进去# apt update # 更新源&#xff0c;需要等几分钟# ex…