logpilot的认识

这篇文章介绍的很清楚了,容器日志采集利器Log-Pilot

这篇文章主要最用就是笔记和一些我的理解吧。

简介: 容器时代越来越多的传统应用将会逐渐容器化,而日志又是应用的一个关键环节,那么在应用容器化过程中,如何方便快捷高效地来自动发现和采集应用的日志,如何与日志存储系统协同来高效存储和搜索应用日志,本文将主要跟大家分享下如何通过Log-Pilot来采集容器的标准输出日志和容器内文件日志。

容器时代越来越多的传统应用将会逐渐容器化,而日志又是应用的一个关键环节,那么在应用容器化过程中,如何方便快捷高效地来自动发现和采集应用的日志,如何与日志存储系统协同来高效存储和搜索应用日志。本文将主要跟大家分享下如何通过Log-Pilot来采集容器的标准输出日志和容器内文件日志。

日志采集难点

首先我们先看一下容器日志采集的一些难点,这里主要从两个方面来讲,第一个是容器本身的特性,第二个是现有采集工具的一些缺陷:


容器本身特性
  • 采集目标多
    容器一般推荐将日志写在标准输出,但是也有一些特殊的场景就是应用直接将日志写在容器内部。对于容器的标准输出日志来说,Docker Engine 本身就提供了一个很好的日志采集能力,但是对于容器内部的文件日志采集,现在并没有一个很好的工具能够去动态发现采集。
  • 容器的弹性伸缩性
    我们知道 Kubernetes 本身是一个分布式集群,那么我们事先就无法像传统虚拟机环境下那样,事先配置好日志的采集路径等一些信息,因此这对于容器的日志采集来说也将面临一个很大的挑战。
现有采集工具缺陷
  • 缺乏动态配置的能力
    目前的采集工具都需要我们事先手动配置好日志采集方式和路径等信息,由于它无法能够自动感知到容器的生命周期变化或者动态漂移,所以它无法动态地去配置。
  • 日志采集重复或丢失
    现有的一些采集工具基本上是通过 tail 的方式来进行日志采集的,那么这里就可能存在两个方面的问题:一个是可能导致日志丢失,比如采集工具在重启的过程中,而应用依然在写日志,那么就有可能导致这个窗口期的日志丢失;而对于这种情况一般保守的做法就是,默认往前多采集 1M 日志或 2M 的日志,那么这就又会可能引起日志采集重复的问题。
  • 未明确标记日志源
    一个应用可能有很多个容器,输出的应用日志也是一样的,那么当我们将所有应用日志收集到统一日志存储后端时,在搜索日志的时候,我们就无法明确这条日志具体是哪一个节点上的哪一个应用容器产生的。

破解利器 Log-Pilot

针对这些问题,我们提供了一个智能容器采集工具 Log-Pilot,它不仅能够高效便捷地将容器日志采集输出到多种存储日志后端,同时还能够动态地发现和采集容器内部的日志文件。

Log-Pilot 本身分为三部分,其中一部分就是容器事件管理,它能够动态地监听容器的事件变化,然后依据容器的标签来进行解析,生成日志采集配置文件,然后交由采集插件来进行日志采集。


下面看一下,针对前面容器日志采集的难点,Log-Pilot 是如何去解决的:


  1. 采集目标多:Log-Pilot 同时支持标准输出和容器内部文件日志采集。
  2. 动态伸缩性:Log-Pilot 支持声明式的日志配置方式。
  3. 缺乏动态配置的能力:Log-Pilot 具有自动感知和发现的特性。
  4. 日志采集重复和丢失:Log-Pilot 内部有 CheckPoint 和句柄保持的机制。
  5. 未明确标记日志源:Log-Pilot 支持日志自动数据打标。

声明式日志配置

