web-dev-qa-db-ja.com

Docker.io init.dスクリプトが開始コンテナーで機能しない

私は、 "-opt/odoo /"ディレクトリに odoo が付いたコンテナを持っています。

「/etc/init.d/odoo-server」上のinitスクリプト

#!/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 startを起動すると、odoo-serverが起動せず、docker /etc/init.d/odoo-server start内で実行すると、正常に動作します...

何が起こっている?

11
Mariano DAngelo

Dockerコンテナには通常、機能するinitシステムがありません。単一のサービスを実行しているだけなら、それを開始するだけです。

より複雑なものが必要な場合は、 supervisord または runit を参照してください。

コンテナは仮想マシンではありません。

15
user2105103

本格的な動作のように動作するDockerイメージを探している場合VM init systemの場合は、 phusion baseimage を見てください。

5

今、私は数時間の作業でバグを追跡しました。

Debianシステムのメインデーモンスターター/テスター/ストッパーツールであるstart-stop-daemonが、/proc/<pid>/exeのデーモンプロセスの仮想ソフトリンクを調べてデーモンの存在を確認する問題の理由開始されたプロセスのバイナリイメージを指す必要があります)。

さて、問題は、Dockerではこのソフトリンクがデフォルトで機能しないことです。これは、Dockerがデフォルトのインストールで厳密なセキュリティポリシーを使用する必要があるためです(主に未確認のソフトウェアを実行するために使用されます)。

タスクには多くの回避策があり、コンテナの特権設定を変更する必要があるものと、そうでないものがあります。 2つの例:

  • start-stop-daemonフラグと--testフラグの両方を使用して--execを使用しないように初期化スクリプトを変更します
  • --cap-add=SYS_ADMINコマンドにdocker runオプションを指定して、Dockerコンテナーを起動します(Dockerコンテナーにsysadm権限は付与されません。生産的な使用のための予防策にすぎない可能性があります)。

これらの隣にあるsystemdもdockerでは機能しませんが、おそらくdockerのsystemdの欠点です。 systemdの代わりに、 pstart を使用できます。


追記:Docker開発者/支持者は、「コンテナはVMではない」などとよく言っています。しかし、日常の経験では、2つの間にそれほど大きな違いはありません。ソフトウェアの生産的なDockerの使用には、少なくともVPSのような機能の最小限のサポートが確実に役立つでしょう。うまくいけば、ドッカーの開発も近い将来、この方向に向けて努力を集中させるでしょう。

サービスが開始されていないのは、/usr/sbin/policy-rc.dが101コードを返すことが原因であることがわかりました。

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

そしてDockerはそれをコンテナで101を返すように設定しました。

そのため、ビルド時にスクリプトが機能するように変更して、build.shDockerfileで実行し、以下のスクリプトを実行できます。

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
2
Alfred Huang