前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker 双栈日志

Docker 双栈日志

作者头像
Jintao Zhang
发布2020-03-26 17:15:27
8590
发布2020-03-26 17:15:27
举报
文章被收录于专栏:MoeLoveMoeLove

本文来聊聊 Docker 双栈日志,看看这个方案解决了我们实际应用中的哪些痛点,以及如何落地使用。

1

容器日志收集

在生产环境中使用 Docker 或 Kubernetes ,甚至是非容器环境,日志管理都是个非常重要的部分。

对于日志的管理,主要涉及以下几个方面:

  • 日志收集
  • 聚合
  • 解析
  • 存储
  • 分析
  • 搜索
  • 归档

最终目标都是我们可以通过日志来及时的发现异常,或排查故障,同时也可以通过日志来分析当前的应用程序或者基础架构是否运行正常,是否有需要改进的地方等。

本篇的重点在于日志收集,目前主要有以下几种解决方案,简单聊聊。

1.1

应用直接写日志中心

最简单,也是应用容器化改造中最省心省力的一种。应用程序直接将日志写入远端的日志中心。

这种方案的好处在于只要基础设施跟得上,应用容器化改造或者服务迁移之类的基本不涉及日志改造之类的问题。

但使用这种方式的话,有几个显著的缺点:

  • 使用远端日志中心,在日志量大的时候,I/O 很容易成为一个瓶颈,不过现在基本都是万兆卡,也可以通过加代理之类的来解决;
  • 应用层需要格外注意当远端日志中心写入失败,或是日志中心失联的情况,要如何处理这个异常。切不可因为写日志而影响业务;
  • 如果是为了应对前面提到的这种远端日志中心写入失败的问题,而要求应用在写日志失败时,在本地额外做记录的话,那反而是失去了这种方案最一开始的好处/优势;

1.2

应用将日志写入固定文件

日志写入固定文件,通过日志采集器收集并解析后发送到日志中心。

这种方案最常见,大家常见的 ELK 日志栈,其中的 L 通常是指 Logstash ,当然也可以换成其他的类似组件,这里不赘述了。如果这种方案是应用在 Kubernetes 中的话,通常会使用一个 sidecar 来配合进行日志收集的工作。

这种方案好处就是业务方不需要有太多调整,维持原本的写日志方式。

缺点则是需要单独启动 sidecar 做日志收集,相应的这会造成一些资源浪费。以及需要注意日志清理等。

1.3

应用将日志直接写 stdout/stderr

应用层稍做改造,将日志写 stdout/stderr 。

这种方案在业务进行容器化改造,或者部署到 Kubernetes 时,是比较推荐的,这也是相对标准/通用的实践方式。

这种方式的要说缺点的话主要是业务层需要对日志记录做些改造,改造成直接写 stdout/stderr,同时也需要注意对日志做区分/标记。

但好处也很明显,不需要有什么额外的 sidecar 做收集,直接利用 Docker 原生的日志机制收集便可以了。很多人会选择通过 DaemonSet 的方式在每个节点部署一个日志采集器做日志收集。

2

Docker 默认日志驱动

介绍完上述几种常规的解决方案后,很明显,这里最推荐的方式是直接写 stdout/stderr 了。我们将重点拉回到 Docker 上,当日志直接写 stdout/stderr 时,Docker 为我们做了些什么?

我们启动一个容器做个测试:

# 启动一个容器,并输出 Happy Birthday Docker
(MoeLove) ➜  ~ docker run alpine echo "Happy Birthday Docker"            
Happy Birthday Docker

Docker 提供了一个 docker logs 的命令可供我们查看容器的日志输出:

(MoeLove) ➜  ~ docker logs $(docker ps -ql)                  
Happy Birthday Docker

你可能会好奇,这个日志记录是从哪里来的呢?这就要归功于 Docker 的日志驱动了。当前默认的日志驱动名叫 json-file ,其功能是将日志以 JSON 的格式写入到本地的文件中,可通过以下命令进行验证:

(MoeLove) ➜  ~ sudo cat `docker info --format '{{ .DockerRootDir }}'`/containers/$(docker ps -ql --no-trunc)/$(docker ps -ql --no-trunc)-json.log
{"log":"Happy Birthday Docker\n","stream":"stdout","time":"2020-03-20T12:28:02.804391064Z"}

可以看到这个文件中保存着刚才通过 echo 写入 stdout 的内容。

PS:很多人在 Kubernetes 中采集容器日志的方式,就是通过 DaemonSet 在每个 Node 上部署一个日志收集器进行日志收集。关于这种方案的优劣不是本篇的重点,暂且跳过。

3

Docker 其他日志驱动

除了这种默认的 json-file 的日志驱动外,Docker 还提供了很多其他的驱动,可通过以下命令进行查看:

(MoeLove) ➜  ~ docker info --format '{{ .Plugins.Log }}'                                                    
[awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog]

