xiaolingzi's blog

每天都在成长...

欢迎您:亲

Centos7 Docker容器中开启systemd(systemctl)

xiaolingzi 发表于 2018-03-27 13:57:31

这段时间开始将部分服务放到容器来运行,主要还是使用centos7来作为基础镜像。自己的docker中服务在Dockerfile中主要还是通过yum来进行安装,所以在运行了之后想看看服务的状态,但当使用熟悉的systemctl命令来查看服务时,发现该命令不可用了。折腾了一会才把它弄了起来,所以就有了这篇文章来记录一下。

一、报错及原因

在执行systemctl命令的报错信息如下:

Failed to get D-Bus connection: Operation not permitted

原因分析:

通过查找资料得知,在最新的centos7的docker基础镜像中其实有包含systemd的,但默认是关闭的,所以只需要将其开启就可以。

二、启用systemd

官方说明地址如下:

https://hub.docker.com/r/_/centos/

1.首先,制作启用了systemd的centos7镜像,Dockerfile内容如下

FROM centos:7
           
ENV container docker
           
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
           
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
           
rm -f /lib/systemd/system/multi-user.target.wants/*;\
           
rm -f /etc/systemd/system/*.wants/*;\
           
rm -f /lib/systemd/system/local-fs.target.wants/*; \
           
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
           
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
           
rm -f /lib/systemd/system/basic.target.wants/*;\
           
rm -f /lib/systemd/system/anaconda.target.wants/*;
           
VOLUME [ "/sys/fs/cgroup" ]
           
CMD ["/usr/sbin/init"]

然后build生成镜像,命令如下(名称可自行修改):

docker build --rm -t local/c7-systemd .

这样我们就得到了启用了systemd的centos7镜像

2.其次,我们就可以使用该基础镜像镜像制作我们自己的服务镜像,如下是官方给的例子,Dockerfile注意不要漏掉CMD那行。

FROM local/c7-systemd
           
RUN yum -y install httpd; yum clean all; systemctl enable httpd.service
           
EXPOSE 80
           
CMD ["/usr/sbin/init"]

然后生成该服务镜像,命令如下:

docker build --rm -t local/c7-systemd-httpd .

最后运行容器,上面官方地址给的命令如下(注意这里挂载的目录一定要):

docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/c7-systemd-httpd

但我在运行的时候报错了,错误如下:

[!!!!!!] Failed to mount API filesystems, freezing.

查找资料,说是要加上特权,所以把命令改为如下即可:

docker run --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/c7-systemd-httpd

如果需要后台运行,将上面-ti改为-dti即可,如果要为容器自定义名称就加入--name,比如--name web

3.最后我们进入容器,执行systemctl命令发现就可以使用了,进入容器命令如下:

docker exec -it web /bin/bash

将web改为实际的容器名称或id即可。

三、关于是否需要启用systemd

这个问题,我先直接复制一个国外友人的答复,如下:

Derek is right. However, let me point out that containers are not really designed to operate the same way as a typical full stack operating system. There is no kernel and, as a result (by default), no service management system (which relies on kernel functionality to operate as expected).

Now, you CAN get systemd installed, but it is still experimental and not recommended (or supported officially). Containers should be both ephemeral and 'specific', meaning that you are doing one thing generally and one thing only. If you have something you want to run as a 'service', you can generally accomplish that by starting the daemon directly (for example, with Apache web server, you could run '/sbin/apachectl -D FOREGROUND' which would start the apache daemon for HTTP service).

这只是其中一种说法,具体大家根据自己的实际情况来,在需要启用systemd的时候可以按上面的方式来。


      

转载请注明出处:http://www.xxling.com/article/3115.aspx

  • 分类: docker
  • 阅读: (1600)
  • 评论: (0)
拍砖 取消
请输入昵称
请输入邮箱
*
 选择评论类型
300字以内  请输入评论内容