Docker - 日志
Docker 日志在维护和排查运行在 container 中的应用程序时至关重要。它们提供 container 行为的实时洞察,帮助识别问题,从而优化性能。它们捕获足够广泛的信息,包括应用程序和 Docker 引擎可能产生的错误、警告和信息消息。这些数据对调试非常有益:开发者可以通过它们追踪导致特定问题的哪些事件发生,理解上下文,并应用修复。
此外,Docker 日志在监控和审计方面具有重要意义。日志应被收集并持续分析,以确保应用程序平稳、安全运行。它能检测异常发生、未经授权访问等安全威胁,从而及时响应潜在漏洞。
Docker 日志为系统提供了关键可见性和控制能力,对于生产环境中维护系统弹性和稳健性至关重要,在这些环境中,正常运行时间和可靠性是首要考虑因素。
在本章中,让我们进一步了解 Docker 日志和 logging drivers。
Docker 日志有何不同?
由于 Docker 的容器化特性,Docker 日志与传统日志不同。让我们来看看基本区别。
集中化和聚合
传统日志通常涉及从单个服务器或应用程序收集日志,随着服务器和应用程序数量的增加,这种方式会变得难以扩展,并逐渐变得繁琐。相比之下,Docker 日志通常涉及集中化和聚合来自多个主机上运行的多个 container 的日志。
在集中式方法中,这将简化日志管理,即使在复杂和分布式环境中,也能从单一入口轻松监控或分析日志。
Log Drivers 和 Plugins
Docker 提供了广泛的 log drivers 和 plugins,用于定制日志的收集、存储和处理方式。这些 log drivers 允许将日志发送到不同的存储点——如 JSON 文件、Syslog、Fluentd、AWS CloudWatch 等。这样,可以提供多种选项来调整日志配置,以满足特定需求和偏好,并无缝集成到现有的日志和监控工具中。
Container 的短暂性
Container 是短暂的;它们设计为具有较短生命周期,可以被暂停、停止或移除。这种瞬态特性对传统日志方法构成了瓶颈,后者主要依赖主机系统的持久本地存储。Docker 通过将日志存储脱离 container 生命周期来解决这个问题。
持久性对于维护完整的事件历史记录至关重要,即使在 container 被移除或替换后,也能访问关键诊断信息。这些细微差异强调了一点:Docker 日志是为容器化环境的动态和可扩展特性而设计的。它体现在集中式日志管理解决方案中,从而使日志数据始终可用。
Docker 日志策略和最佳实践
主动日志记录是管理和支持 Dockerized 应用程序的重要过程。日志条目提供了对应用程序行为、性能和问题的深刻洞察,从而实现主动管理和快速排查。
Docker 提供了多种日志管理方式,每种方式都有其优势和适用场景。让我们逐一讨论。
通过应用程序进行日志记录
Dockerized 应用程序进行日志记录的最简单方式实际上是从应用程序本身开始。这可以通过设置应用程序使用标准输出 (stdout) 和标准错误 (stderr) 进行日志记录来实现。Docker 会收集这些输出,因此对于日志,您可以使用 docker logs 命令轻松检索它们。
通过应用程序进行日志记录的优势
- 实现简单 − 易于执行,无需额外配置。
- 可移植性 − 日志可以通过 Docker 的原生日志功能轻松访问。
- 兼容性 − 与任何可以配置为向 stdout 和 stderr 输出日志的应用程序良好兼容。
最佳实践
- 结构化日志记录 − 由于采用结构化格式(如 JSON 日志),日志解析和分析更好。
- 日志轮转 − 使用应用程序的日志轮转功能来限制日志文件膨胀。
- 日志级别 − 设置适当的日志级别(例如,debug、info、warning、error)来指定日志的详细程度。
数据卷日志记录
另一种方法是使用 Docker 数据卷来存储日志。如果您将卷附加到容器内部写入日志的目录,您可以确信它将经受住容器的移除或重启。
数据卷日志记录的优势
- 持久性 − 日志不会因容器的销毁和重新创建而丢失。
- 关注点分离 − 将日志存储与容器化应用程序分开。
- 灵活性 − 外部日志管理工具可以直接从卷访问和处理日志。
最佳实践
- 卷管理 − 监控和管理日志卷大小,以确保磁盘空间没有问题。
- 备份和保留 − 实施组织的日志备份策略及其保留政策。
- 访问控制 − 保护日志卷免受未经授权的访问。
使用 Docker 日志驱动程序进行日志记录
Docker 包含众多内置的日志驱动程序,这些驱动程序提供了灵活的选项,将容器日志发送到各种目的地:syslog、journald、Fluentd 和 AWS CloudWatch 等。它可以在守护进程和容器级别进行配置。
使用 Docker 日志驱动程序进行日志记录的优势
- 集中式日志记录 − 轻松从多个主机和容器收集日志。
- CI/CD 集成 − 与现有的基础设施和日志工具集成。
- 可扩展性 − 支持多种日志存储后端和服务。
最佳实践
- 选择驱动程序 − 选择与您的日志基础设施和需求相匹配的日志驱动程序。
- 配置 − 配置日志驱动程序,以确保提供的性能和可靠性达到最佳。
- 监控 − 持续观察驱动程序的错误或日志记录问题。
使用特定日志记录容器
日志记录容器是专用的,这意味着它可以从主机上的所有其他容器收集日志。这通常意味着容器运行一个日志代理,如 Fluentd 或 Logstash,并将日志聚合并发送到中央日志系统。
优势
- 隔离 − 日志记录关注点保持在与应用程序容器隔离的上下文中。
- 可扩展性 − 它独立于应用程序容器。
- 灵活性 − 支持复杂的日志处理和转发配置。
最佳实践
- 资源分配 − 为日志记录容器分配足够的资源以处理日志量。
- 网络配置 − 设置网络以实现容器之间安全有效的日志传输。
- 冗余 − 为日志记录容器引入冗余和故障转移功能。
通过 Sidecar 方式进行日志记录
Sidecar container 在 Kubernetes 或 Docker 环境中与主应用 container 在同一个 pod 中并行运行。Sidecar container 的职责包括收集、处理和转发应用日志。
优势
- Proximity − 它确保以低延迟收集日志,因为主 container 被放置在靠近应用的位置。
- Modularity − 日志记录功能可以独立扩展和管理。
- Consistency − 在所有环境中使用相同的日志配置。
最佳实践
主 container 和 sidecar container 之间应该进行适当的同步。
- Resource Allocation − 为 sidecar container 分配足够的资源用于日志处理。
- Observability − 观察和监控主 container 和 sidecar container 的健康状态和运行情况。
如何使用 Docker Logs 命令处理 Docker Container 日志?
管理和访问日志是使用 Docker container 的重要部分。docker logs 命令提供了一种便捷的方式来访问和查看运行中的 container 日志。本指南将通过实际示例和最佳实践,带您了解如何使用 docker logs 命令。
Docker Logs 命令的基本用法
docker logs 命令用于获取 container 的日志。其语法非常简单,例如:
$ docker logs [OPTIONS] CONTAINER
这里,CONTAINER 表示您想要查看日志的 container 的名称或 ID。
查看日志
要查看 container 的日志,需要使用 docker logs 命令后跟 container 的名称或 ID。例如 −
$ docker logs my-container
此命令将显示 my-container 产生的全部日志。
实时日志流式传输
-f 或 --follow 标志允许您查看运行中的日志,这类似于在类 Unix 系统中对日志执行 "tail -f"。它会实时跟踪您的日志 −
$ docker logs -f my-container
查看尾部日志
如果您只想查看最新的日志记录,请使用 --tail 选项:这在管理大型日志文件时特别有用。
$ docker logs --tail 100 my-container
此命令将获取 my-container 的最后 100 行日志。
带时间戳的日志
使用 -t 或 --timestamps 选项来获取带时间戳的日志。此选项会在每个日志条目中添加时间戳,便于关联事件 −
$ docker logs -t my-container
组合选项
可以组合多个选项来创建自定义日志视图。例如,如果您想查看带时间戳的日志并限制为最后 50 条记录,可以使用 −
$ docker logs -f -t --tail 50 my-container
按日期过滤日志
虽然 docker logs 命令不支持直接按日期过滤日志,但可以使用 Unix grep 命令实现。以下是一个示例 −
$ docker logs my-container | grep "2024-06-01"
此命令过滤 my-container 的日志,仅显示包含 2024-06-01 日期的日志。
将日志保存到文件
您可以将这些日志保存到文件中,以便后续分析或归档 −
$ docker logs my-container > my-container-logs.txt
此命令将 my-container 的所有日志记录到名为 my-container-logs.txt 的文件中。
日志轮转
Docker 本身不会自动进行日志轮转。因此,日志文件可能会变得过大。可以通过 Docker logging driver 选项配置日志轮转。例如,设置日志文件大小限制和日志文件数量:在您的 docker-compose.yml 文件或 daemon.json 中添加以下内容 −
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
这将每个日志文件大小限制为 10 MB,并保留最多三个日志文件。
什么是 Logging Driver?
Docker logging driver 是一种将来自 Docker 容器的日志消息定向到特定位置并以特定方式处理的方法。默认情况下,Docker 会捕获每个容器的标准输出 (stdout) 和标准错误 (stderr) 流中的日志。
Logging driver 指定这些日志将被定向到哪里:本地文件、远程服务器,或者是实际日志系统的外部服务钩子。Docker 还支持多种 logging driver,以提供可扩展且灵活的日志管理解决方案。
如何配置 Docker Logging Driver?
您可以在 Docker daemon 级别和每个容器的基础上配置 logging driver。
为 Daemon 配置 Docker Logging Driver
要设置默认值,从而控制 Docker daemon 上管理的所有容器,您可以使用 daemon.json 配置文件。通常,此文件位于 Linux 系统上的 /etc/docker/daemon.json。例如,以下是如何将其设置为使用 'JSON-file' driver 的方法 −
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
然后,要应用更改,您必须通过运行以下命令重启 Docker daemon −
$ sudo systemctl restart docker
为单个容器使用 Logging Driver
在启动容器时,可以使用 --logdriver 选项覆盖默认 logging driver。例如,要使用 syslog logging driver,可以添加以下行 −
$ docker run --log-driver=syslog my-container
还可以指定以下内容以选择更多日志选项 −
$ docker run --log-driver=syslog --log-opt syslog-address=udp://localhost:514 my-container
Docker 日志默认保存在哪里?
默认情况下,Docker 使用 json-file log driver。此格式的日志文件将被放入主机上的目录 /var/lib/docker/containers/<container-id>/ 中。每个容器都会有一个这样的目录。日志被写入名为 <container-id>-json.log 的文件中。
什么是 Delivery Modes?
Delivery modes 仅定义了 Docker 中日志消息如何传递到最终目的地的两种主要 delivery modes 支持 logging drivers −
Blocking(默认)
在 blocking 模式下,消息以同步方式传递。容器内的发送进程将暂停,直到 logging driver 确认日志消息已被处理。它在消息脱离容器方面是可靠的。然而,如果 logging backend 较慢或不可用,这可能会在性能上造成痛苦。
Non-blocking
在 non-blocking 传递中,容器进程不会等待 logging driver 处理日志消息,这提高了性能,但代价是如果 logging driver 或其 backend 无法应对数据速率,日志可能会丢失。激活 non-blocking 模式的一种方式是使用 mode logging 选项。
设置 non-blocking 模式的示例 −
$ docker run --log-driver=json-file --log-opt mode=non-blocking my-container
Docker 日志驱动选项/标志
Docker 日志驱动提供了众多选项或标志,可以根据需求对其进行配置。下面是一些常见的可能性和常用日志驱动 −
json-file
- max-size − 日志文件在轮转前的最大大小。
- max-file − 要保留的最大日志文件数量。
$ docker run --log-driver=json-file --log-opt max-size=10m --log-opt max-file=3 my-container
syslog
- syslog-address − syslog 消息将发送到的服务器地址。
- syslog-facility − 要使用的 syslog facility(例如,daemon、user)。
- syslog-tls-ca-cert − 机器上 TLS 的 CA 证书路径。
$ docker run --log-driver=syslog --log-opt syslog-address=udp://localhost:514 --log-opt syslog-facility=daemon my-container
Fluentd
- fluentd-address − Fluentd 服务器地址。
- fluentd-async-connect − 异步连接到 Fluentd。
- fluentd-buffer-limit − 设置 Fluentd 的缓冲区限制。
$ docker run --log-driver=fluentd --log-opt fluentd-address=localhost:24224 --log-opt fluentd-async-connect=true my-container
AWS-Logs
- awslogs-region − AWS 区域。
- awslogs-group − CloudWatch Logs 组的名称。
- awslogs-stream − CloudWatch Logs 流的名称。
$ docker run --log-driver=awslogs --log-opt awslogs-region=us-east-1 --log-opt awslogs-group=my-log-group --log-opt awslogs-stream=my-log-stream my-container
结论
通过 Docker 提供的多样化日志方法,从应用级日志和数据卷,到高级日志驱动和流行的 sidecars,开发者和系统管理员可以根据面临的需要和运营要求调整日志配置。每种方法都有其优势,从简单性和易于扩展,到与外部日志系统的集成,从而在异构环境中提供全面的日志管理。
FAQ
Q 1. Docker 中的默认 logging driver 是什么,它是如何工作的?
In Docker 中,json-file driver 是默认的 logging 机制。此 driver 会捕获容器生成的日志,并将它们存储为 JSON 对象,每个容器都有其专用的日志文件。这种结构化格式便于解析和分析日志数据,但如果这些文件未得到有效管理,请注意潜在的存储问题。
Q 2. 我可以自定义 Docker 处理日志的方式吗?
当然可以!Docker 提供了多种 logging driver 可供选择,每种 driver 都有独特的功能和行为。您可以选择将日志发送到集中式 logging 服务(如 Syslog 或 Fluentd)的 driver,以实现更简化的管理和分析。如果现有 driver 无法完全满足您的需求,您甚至可以创建自定义 logging driver 来满足特定要求。
Q 3. 如何查看运行中 Docker 容器的日志?
查看运行中容器的日志是一项简单任务。您可以使用 docker logs 命令后跟容器名称或 ID 来显示日志。要实时监控日志,请包含 --follow 选项。如果您只想查看最近的条目,请使用 --tail 选项来限制输出。对于更高级的过滤或分析,您可能需要探索专为 Docker 设计的第三方 logging 工具。
Q 4. Docker 中 logging 的最佳实践有哪些?
Docker 中的有效 logging 涉及几项关键实践。首先,将多个容器的日志集中到一个统一位置,可以显著简化管理和分析。此外,根据您的基础设施和具体需求选择合适的 logging driver 至关重要。这需要平衡性能和 driver 所需功能等因素。
使用 JSON 等结构化格式可以简化日志解析和查询,而设置日志轮转策略或使用自动管理日志大小的 driver 可以防止存储问题。最后,积极监控日志有助于及时检测问题、安全威胁或性能瓶颈。
Q 5. 如何排查 Docker 中常见的 logging 问题?
遇到 Docker 中的 logging 问题时,首先检查您选择的 logging driver 及其配置设置。确保日志文件写入正确位置,并且权限配置正确。如果您使用远程 logging driver,请确认网络连接已建立。
在某些情况下,简单重启容器或 Docker daemon 即可解决问题。如果问题持续存在,请参考特定 logging driver 的文档,或向 Docker 社区论坛寻求帮助。