【问题标题】:Production logging on Docker orchestratorDocker 编排器上的生产日志记录
【发布时间】:2023-03-15 11:43:01
【问题描述】:
我开发了一个 Web 应用程序,它包含前端(VueJS 应用程序)和后端(Flask Python3 应用程序)。在生产模式下,我将使用 docker 和 Kubernetes 作为编排器。
我已设置 Flask 日志记录以登录目录中的两个不同文件
/var/log/appname
它工作正常。
问题是:在生产中,如果 Kubernetes 同时实例化多个后端,每个容器都会产生自己的日志。
有没有办法集中只有一个文件的日志记录过程?
对不起,我不是编排专家,也许没有理由问这个问题。
谢谢。
【问题讨论】:
标签:
python-3.x
docker
flask
kubernetes
【解决方案1】:
据我所知,我对将来自多个容器的日志集中在一个文件中的感觉很复杂,数据会混合在一起。但好的解决方案是附加额外的音量。
可以创建一个 Docker/Kubernetes 卷(或多个卷),指向这些日志文件在应用程序中的驻留位置。通过利用 Docker 模板,可以使用服务任务 ID(整数)为每个卷添加后缀。如果多个服务任务在同一主机上运行,则在卷名上放置后缀可防止与日志记录有关的任何冲突。需要创建一个运行具有目录通配符支持的日志记录代理的全局服务。最后,可以通过日志工具设置额外的正则表达式,将文件的源目录转换为索引值。
下面的示例显示了如何使用官方Tomcat 图像来完成此操作。官方的 Tomcat 映像在/usr/local/tomcat/logs 中记录了几个文件,与大多数 Java 应用程序非常相似。在该路径中,可以找到catalina.2017-07-06.log、host-manager.2017-07-06.log、localhost.2017-07-06.log、localhost_access_log.2017-07-06.txt 和manager.2017-07-06.log 等文件。
为挂载/var/lib/docker/volumes:/logs/volumes的日志记录实用程序创建一个全局服务。
为使用与此通用示例类似的规则进行记录的日志记录代理创建日志记录规则:"/log/volumes/*/_data/*.log"。
-
在卷上使用基于 go 的模板启动服务:
启动服务时,使用以下参数:
docker service create \
-d \
--name prod-tomcat \
--label version=1.5 \
--label environment=prod \
--mount type=volume,src="{{.Task.Name}}",dst=/usr/local/tomcat/logs \
--replicas 3 \
tomcat:latest
如果两个副本都安排在同一个节点上,那么将在主机prod-tomcat.1.oro7h0e5yow69p9yumaetor3l 和prod-tomcat.2.ez0jpuqe2mkl6ppqnuffxqagl 上创建两个包含日志的卷。
只要日志记录代理支持通配符并通过检查 inode(而不是文件)来处理任何日志轮换,就应该收集日志。
如果应用程序记录到多个位置,则尝试将日志符号链接到单个目录或向卷添加描述性名称。如果将描述性名称添加到卷名称,则需要更新任何类型的提取以适应该更改。 (即grok)
-
大多数记录器应该收集文件路径以及日志内容。通过将日志文件所在的卷转换为可索引字段,可以从这些类型的应用程序中搜索和聚合信息。这是一个使用grok 模式并创建两个新的可索引字段CONTAINER_NAME 和FILENAME 的示例。
match => { "path" => "/log/volumes/%{DATA:CONTAINER_NAME}/_data/%{GREEDYDATA:FILE_NAME}" }
CONTAINER_NAME 将匹配来自容器的stdout 流的输出,便于根据容器的日志进行过滤。
可以在swarm-elk repo 中找到包含工作示例的存储库的更多信息。
有关日志记录过程的更多信息,您可以在此处找到:logging。