Docker.io init.d脚本不能在启动容器上工作

我有一个容器与odoo上的目录“/ opt / odoo /”。

“/etc/init.d/odoo-server”上的初始化脚本

#!/bin/bash ### BEGIN INIT INFO # Provides: odoo # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start openerp daemon at boot time # Description: Enable service provided by daemon. # X-Interactive: true ### END INIT INFO ## more info: http://wiki.debian.org/LSBInitScripts PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin DAEMON=/opt/odoo/openerp-server NAME=odoo DESC=odoo CONFIG=/etc/odoo-server.conf LOGFILE=/var/log/odoo/odoo-server.log PIDFILE=/var/run/${NAME}.pid USER=odoo export LOGNAME=$USER test -x $DAEMON || exit 0 set -e function _start() { start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$USER --background --make-pidfile --exec $DAEMON -- --config $CONFIG --logfile $LOGFILE } function _stop() { start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --retry 3 rm -f $PIDFILE } function _status() { start-stop-daemon --status --quiet --pidfile $PIDFILE return $? } case "$1" in start) echo -n "Starting $DESC: " _start echo "ok" ;; stop) echo -n "Stopping $DESC: " _stop echo "ok" ;; restart|force-reload) echo -n "Restarting $DESC: " _stop sleep 1 _start echo "ok" ;; status) echo -n "Status of $DESC: " _status && echo "running" || echo "stopped" ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload|status}" >&2 exit 1 ;; esac exit 0 

那我呢

 root@cca438c81a87:/# update-rc.d odoo-server defaults Adding system startup for /etc/init.d/odoo-server ... /etc/rc0.d/K20odoo-server -> ../init.d/odoo-server /etc/rc1.d/K20odoo-server -> ../init.d/odoo-server /etc/rc6.d/K20odoo-server -> ../init.d/odoo-server /etc/rc2.d/S20odoo-server -> ../init.d/odoo-server /etc/rc3.d/S20odoo-server -> ../init.d/odoo-server /etc/rc4.d/S20odoo-server -> ../init.d/odoo-server /etc/rc5.d/S20odoo-server -> ../init.d/odoo-server 

当我启动docker启动docker启动时,odoo-server无法启动,当我在docker /etc/init.d/odoo-server启动时运行好了…

发生什么事?

Docker容器通常没有可用的init系统。 如果你只是运行一个单一的服务 – 只要开始。

如果你需要更复杂的东西,看看supervisord或runit 。

容器不是虚拟机。

如果你正在寻找一个Docker镜像,这个镜像的行为就像是一个完整的虚拟机系统,那么你可以看一下这个镜像。

现在我在几个小时的工作中跟踪了这个bug。

debian系统的主要守护进程启动器/测试器/ start-stop-daemon工具start-stop-daemon通过检查/proc/<pid>/exe守护进程的虚拟软链接来检查守护进程是否存在, /proc/<pid>/exe (它应该指向启动过程的二进制映像)。

现在的问题是,在docker中,这个软链接默认不起作用。 这是因为docker必须在默认安装中使用严格的安全策略(主要用于运行不明身份的软件)。

这个任务有很多解决方法,有些需要更改容器的权限设置,有些则不需要。 两个例子:

  • 你可以把你的init脚本改成不使用start-stop-daemon同时使用--test--exec标志
  • 通过给--cap-add=SYS_ADMIN docker run命令提供--cap-add=SYS_ADMIN选项来启动你的--cap-add=SYS_ADMIN容器(不要担心,它不会给你的docker容器任何sysadm权限,这可能只是预防性的使用)

在这些旁边, systemd也不能在docker中工作,虽然它可能更像是docker的systemd的缺点。 暴发户可以使用,而不是systemd


Ps:码头开发人员/倡导者经常说“容器不是虚拟机”和类似的东西。 但是,在日常经验中,两者之间没有如此强烈的区分,而且对于软件生产者来说,至少对VPS类功能的最小支持肯定是有用的。 码头的发展也希望在不久的将来能够把重点放在这个方向上。

我发现服务没有启动是因为/usr/sbin/policy-rc.d返回一个101代码:

请参阅: http : //jpetazzo.github.io/2013/10/06/policy-rc-d-do-not-start-services-automatically/

码头工人把它放回一个容器中。

所以,修改build上的脚本就可以了,你可以在Dockerfile运行build.sh并运行下面的脚本:

 cat << EOF > /usr/sbin/policy-rc.d #!/bin/sh # For most Docker users, "apt-get install" only happens during "docker build", # where starting services doesn't work and often fails in humorous ways. This # prevents those failures by stopping the services from attempting to start. # exit 101 exit 0 EOF 

看起来像你的屁股是不正确的,而不是#!/ bin / bash应该是#! / bin / sh的

请参阅: https : //unix.stackexchange.com/questions/124566/how-to-debug-init-d-script-that-isnt-being-run