前言---关于容器的日志说明:
- 如果把日志保存在容器内部,它会随着容器的销毁而被删除。由于容器的生命周期相对虚拟机大大缩短,创建销毁属于常态,因此需要一种方式持久化的保存日志;
- 进入容器时代后,需要管理的目标对象远多于虚拟机或物理机,登录到目标容器排查问题会变得更加复杂且不经济;
- 容器的出现让微服务更容易落地,它在给我们的系统带来松耦合的同时引入了更多的组件。因此我们需要一种技术,它既能帮助我们全局性的了解系统运行情况,又能迅速定位问题现场、还原上下文。
容器的日志分为两大类:
一、标准输出
说明:通过 STDOUT、STDERR 输出的信息,包括被重定向到标准输出的文本文件。
二、文本日志
存在于容器内部并且没有被重定向到标准输出的日志。
标准输出
1.使用 logging driver
logging drive有很多格式如图所示
通过 logging driver 采集容器标准输出的优势在于使用简单,例如:
## 使用logging-drive 的syslog格式
docker run -p 389:389 --name openldap --restart=always -e LANG=en_US.UTF-8 -e LANGUAGE=en_US:en -e LC_ALL=en_US.UTF-8 --env TZ="Asia/Shanghai" --env LDAP_ORGANISATION="es" --env LDAP_DOMAIN="es.com" --env LDAP_ADMIN_PASSWORD="devv587" --volume /etc/localtime:/etc/localtime --volume /data/docker/openldap/database:/var/libldap --volume /data/docker/openldap/slapd.d:/etc/ldap/slapd.d --detach --log-driver syslog osixia/openldap:1.5.0
# 该命令表示在 docker daemon 级别为所有容器配置 syslog 日志驱动
dockerd -–log-driver syslog –-log-opt syslog-address=udp://1.2.3.4:1111
# 该命令表示为当前容器配置 syslog 日志驱动
docker run -–log-driver syslog –-log-opt syslog-address=udp://1.2.3.4:1111 alpine echo hello world
缺点
除了 json-file 和 journald,使用其他 logging driver 将使 docker logs API 不可用。例如,当您使用 portainer 管理宿主机上的容器,并且使用了上述两者之外的 logging driver,您会发现无法通过 UI 界面观察到容器的标准输出
2.使用 docker logs API
对于那些使用默认 logging driver 的容器,我们可以通过向 docker daemon 发送 docker logs 命令来获取容器的标准输出。使用此方式采集日志的工具包括 logspout、sematext-agent-docker 等。下列样例中的命令表示获取容器自2018-01-01T15:00:00
以来最新的5条日志。
docker logs --since "2018-01-01T15:00:00" --tail 5 <container-id>
缺点
当日志量较大时,这种方式会对 docker daemon 造成较大压力,导致 docker daemon 无法及时响应创建容器、销毁容器等命令。
3.采集 json-file 文件
默认 logging driver 会将日志以 json 的格式写入宿主机文件里,文件路径为/var/lib/docker/containers/<container-id>/<container-id>-json.log
。这样可以通过直接采集宿主机文件来达到采集容器标准输出的目的。
该方案较为推荐,因为它既不会使 docker logs API 变得不可用,又不会影响 docker daemon,并且现在许多工具原生支持采集宿主机文件,如 filebeat、logstash 等。
文本日志
1.挂载宿主机目录
也就是我们常见的docker容器的目录映射,通过 bind mounts 或 volumes 方式将宿主机目录挂载到容器日志所在目录上,如下图所示。
在 docker run -v 中有详解,这里不再赘述。
缺点:有一定的侵入性质
2.计算容器 rootfs 挂载点
使用挂载宿主机目录的方式采集日志对应用会有一定的侵入性,因为它要求容器启动的时候包含挂载命令。如果采集过程能对用户透明那就太棒了。事实上,可以通过计算容器 rootfs 挂载点来达到这种目的。
和容器 rootfs 挂载点密不可分的一个概念是 storage driver。实际使用过程中,用户往往会根据 linux 版本、文件系统类型、容器读写情况等因素选择合适的 storage driver。不同 storage driver 下,容器的 rootfs 挂载点遵循一定规律,因此我们可以根据 storage driver 的类型推断出容器的 rootfs 挂载点,进而采集容器内部日志。下表展示了部分 storage dirver 的 rootfs 挂载点及其计算方法。
3.Logtail 方案,如图所示
功能特点
logtail 方案包含如下功能:
- 支持采集宿主机文件以及宿主机上容器的日志(包括标准输出和日志文件);
- 支持容器自动发现,即当您配置了采集目标后,每当有符合条件的容器被创建时,该容器上的目标日志将被自动采集;
- 支持通过 docker label 以及环境变量过滤指定容器,支持白名单、黑名单机制;
- 采集数据自动打标,即对收集上来的日志自动加上 container name、container IP、文件路径等用于标识数据源的信息;
- 支持采集 K8s 容器日志。
核心优势
- 通过 checkpoint 机制以及部署额外的监控进程保证 at-least-once 语义;
- 历经多次双十一、双十二的考验以及阿里集团内部百万级别的部署规模,稳定和性能方面非常有保障。