码蚁

打码改变人生

基于 Docker 容器应用的日志收集方案

Posted at — Jul 13, 2017

大规模云服务及系统中,日志系统是保障系统稳定运行不可或缺的一部分,其重要性和监控系统,自动部署系统,自动测试系统等相当。

在基于容器的微服务架构中,由于服务运行的位置、数量和时间的不确定性,传统用于虚拟机的性能监控和日志收集方式很难适应容器应用动态变化的特点。

应用日志的去向

容器挂载宿主机目录作为应用日志输出目录

集群中所有宿主机上需要运行采集工具,如 filebeat、logstash 等。 相较于传统虚拟机应用差别不大,但由于 Docker 的特点以及应用混搭在同一集群中,有以下弊端:

应用日志标准输出到控制台

Docker 从 1.12 开始支持 Logging Driver,允许将Docker日志路由到指定的第三方日志转发层,可将日志转发到 AWS CloudWatch,Fluentd,syslog,GELF 或 NAT 服务器。

使用 logging drivers 比较简单好用,它们需要为每个容器指定,并且将需要在日志的接收端进行其他配置。

下面是一个指定 Logging Driver 为 GELF 并传送到 logstash 的例子:

docker run \
--log-driver gelf \
--log-opt gelf-address=udp://10.78.170.55:12201 \
 alpine echo hello world

logstash 配置:

input {
  gelf {
      host => "0.0.0.0"
      port => 12201
  }
}

output {
  elasticsearch {
    hosts => ["elasticsearch"]
    workers=> 10
  }
}

下面是一个指定 Logging Driver 为 syslog 并传送到 logstash 的例子:

docker run \
--log-driver=syslog \
--log-opt syslog-address=tcp://10.78.170.55:5000 \
--log-opt syslog-facility=daemon \
alpine echo hello world

logstash 配置:

input {
  syslog {
      host => "0.0.0.0"
      port => 5000
  }
}

output {
  elasticsearch {
    hosts => ["elasticsearch"]
    workers=> 10
  }
}

如此这样运行每一个容器,结果是将 Docker 容器日志流输出到 logstash input syslog server,这些日志经过 logstash 处理后发送到 Elasticsearch 或 kafka。

此方案对应用要求低,只需要日志前台输出就可以收集,并不同业务应用日志不会混在一起,方便后期的处理。 关于日志完整性以及数据持久化问采集端 logstash 可以不做任何处转发至 kaf其他组件通过订阅 Kafka 实现更丰富的日志处理。例如:logstash分割聚合后入Elasticsearch,storm 计算处理进行告警,flume 采集处理至 hd进行日志落盘。

kubernetes 目前暂未支持 pod 级别的 log-driver,但社区有讨论 方案,后续有望支持。

应用主动把日志输出到日志收集器

业务日志由进程直接写入 Kafka,其他组件通过订阅 Kafka 实现更丰富的日志处理。例如,使用 Flume 订阅 Kafka 并将日志写入 HDFS。logstash 订阅 Kakfa 分割聚合写入 ElasticSearch。

此方案是最完美的,但需要对业务应日志模块进行更改。

comments powered by Disqus