在docker conatiner内使用systemctl启动服务

在我的Dockerfile中,我正在尝试安装多个服务,并希望在启动容器时自动启动它们。 其中一个服务是mysql,当我启动容器时,我看不到mysql服务启动。 当我尝试手动启动时,出现错误: Failed to get D-Bus connection: Operation not permitted

Dockerfile:

 FROM centos:7 RUN yum -y install mariadb mariadb-server COPY start.sh start.sh CMD ["/bin/bash", "start.sh"] 

我的start.sh文件:

 service mariadb start 

Docker构build:

 docker build --tag="pbellamk/mariadb" . 

Docker运行:

 docker run -it -d --privileged=true pbellamk/mariadb bash 

我检查了centos:systemd映像,这也没有帮助。 如何启动使用systemctl / service命令启动服务的容器。

当您使用bash作为docker run命令时,init系统(例如SystemD)不会启动(您的启动脚本也不会启动,因为您传递的命令将覆盖Dockerfile中的CMD )。 尝试将用于/sbin/init的命令更改为以守护进程模式启动容器,然后使用docker exec -it <container id> sh在shell中查看。

Docker是围绕每个容器的单个服务/进程devise的。 尽pipe它肯定支持在一个容器中运行多个进程,并且绝不会阻止你这样做,但是最终会遇到容器中的多个服务不能完全映射Docker或外部工具所期望的区域。 像转向扩展服务,或者跨主机使用Docker swarm只支持每个容器一个服务的概念。

Docker Compose允许你将多个容器组合成一个单一的定义,这意味着你可以使用更多的标准预build容器( httpdmariadb )而不是自己构build。 将定义映射到Docker Swarm服务相当容易。 另外请看Kubernetes和Marathon / Mesos来pipe理集装箱作为一种服务。

Docker中的进程pipe理

可以在容器中运行systemd ,但它需要 – 对主机和/sys/fs/cgroup卷的--privileged访问,因此可能不适合大多数情况。

s6-overlay项目使用s6提供了一个更加适合Docker的过程pipe理系统。

实际上你需要ssh访问一个容器是非常罕见的,但是如果这是一个困难的需求,那么你将被困在构build自己的容器和使用stream程pipe理器。

您可以避免在Docker容器中完全运行systemd守护进程。 你甚至可以避免写一个特殊的start.sh脚本 – 这是使用docker-systemctl-replacement脚本的另一个好处。

docker systemctl.py可以parsing正常的* .service文件来知道如何启动和停止服务。 您可以将其注册为映像的CMD,在这种情况下,它将查找所有启用systemctl的服务 – 这些服务将以正确的顺序启动和停止。

目前的testing包包括LAMP堆栈包括centos的testing用例,所以它应该在您的设置中运行良好。