在Dockerfile搭建Ubuntu20.04+bind9环境时出现bind9.service未找到报错
报错原因
- Docker容器默认不会启动systemd init系统:你的本地Ubuntu 20.04宿主机默认以systemd作为PID 1进程管理服务,安装bind9时会自动将
bind9.service注册到systemd的服务单元目录,所以可以正常用systemctl操作。但Docker容器默认的PID 1进程是镜像指定的启动命令,默认不会运行systemd,systemctl是和systemd daemon通信的客户端,没有运行的systemd进程,自然找不到对应的服务单元。 - 你现有Dockerfile的执行逻辑存在问题:
RUN /usr/sbin/named -g -c /etc/bind/named.conf -u bind是在镜像构建阶段前台启动bind9的命令,执行到这一步时构建进程会永久阻塞,你能走到后续systemctl步骤说明这一行并未正常执行完成,也不会生成systemd需要的服务注册信息。 - 官方Ubuntu 20.04镜像做了轻量化裁剪,即便安装了systemd包,默认也不会启用相关配置,且容器默认没有开放systemd依赖的cgroup、tmpfs挂载权限,普通参数启动的容器根本无法正常运行systemd。
修正方案
完全不需要在容器里用systemd管理单服务,直接在容器启动时前台运行bind9即可,符合Docker单进程容器的最佳实践,修改后的Dockerfile如下:
FROM ubuntu:20.04 # 建议指定完整时区,避免时区异常 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 安装bind9,清理apt缓存减少镜像体积 RUN apt-get update && apt-get install -y --no-install-recommends \ bind9 \ && rm -rf /var/lib/apt/lists/* # 暴露DNS服务默认端口 EXPOSE 53/udp EXPOSE 53/tcp # 容器启动时前台运行bind9,进程退出则容器停止 CMD ["/usr/sbin/named", "-g", "-c", "/etc/bind/named.conf", "-u", "bind"]
如果确实需要在容器内使用systemd,启动容器时需要额外添加--privileged参数,并且挂载宿主机的/sys/fs/cgroup目录,同时将/sbin/init作为容器启动命令,该方式会提升容器权限、增加安全风险,不建议用于生产环境的单服务场景。
内容的提问来源于stack exchange,提问作者Siddhpura Amit
相关产品推荐
相关产品推荐

