Docker 容器内运行 rsyslog 报 "rsyslogd is not running... failed" 怎么办?

Docker 容器中 rsyslog 起不来的常见原因:没有 init 系统、缺少 /dev/log 套接字、前台运行配置错误。本文给出 Dockerfile 示例及排错步骤,并说明更推荐的容器日志方案。

最佳实践
Docker 容器内运行 rsyslog 报 "rsyslogd is not running... failed" 怎么办?封面

容器里跑 rsyslog 的典型坑:容器默认没有 systemd/init,service rsyslog start 不可靠;缺少 /dev/log 套接字导致输入模块报错。让 rsyslog 直接以前台模式作为容器主进程运行最可靠:rsyslogd -n。

可用的 Dockerfile 示例

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y rsyslog && rm -rf /var/lib/apt/lists/*

COPY rsyslog.conf /etc/rsyslog.conf

# 前台模式运行(容器主进程)
CMD ["rsyslogd", "-n"]

关键点:-n 让 rsyslog 前台运行,容器的主进程就是它,挂了容器就退出(可被编排系统重启)。

常见报错排查

"rsyslogd is not running... failed":
用 service rsyslog start 启动失败时,直接手动前台运行看真实报错:

rsyslogd -n -d    # debug 模式,输出具体错误

imklog 模块错误(imklog: cannot open kernel log):
容器内读不了内核日志。在 /etc/rsyslog.conf 中注释掉 module(load="imklog")。

/dev/log 不存在:
容器里没有 syslog 套接字。需要其他容器把日志发过来时,改用网络输入:

module(load="imudp")
input(type="imudp" port="514")
module(load="imtcp")
input(type="imtcp" port="514")

更重要的思考:容器里该不该跑 rsyslog?

容器最佳实践是一个容器一个进程,应用日志直接写 stdout/stderr,由容器运行时收集。在容器里跑 rsyslog 通常只在两种场景合理:

  1. 把容器做成日志收集器(接收其他系统的 syslog);
  2. 遗留应用只能写 syslog,短期过渡。

确需远程汇集 syslog 时,可以让现有 rsyslog 转发到观测云 DataKit 的日志 Socket 接收端。先按接收配置核对 TCP/UDP、监听地址和端口,再发送一条测试消息验证时间与主机字段;不能把传统 syslog 的 514 当作所有 DataKit 实例的默认端口。

常见问题(FAQ)

Q:多进程容器怎么管理 rsyslog 和应用?
A:用 supervisord 或 s6 作为 PID 1 管理多个进程;但优先重新评估架构,单容器单进程更清晰。

Q:rsyslog 在容器里收不到宿主机的日志?
A:rsyslog 容器化后只监听自己的网络命名空间。需要端口映射 -p 514:514/udp -p 514:514 才能接收外部 syslog。

Q:K8s 里怎么收 syslog?
A:DataKit DaemonSet 监听宿主机端口,或部署为带 hostNetwork 的采集层;网络设备 syslog 直接发到 DataKit 服务的地址。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台