使用Logspout转发Docker日志至Syslog,rsyslog按容器拆分日志遇错求解
首先,咱们得先搞清楚你遇到的问题根源:你写的rsyslog规则格式理解错了,导致rsyslog把你想用来标识容器的munin-server当成了系统用户名,而非日志的标签/标识,这才引发了一连串错误。咱们一步步拆解解决:
1. 逐个分析错误原因
错误1:KLogPermitNonKernelFacility指令不被允许
这个是rsyslog版本兼容问题——v6+的rsyslog改用了RainerScript配置语法,旧的KLogPermitNonKernelFacility已经被弃用。你需要把配置里的这条指令替换成:
module(load="imklog" permitNonKernelFacility="on")
错误2&3:munin-server被识别为用户名
这是核心问题!rsyslog的规则格式是[syslog设施].[优先级] 动作,其中设施是syslog标准定义的(比如auth、daemon、local0-local7这类),而你写的munin-server不是合法设施,所以rsyslog自动把它当成了「要发送日志的用户名」(对应omusrmsg模块),但munin-server长度超过了rsyslog允许的用户名上限,于是又触发了第三个错误。
2. 正确的解决方案:按容器标签拆分日志
要实现按容器拆分日志,你需要先让Logspout给每个容器的日志打上容器名称作为syslog标签,再在rsyslog里根据标签过滤:
步骤1:修改Logspout启动命令,添加容器名称标签
更新你的Logspout启动命令,通过环境变量SYSLOG_TAG让它把容器名称作为日志的syslog标签:
docker run --name="logspout" -d \ --restart=unless-stopped \ --volume=/var/run/docker.sock:/var/run/docker.sock \ -e SYSLOG_TAG="{{.ContainerName}}" \ gliderlabs/logspout \ syslog://host-01.example.com:514
这样每个容器的日志都会带上类似munin-server:的标签(注意末尾的冒号,syslog标签默认会加冒号)。
步骤2:配置rsyslog按标签过滤日志
在/etc/rsyslog.d/下新建一个配置文件(比如90-docker-logs.conf),添加以下规则:
# 匹配munin-server容器的日志,写入指定文件 if $syslogtag == 'munin-server:' then /var/log/munin.log & stop # 阻止日志继续写入默认的syslog文件 # 其他容器的规则可以依此类推 if $syslogtag == 'nginx:' then /var/log/nginx-docker.log & stop
步骤3:重启rsyslog服务
保存配置后重启rsyslog生效:
systemctl restart rsyslog
3. 关于你的问题
- 能不能修改名称? 当然可以!只要Logspout给容器日志打上你想要的标签(比如自定义别名,只要修改
SYSLOG_TAG的模板就行,比如{{.ContainerName}}-custom),你就能在rsyslog里用这个标签来过滤拆分日志。 - 提示信息是否误导? 完全不误导,是你对rsyslog规则格式的理解有误,才导致rsyslog把你的容器名称当成了用户名处理。
内容的提问来源于stack exchange,提问作者andreas

