web-dev-qa-db-ja.com

コンテナーの自動削除でDockerコンテナーを自動的に再起動するにはどうすればよいですか?

私は汎用のVPSを持っており、その上でアプリをDocker化しています。その上に約5〜6個のコンテナーがあり、それ以外はほとんどないため、ボックスは必要に応じて簡単に再構築できます。

アプリごとに、起動スクリプトを用意しています。 WordPressコンテナは次のようになります:

#!/bin/bash

# Get the Host IP address
export DOCKER_HOSTIP=`ifconfig docker0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1`
echo "Connecting to database on Docker Host ${DOCKER_HOSTIP}"

docker run \
    --add-Host=docker:${DOCKER_HOSTIP} \
    --network dockernet \
    --network-alias jonblog \
    --detach \
    --restart always \
    --rm \
    jonblog

ただし、エラーが返されます。

競合するオプション:--restartおよび--rm

これが理にかなっていると言うDockerチケットがいくつかありますが、私にはわかりません。私の意味は明確だと思います:コンテナーが実行されていない場合(たとえば、起動時)、それを開始したいと思います。それが死んだ場合は、コンテナが削除され、ベースイメージから新しいフレッシュなコンテナが作成されることを期待しています。コンテナはいずれにせよ不変である必要があります-メディアファイルやログなど、保存したい状態はすべてボリュームに書き込まれます。

そのため、--restartフラグを削除し、プロセスマネージャーを使用してDockerコンテナーを停止および開始する必要があると考えました。ここでMonitを使用できますか?私は次のようなことができることを望んでいました:

CHECK PROCESS jonblog MATCHING jonblog
  START PROGRAM = "/root/docker/jonblog/Host-start.sh"
  STOP PROGRAM = "docker stop jon-blog"

ただし、これはdocker psではなくシステムプロセステーブルをチェックするため、指定された文字列に一致するものは見つかりません。定期的にdocker psを実行して、出力の行を一致させることはできますか?

堅牢であることが証明されたら、別のツールを使用できれば幸いです。たとえば、私はスーパーバイザを少し重いと思いますが、それがDockerで動作するようになれば、それを使用したいと思います。

--rmの説明

--rmが必要な理由は、Dockerizationプロセス中に、現在実行中のコンテナーを停止し、新しいバージョンのイメージをload停止して、上記のスクリプトを再実行するためです。これは、各コンテナのrestartポリシーがDockerに通知されていることを意味します。ボックスを再起動した後、アプリの15個ほどのわずかに異なるバージョンが同時に実行されることがわかりましたが、これは意図されていません。

古いコンテナーでdocker update --restart neverを使用してこれを防ぐことができると思いますが、コンテナーが停止すると、コンテナーが横になっているままになり、すぐに自動削除されます。ある種のcronジョブを使用して定期的に古いファイルをクリーンアップすることはできましたが、Dockerが私のために実行できることを考えると、それは少し厄介な感じがします。

さまざまな答えを探す

非常に役立つコメントから、Minikubeを調べる必要があることが示唆されました。これにより、Kubernetesのセットアップが明らかに簡略化されます。

まだもっと軽量なソリューションが提案されることを望んでいるので、選択できる答えはたくさんあります。指摘したように、Monitのようなプロセススーパーバイザが機能するかどうかの答えを知りたいと思います。

頭から離れて、5秒ごとに1分間ファイルにdocker psを書き込むシェルループを作成し、それをCronで毎分実行することができました。次に、grepとMonit CHECK PROGRAMシステムチェックを使用してそのファイルをスキャンできます。ちょっとハックですが、問題があれば簡単に理解できます。その提案について何か進歩はありますか?

4
halfer

Dockerの現在の理解に適した答えがあります。私はコメントでミニクベを試してみるように助言されました、そして間違いなくこれはすぐにスピンアップすることができますが、これが私が何週間もタールで動けなくなるような学習のうさぎの穴になるのではないかと心配しました。私のエンジニアリングの原則の1つは、新しい情報を詰め込むための認知的限界に達したときを知ることです。

したがって、私はこの問題を簡単な方法で解決しようと試みました。私には2つの選択肢がありました。

  1. Dockerのコンテナー自動削除機能を使用して、独自の再起動システムをセットアップする
  2. Docker再起動ポリシーを使用して、独自のコンテナー削除システムをセットアップする

プロセススーパーバイザーのMonitは軽量であるという理由もあれば、慣れているという理由もあって使いやすいだろうという考えから、これらの最初のものから始めました。ただし、Dockerコンテナープロセスリストを正しく取得できないというコアの問題を回避しているため、それは間違ったソリューションのように感じられ始めました。

実際、2番目のオプションははるかにクリーンでした。これは、コンテナーのクリーンアップの停止が実際には優先事項ではないという事実によって増幅されました。もちろん、私はこれにDockerを使用しました。これがDockerfileです:

# Docker build script for Docker Tidy

FROM Alpine:3.6

RUN apk update
RUN apk add docker

# See this for BusyBox cron schedules
# https://Gist.github.com/andyshinn/3ae01fa13cb64c9d36e7
COPY bin/docker-tidy.sh /etc/periodic/daily/
RUN chmod +x /etc/periodic/daily/docker-tidy.sh

# Start Cron in the foreground
ENTRYPOINT ["crond", "-l", "2", "-f"]

そして、これがbin/docker-tidy.sh

#!/bin/sh
#
# With thanks to:
# http://www.doublecloud.org/2015/05/simple-script-to-list-and-remove-all-stopped-docker-containers/

docker rm -v $(docker ps -a -q -f status=exited)

最後に、私のソリューションの1つの欠点は、コンテナーのクリーンアップを停止する前にホストを再起動すると、それらのコンテナーも再起動するように見えることです。したがって、新しいコンテナを開始する前に、それらのコンテナの再起動ポリシーをリセットします。

たとえば、ホストでDocker Tidyコンテナー自体を起動する方法を次に示します。実際には、ポリシー変更コードを独自のスクリプトに整理しましたが、これにより一般的なアイデアが得られます。

#!/bin/bash

# Removes the restart policy from previous containers
CONTAINER_LABEL=docker-tidy-instance
docker ps --all --filter label=$CONTAINER_LABEL --quiet | xargs --no-run-if-empty docker update --restart no

docker run \
    --label $CONTAINER_LABEL \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --detach \
    --restart always \
    docker-tidy
0
halfer