这些日志驱动有它们不同的使用场景,简单聊几种:

  • journald: 如果你喜欢所有的日志都通过 journalctl 进行访问或管理,或者你的日志收集器是直接采集 journal log 的话,可以使用这个日志驱动;
  • syslog: 如果你有 syslog 日志服务器,那你可以直接使用这种日志驱动,将日志发送过去,而不需要做什么其他特殊的配置;
  • fluentd: 可以直接将日志发送至 Fluentd ( http://www.fluentd.org/ ) ,通过 Fluentd 再将日志输出到 ES/Kafka 或者其他多种存储上。

这里有个值得注意的内容,fluentd 这种日志驱动其实不一定非要和 Fluentd 绑定,你也可以使用 Fluent Bit ( https://fluentbit.io/ )。

4

Docker 使用 fluentd 日志驱动

这里我来做个示例,使用 fluentd 这个日志驱动,但使用 Fluent Bit 进行接收。

4.1

启动 Fluent Bit

首先,创建一个配置文件,这里为了演示,我将接收到的日志直接进行输出:

[SERVICE]
    Flush        5
    Daemon       Off
    Log_Level    debug

[INPUT]
    Name   forward
    Listen 0.0.0.0
    Port   24224

[OUTPUT]
    Name  stdout

这里需要注意,INPUT 块中,使用 forward 输入。

这里我将此配置文件保存为 docker_to_stdout.conf,并使用此配置启动一个 Fluent Bit 的容器。

(MoeLove) ➜  fluentbit-docker docker run -p 24224:24224 -v $PWD/docker_to_stdout.conf:/docker_to_stdout.conf --rm fluent/fluent-bit:1.3 
/fluent-bit/bin/fluent-bit -c /docker_to_stdout.conf 
Fluent Bit v1.3.11
Copyright (C) Treasure Data

[2020/03/20 16:09:13] [ info] Configuration:
[2020/03/20 16:09:13] [ info]  flush time     | 5.000000 seconds
[2020/03/20 16:09:13] [ info]  grace          | 5 seconds
[2020/03/20 16:09:13] [ info]  daemon         | 0
[2020/03/20 16:09:13] [ info] ___________
[2020/03/20 16:09:13] [ info]  inputs:
[2020/03/20 16:09:13] [ info]      forward
[2020/03/20 16:09:13] [ info] ___________
[2020/03/20 16:09:13] [ info]  filters:
[2020/03/20 16:09:13] [ info] ___________
[2020/03/20 16:09:13] [ info]  outputs:
[2020/03/20 16:09:13] [ info]      stdout.0
[2020/03/20 16:09:13] [ info] ___________
[2020/03/20 16:09:13] [ info]  collectors:
[2020/03/20 16:09:13] [debug] [storage] [cio stream] new stream registered: forward.0
[2020/03/20 16:09:13] [ info] [storage] version=1.0.3, initializing...
[2020/03/20 16:09:13] [ info] [storage] in-memory
[2020/03/20 16:09:13] [ info] [storage] normal synchronization mode, checksum disabled, max_chunks_up=128
[2020/03/20 16:09:13] [ info] [engine] started (pid=1)
[2020/03/20 16:09:13] [debug] [engine] coroutine stack size: 24576 bytes (24.0K)
[2020/03/20 16:09:13] [debug] [in_fw] Listen='0.0.0.0' TCP_Port=24224
[2020/03/20 16:09:13] [ info] [in_fw] binding 0.0.0.0:24224
[2020/03/20 16:09:13] [debug] [router] default match rule forward.0:stdout.0
[2020/03/20 16:09:13] [ info] [sp] stream processor started

这里我将 Fluent Bit 监听的端口映射到了本地的 24224 端口。

4.2

将日志转发至 Fluent Bit

启动容器,并使用 --log-driver=fluentd 参数指定容器使用此日志驱动。你也可以直接修改 /etc/docker/daemon.json 的配置文件,添加 "log-driver": "fluentd" 令所有容器都默认使用此配置。

(MoeLove) ➜  ~ docker run --log-driver=fluentd --log-opt fluentd-address=tcp://localhost:24224  alpine echo "Happy Birthday Docker" 
Happy Birthday Docker

查看刚才 Fluent Bit 容器的输出,可以看到多了以下内容:

[2020/03/20 16:17:22] [debug] [task] created task=0x7fdc6288e0a0 id=0 OK
[2020/03/20 16:17:23] [debug] [task] destroy task=0x7fdc6288e0a0 (task_id=0)
[0] 678aa7a18729: [1584721039.000000000, {"container_id"=>"678aa7a18729b25159b65f5221968f825447c6f6b71b31ee2853e0dcdd992cb2", "container_name"=>"/distracted_faraday", "source"=>"stdout", "log"=>"Happy Birthday Docker"}]

说明 日志已经传递到了 Fluent Bit 。

同时,我们继续使用 docker logs 命令查看刚才容器的日志:

(MoeLove) ➜  ~ docker logs $(docker ps -ql)                  
Error response from daemon: configured logging driver does not support reading

可以看到当使用了 fluentd 的日志驱动后,无法再通过 docker logs 直接查看日志了! 实际上,不只是对于 fluentd 这个日志驱动,包括 syslog,awslogs,gcplogs,splunk 等除了 jsonfile 和 journald 这两个日志驱动时,都不能通过 docker logs 直接查看日志!这就非常的不方便了。

你无法在本地直接查看容器日志了,当发生一些紧急情况时,这就会比较影响效率了。

这也就进行到了本节的重点内容了,用 Docker 双栈日志解决此问题!

5

Docker 双栈日志

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 MoeLove 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档