K8s环境下如何解析日志并流式传输至Docker守护进程
NGINX Plus日志双链路输出实现方案
以下三种方案都可以实现「日志解析采集+流式输出给Docker守护进程」的需求,不需要改动现有K8s日志采集链路:
方案1:NGINX原生双日志输出(优先推荐,稳定性最高)
- 直接调整NGINX配置,同时配置两个独立的日志输出目标,完全不需要引入额外组件:
- 一路日志输出到
/dev/stdout、/dev/stderr,保留默认流式输出逻辑,日志会直接被Docker守护进程捕获,后续可正常被fluent-bit采集 - 另一路日志写入共享卷上的文件,供同Pod的telegraf解析具体状态码指标
- 一路日志输出到
- 核心NGINX配置示例:
http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 输出到标准输出,对接K8s原生日志链路 access_log /dev/stdout main; error_log /dev/stderr warn; # 输出到共享卷文件,供telegraf解析 access_log /var/log/nginx/access.log main; }
- 配套部署要求:在Pod中添加
emptyDir类型的共享存储卷,分别挂载到NGINX容器的/var/log/nginx路径、telegraf容器的日志采集路径即可,不需要开启进程命名空间共享特性。telegraf使用tail插件采集日志文件时,自带文件轮转识别能力,不需要额外部署日志轮转组件。
方案2:共享进程命名空间流捕获(无NGINX配置改动)
- 如果你不方便修改NGINX配置,已经开启
shareProcessNamespace特性的前提下,可以直接通过procfs读取NGINX进程的标准输出流:- 在telegraf容器的启动脚本中,先查找NGINX主进程的PID
- 读取
/proc/<NGINX_PID>/fd/1(标准输出)、/proc/<NGINX_PID>/fd/2(标准错误)的流内容 - 用
tee命令做流分发:一份输出到telegraf自身的/dev/stdout,供Docker守护进程采集;另一份喂给telegraf的日志解析插件提取状态码指标
- 该方案的缺点是需要处理NGINX进程重启后的PID重新识别逻辑,适合临时调试或者无法调整NGINX配置的场景。
方案3:无盘流转发(高流量场景最优)
- 高并发场景下如果要避免写磁盘的IO开销,可以部署一个极简流转发sidecar:
- 让NGINX的日志输出直接对接sidecar的监听端口或者Unix域套接字
- sidecar收到日志流后做双份转发:一份输出到自身标准输出对接K8s日志链路,一份转发给同Pod的telegraf做指标解析
- 整个链路没有磁盘读写,日志处理延迟最低,也不会出现日志文件占满磁盘的问题。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