Log-Pilot 支持声明式日志配置,可以依据容器的 Label 或者 ENV 来动态地生成日志采集配置文件。这里重点说明两个变量:

  1. name:我们自定义的一个字符串,它在不同的场景下指代不同的含义。当我们将日志采集到 ElasticSearch 的时候, name 表示的是 Index;当我们将日志采集到 Kafka 的时候, name 表示的是 Topic;当我们将日志采集到阿里云日志服务的时候,name 表示的是 LogstoreName。
  2. path:它本身支持两种,一种是约定关键字 stdout,表示的是采集容器的标准输出日志,第二种是容器内部的具体文件日志路径,可以支持通配符的方式。比如我们要采集 tomcat 容器日志,那么我们通过配置标签 aliyun.logs.catalina=stdout 来采集 tomcat 标准输出日志,通过配置标签 aliyun.logs.access=/usr/local/tomcat/logs/*.log 来采集 tomcat 容器内部文件日志。

自动发现机制

Log-Pilot 能够自动感知宿主机上容器的创建删除事件,进而动态配置容器日志采集配置文件。

一般情况下我们是通过全量扫描加事件监听的方式,比如采集工具进程在起来的时候,会先去全量扫描一遍宿主机上的所有容器列表,然后依据容器的声明式配置来进行日志采集配置文件的动态生成,然后再注册事件监听,那么这样可能会导致一个问题,在全量扫描配置的过程中并且在注册事件监听之前,这个窗口期的容器事件就有可能会丢失,因此这里我们采用的是先注册事件监听,然后再全量扫描,这样就可以很好地规避容器事件丢失的问题。

句柄保持机制

自动 CheckPoint

Log-Pilot 内部会实时跟踪日志采集偏移量,然后维持日志文件信息与偏移量的映射关系,最后定期地持久化到磁盘中。采用偏移量的方式我们可以避免日志采集丢失和重复的问题,同时即使当采集工具宕掉再起来,它可以通过加载持久化在磁盘上的元数据信息,然后从指定的日志偏移位置上继续采集日志。

句柄保持机制

Log-Pilot 在监测到配置的日志路径目录下有新的日志文件产生时会主动地打开其句柄,并维持打开状态,这样是为了防止因日志采集工具比较慢或者应用日志输出速率特别大,比如说当前已经生成五个日志文件但只采集到第三个,后面两个还没有开始采集,一旦这个容器退出就可能导致后面两个文件的日志丢失了。

因此 Log-Pilot 在监测到有新的日志产生的时候,会立即将其文件句柄打开,这样的话即使这个日志文件删除,它在磁盘中的数据并没有被擦除,只有当该日志文件采集完成后,我们才会主动去释放这个文件句柄,这样就可以保证日志文件里面的日志不会丢失。

自动数据打标

Log-Pilot 在采集容器日志的时候,同时也会收集容器的元数据信息,包括容器的名称,容器所属的服务名称以及容器所属的应用名称,同时在 Kubernetes 里面也会采集容器所属的 Pod 信息,包括 Pod 的名称,Pod 所属的 namespace 以及 Pod 所在的节点信息。这样我们排查问题时,就可以很方便地知道这个日志数据是来源于哪个节点上的哪个应用容器。

支持高级特性

Log-Pilot 除了提供前面的几个特性外,还支持一些其他的高级特性,比如低资源消耗,支持自定义 tag,支持多种日志解析格式,支持自定义日志输出 target 以及支持 fluentd 和 filebeat 等插件,最后支持对接到多种日志存储后端。

低资源消耗

针对低资源消耗,我们先简单看一下容器日志采集一般采用的两种部署模式:

  • SideCar 模式

这种需要我们在每个 Pod 中都附带一个 logging 容器来进行本 Pod 内部容器的日志采集,一般采用共享卷的方式,但是对于这一种模式来说,很明显的一个问题就是占用的资源比较多,尤其是在集群规模比较大的情况下,或者说单个节点上容器特别多的情况下,它会占用过多的系统资源,同时也对日志存储后端占用过多的连接数。当我们的集群规模越大,这种部署模式引发的潜在问题就越大。

  • Node 模式

这种模式是我们在每个 Node 节点上仅需布署一个 logging 容器来进行本 Node 所有容器的日志采集。这样跟前面的模式相比最明显的优势就是占用资源比较少,同样在集群规模比较大的情况下表现出的优势越明显。

但对于这种模式来说我们就需要一个更加智能的日志采集工具来配合,那么这里用 Log-Pilot 工具就是一个很好的选择,因此我们在布署 Log-Pilot 采集工具的时候采用的就是 Node 模式。

支持自定义Tag

Log-Pilot 也支持自定义Tag,我们可以在容器的标签或者环境变量里配置 aliyun.logs.$name.tags: k=v,那么在采集日志的时候也会将k=v采集到容器的日志输出中。

比如我们有一种场景,有一个开发环境和测试环境,应用日志都会被采集到统一的一个日志存储后端,假设是一个 ElasticSearch 集群,但是我们在 ElasticSearch 中查询日志的时候又想区分出来,具体某条日志记录到底来源于生产环境,还是测试环境。

那么我们就可以通过给测试环境的容器打上 stage=dev 的 tag,给生产环境的容器打上 stage=pro 的 tag,Log-Pilot 在采集容器日志的时候,同时会将这些 tag 随容器日志一同采集到日志存储后端中,那么当我们在查询日志的时候,就可以通过 stage=dev 或者 stage=pro 能明确地区分出某条日志是来源于生产环境的应用容器所产生,还是测试环境应用容器所产生的。另外通过自定义 tag 的方式我们还可以进行日志统计、日志路由和日志过滤。

支持多种日志解析格式

Log-Pilot 也支持多种日志解析格式,通过 aliyun.logs.$name.format: <format>标签就可以告诉 Log-Pilot 在采集日志的时候,同时以什么样的格式来解析日志记录。目前主要支持六种:

  1. none:默认格式,指不对日志记录做任何解析,整行采集出来直接输出到日志存储后端。
  2. json:Log-Pilot 在采集日志的时候同时会将每一行日志以 json 的方式进行解析,解析出多个 KV 对,然后输出到日志存储后端。
  3. csv:主要是针对csv格式的日志采集配置(需配置fluentd插件)。
  4. nginx:主要是针对Nginx的日志采集配置(需配置fluentd插件)。
  5. apache2:主要是针对Apache的日志采集配置(需配置fluentd插件)。
  6. regexp:用户可以通过 format 标签来自定义正则表达式,告诉 Log-Pilot 在解析日志记录的时候以什么样的拆分格式来进行解析拆分(需配置fluentd插件)。

支持自定义输出Target

这里假设一种场景,我们同时有一个生产环境和一个测试环境,应用日志都需要被采集到同一套 Kafka 中,然后由不同的 consumer 去消费。

但是我们同样希望区分出来,某条日志数据是由生产环境的应用容器产生的,还是测试环境的应用容器产生的,但我们在测试环境中的应用容器已经配置了 aliyun.logs.svc=stdout 标签,那么当这些应用容器的标准输出日志被采集到 kafka 中,它最终会被路由到 topic=svc 的消息队列中,那么订阅了 topic=svc 的 consumer 就能够接收测试环境的应用容器产生的日志。

但当我们将该应用发布到生产环境时,希望它产生的日志只能交由生产环境的 consumer 来接收处理,那么我们就可以通过 target 的方式,给生产环境的应用容器额外定义一个 target=pro-svc,那么生产环境的应用日志在被采集到 Kafka 中时,最终会被路由到 topic 为 pro-svc 的消息队列中,那么订阅了 topic =pro-svc 的 consumer 就可以正常地接收到来自于生产环境的容器产生的日志。

因此这里的 target 本身也有三种含义:

  • 当我们将日志对接到ElasticeSearch时,这个 target 字符串是 Index;
  • 当我们对接到Kafka时,它指代的是 topic;
  • 当我们将日志对接到日志服务时,它代表的是 Logstore Name。

支持多采集插件

目前 Log-Pilot 支持两种采集插件:一个是CNCF社区的Fluentd插件,一个是Elastic的Filebeat插件;其同时其支持对接多种存储后端,目前 Fluentd 和 Filebeat 都支持 Elasticsearch、Kafka、File、Console 作为日志存储后端,而 Fluentd 还支持 Graylog、阿里云日志服务 以及 Mongodb 作为存储后端。



log-pilot的githup地址,可以看到该项目已经很久不维护了,

查看该githup项目中的readme,Run pilot如下:

docker run --rm -it \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /etc/localtime:/etc/localtime \
    -v /:/host:ro \
    --cap-add SYS_ADMIN \
    registry.cn-hangzhou.aliyuncs.com/acs/log-pilot:0.9.5-filebeat

从上面可以看出以下几点注意的:

  • 需要使用宿主机的docker,所以将宿主机的docker.sock映射容器内。
  • 将宿主机的/目录下的所有文件映射到容器内的/host内,以readOnly的方式。pod(需要记载日志的)内的文件日志以emptyDir的方式映射到宿主机上,所以需要将宿主机上的文件映射到logpilot容器内,这样logpilot容器才可以正常采集到各个pod的日志,这也是为什么logpilot容器需要将宿主机的/目录下的所有文件映射到容器内的/host内原因,而且必须是/host目录,不能是自定义目录名。
  • 增加容器SYS_ADMIN权限。将宿主机的/目录下的所有文件映射到容器内的/host内,普通用户是没有这个权限的,所以需要给宿主机增加admin权限。
  • 在docker hup上看不到官方的log-pilot官方镜像,既然readme中给的镜像地址是registry.cn-hangzhou.aliyuncs.com/acs,那么该地址就可以理解为镜像地址了。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容