Docker容器中service与systemctl的异常及--privileged问题排查
Docker容器中systemctl无法正常工作的解决方法
环境配置
setup.sh脚本
set -e apt-get update apt-get install --yes apt-utils apt-get install --yes language-pack-et net-tools systemd rm --force \ /etc/init.d/ondemand \ /etc/systemd/system/*.wants/* \ /lib/systemd/system/*getty*.service \ /lib/systemd/system/basic.target.wants/* \ /lib/systemd/system/local-fs.target.wants/* \ /lib/systemd/system/multi-user.target.wants/* \ /lib/systemd/system/sockets.target.wants/*initctl* \ /lib/systemd/system/sockets.target.wants/*udev* \ /lib/systemd/system/systemd-update-utmp* find /lib/systemd/system/sysinit.target.wants -type l \ ! -name systemd-tmpfiles-setup\* \ -delete systemctl set-default multi-user.target rm --force /usr/sbin/policy-rc.d apt-get install --yes rsyslog apt-get clean rm --recursive --force /var/lib/apt/lists/* exit 0
Dockerfile
# Ubuntu 20.04 LTS (Focal Fossa) FROM ubuntu:focal # Set up APT COPY src/apt-sources.list /etc/apt/sources.list COPY src/apt-local-options /etc/apt/apt.conf.d/90local-options COPY src/rc.local /etc/rc.local RUN chmod +x /etc/rc.local ENV DEBIAN_FRONTEND=noninteractive COPY setup.sh /usr/local/bin/ RUN sh -x /usr/local/bin/setup.sh
docker-compose.yml
services: tests: build: context: ./docker dockerfile: Dockerfile image: "test:latest" container_name: testc entrypoint: /lib/systemd/systemd systemd.unit=multi-user.service stop_grace_period: 1s tmpfs: - /run - /tmp volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro version: '2.2'
问题现象
执行
docker-compose exec --privileged tests service rsyslog status时返回:Failed to connect to bus: No such file or directory Failed to connect to bus: No such file or directory不带
--privileged执行则正常返回* rsyslogd is not running。无论是否带
--privileged,执行docker-compose exec tests systemctl status rsyslog都返回:System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down但
docker-compose exec tests ps -p 1 -o comm=显示PID 1是systemd。
解决方法
1. 修复setup.sh中的systemd服务清理逻辑
核心问题是setup.sh中删除了sysinit.target.wants下的dbus.service链接,导致systemd启动时未初始化D-Bus总线,systemctl无法连接。修改setup.sh中的find命令,保留dbus服务:
find /lib/systemd/system/sysinit.target.wants -type l \ ! -name systemd-tmpfiles-setup\* \ ! -name dbus.service \ -delete
同时在setup.sh末尾、exit前添加dbus初始化步骤,确保套接字生成:
# 初始化dbus套接字 mkdir -p /run/dbus dbus-uuidgen --ensure chmod 755 /run/dbus
2. 修复--privileged执行service命令的问题
使用--privileged时容器环境变量会被重置,需要手动指定D-Bus地址:
docker-compose exec --privileged tests env DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket service rsyslog status
3. 验证systemctl功能
修改后重新构建容器:
docker-compose down docker-compose up -d --build tests
现在执行systemctl命令即可正常工作:
docker-compose exec tests systemctl status rsyslog
如果仍有问题,可在Dockerfile中添加环境变量,确保shell继承D-Bus地址:
ENV DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket
内容的提问来源于stack exchange,提问作者AnthonyGP
相关产品推荐
相关产品推荐

