Docker.io init.d 脚本在启动容器上不起作用
Posted
技术标签:
【中文标题】Docker.io init.d 脚本在启动容器上不起作用【英文标题】:Docker.io init.d script not working on start container 【发布时间】:2015-01-12 08:34:56 【问题描述】:我在目录“/opt/odoo/”上有一个带有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 start 启动 docker 时,odoo-server 没有启动,当我在 docker /etc/init.d/odoo-server start 内部运行时,它可以正常工作...
发生了什么?
【问题讨论】:
【参考方案1】:Docker 容器通常没有正常运行的初始化系统。如果您只是运行一个服务——只需启动它。
如果您需要更复杂的东西,请查看supervisord 或runit。
容器不是虚拟机。
【讨论】:
我找到了将解决方案作为答案发布的要点:***.com/a/37289932/2544762 “容器不是虚拟机。” 不应该。您提供的软件能够提供解决 docker 错误的半解决方案,因此您的答案值得一提。【参考方案2】:如果您正在寻找一个 Docker 镜像,它的行为与带有初始化系统的完整虚拟机非常相似,请查看 phusion baseimage
【讨论】:
我找到了将解决方案作为答案发布的要点:***.com/a/37289932/2544762【参考方案3】:看起来你的 shebang 不正确,而不是 #!/bin/bash 应该是 #! /bin/sh
见:https://unix.stackexchange.com/questions/124566/how-to-debug-init-d-script-that-isnt-being-run
【讨论】:
不,添加空格对 shebang 行没有影响。见***.com/questions/10197690/perl-shebang-space【参考方案4】:发现服务没有启动是因为/usr/sbin/policy-rc.d
返回了101码:
见:http://jpetazzo.github.io/2013/10/06/policy-rc-d-do-not-start-services-automatically/
并且 docker 将其设置为在容器中返回 101。
因此,在构建时更改该脚本将起作用,您可以创建一个 build.sh
以在 Dockerfile
中运行并运行以下脚本:
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
【讨论】:
作为构建过程的一部分在 Dockerfile 中运行?因为我试过了。文件已更改,但说/etc/init.d/postgresql
无法启动
这在更改文件并重新启动容器后不起作用。【参考方案5】:
现在我在几个小时的工作中找到了这个错误。
debian系统的主daemon starter/tester/stopper工具start-stop-daemon
通过检查/proc/<pid>/exe
中daemon进程的虚拟软链接来检查daemon是否存在的问题原因(应该指向已启动进程的二进制图像)。
现在的问题是,在 docker 中,这个软链接在默认情况下根本不起作用。这是因为 docker 在默认安装中必须使用严格的安全策略(它主要用于运行未识别的软件)。
该任务有很多变通方法,有些需要更改容器的权限设置,有些则不需要。两个例子:
您将初始化脚本更改为不使用带有--test
和--exec
标志的start-stop-daemon
你可以通过给docker run
命令提供--cap-add=SYS_ADMIN
选项来启动你的docker容器(别担心,它不会给你的docker容器任何sysadm权限,它可能只是生产使用的预防措施)李>
在这些旁边,systemd
在 docker 中也不起作用,尽管它可能更像是 systemd 的一个缺点,就像 docker 一样。可以使用upstart 代替systemd
。
P.s.:docker 开发者/倡导者经常说,“容器不是虚拟机”等等。但是,在日常体验中,两者之间并没有那么明显的区别,并且对于软件的高效 docker 使用,至少对类似 VPS 的功能的最小支持肯定是有用的。希望 docker 开发人员在不久的将来也能将精力集中在这个方向上。
【讨论】:
【参考方案6】:s6 是轻量级进程管理器,suitable 用于 docker 容器 (via)
【讨论】:
以上是关于Docker.io init.d 脚本在启动容器上不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Mongo mongod init.d 脚本无法在 CentOS 上运行
Cent OS 上 nginx 的 Init.d 脚本 [关闭]