Docker构建安装mdatp提示未以systemd为init系统报错
问题描述
在Docker容器中安装Windows Defender(mdatp),执行docker build构建镜像流程时出现报错:
System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is down
当前使用的Dockerfile配置如下:
FROM openjdk:11 RUN apt-get -y update RUN apt-get -y install curl RUN curl -o microsoft.list https://packages.microsoft.com/config/debian/10/prod.list RUN mv ./microsoft.list /etc/apt/sources.list.d/microsoft-prod.list RUN apt-get install -y gpg RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - RUN apt-get install apt-transport-https RUN apt-get -y update RUN apt-get install -y systemd RUN apt-get install -y mdatp
报错根因
- mdatp的deb安装包默认会在安装阶段尝试通过systemd注册自启服务,连接systemd总线完成服务初始化。
- Docker镜像构建阶段不会启动systemd作为PID 1进程,该阶段默认PID 1是执行构建命令的shell进程,没有运行systemd和dbus服务,因此会触发连接总线失败的报错。
- 仅在构建阶段安装systemd包无法解决问题,因为安装操作不会触发systemd init流程。
解决方法
方案1:安装阶段屏蔽服务自启(推荐,不影响后续容器运行)
Debian系的deb包安装时会检查/usr/sbin/policy-rc.d文件的返回值,返回101时会跳过所有安装阶段的服务启动操作,直接修改Dockerfile对应步骤即可:
- 在安装mdatp前写入策略文件,赋予执行权限
- 完成mdatp安装后删除该策略文件,避免影响容器启动后的正常服务操作
修改后的核心构建片段:
RUN apt-get -y update # 写入服务启动屏蔽策略 RUN echo '#!/bin/sh\nexit 101' > /usr/sbin/policy-rc.d && chmod +x /usr/sbin/policy-rc.d RUN apt-get install -y systemd RUN apt-get install -y mdatp # 安装完成后清理策略文件 RUN rm /usr/sbin/policy-rc.d
注意:如果需要在容器运行时正常启动mdatp服务,启动容器时必须指定systemd为PID 1进程,同时挂载cgroup目录、添加特权权限,参考启动命令:docker run --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro 自定义镜像名 /lib/systemd/systemd
方案2:忽略服务配置(仅适合不需要运行mdatp服务的场景)
如果仅需要在镜像中打入mdatp二进制文件,不需要在容器内实际运行mdatp服务,可以直接强制覆盖安装时的服务报错,不过这种方式安装的mdatp无法正常提供防护能力,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Testuser
相关产品推荐
相关产品推荐

