Help us understand the problem. What is going on with this article?

Dockerコンテナ実行時のリトライ処理

More than 1 year has passed since last update.

最近AWS ECS、Fargate、Batchとコンテナに囲まれた生活を送っていた。

そんな中で「コンテナプロセスのリトライ処理出来るBatch君すごい!AWS様すごい!」とか思ってて、仮に自前でリトライ処理やろうと思ったらどうやればいいんだろうとか思いながら、Dockerドキュメントを読み漁ってたらDocker run リファレンス内に restart フラグを見つけて感動したので記事にした。

tl;dr

  • docker container run コマンド実行時に引数として --restart=on-failure:xx を渡すとリトライ処理が可能(xx=整数)
  • リトライ処理の実行条件はコンテナプロセス終了コードが0以外の場合
  • リトライされたコンテナプロセスはバックグラウンドプロセスで実行される

本当にリトライされるか検証

検証環境

  • macOS 10.13.1, Darwin 17.2.0
  • Docker version 18.06.1-ce

ディレクトリ構成

いつも自分が作業するディレクトリの下に以下のディレクトリ構成を作成する。

ディレクトリ名: retry_container

retry_container
.
├── Dockerfile
└── date.log

0 directories, 2 files

検証用Dockerfile

以下の内容を作成したDockerfile内に貼り付ける。

FROM alpine:3.8
CMD date >> /tmp/date.log && echo "container run!" && exit 1

このDockerfileで作成されるコンテナの振る舞いとしては以下の通り。

  • dateコマンドの標準出力を/tmp/date.logに書き込む
  • echoコマンドでホストマシン側に実行されたと分かる文字列を出力
  • exit コマンドに引数として1を渡し、プロセス終了コード1としてコンテナプロセスを終了させる

date.log

touchだけでOK。

$ touch date.log

コンテナイメージを作成

Dockerfiledate.logが用意できたらビルドする。

$ docker build -t retry_container .

Successfully built というメッセージが流れたらビルド成功。

コンテナを実行してみる

$ docker container run -v $HOME/work/retry_container/:/tmp/ retry_container:latest

-vオプションを用いて、ホストマシンの$HOME/work/retry_container/ディレクトリ以下の内容をコンテナ内の /tmp/ ディレクトリ以下にマウントしている。

$HOME/work/ 部分のファイルパスに関しては自分の環境に合わせて書き換える必要有り。

実行結果は以下の通り

container run!
$ cat ./date.log
Thu Sep 13 17:18:52 UTC 2018

ホストマシン側には標準出力として echo で出力した文字列とdate.log ファイル内にはコンテナ内で実行したdateコマンドのUTC時刻が書き込まれているはず。

書き込まれていれば、コンテナの実行は成功。

restart フラグを付与してコンテナを実行してみる

$ docker container run --restart=on-failure:10 -v $HOME/work/retry_container/:/tmp/ retry_container:latest

restart フラグに与える引数はon-failure:10なのでリトライ処理試行回数は10回となる。

実行結果

container run!

出力を見た感じrestartフラグを付ける前と変わっていない感じがする。

しかし、date.logファイルの中身が大きく変わってくるはずだ。

$ cat ./date.log
Thu Sep 13 17:18:52 UTC 2018
Thu Sep 13 17:35:35 UTC 2018
Thu Sep 13 17:35:37 UTC 2018
Thu Sep 13 17:35:38 UTC 2018

明らかに自分が実行した回数以上にdate.logファイルにdateコマンドの出力が書き込まれているはず。

docker container run --restart=on-failure:10 -v $HOME/work/retry_container:/tmp/ retry_container:latestを実行して、数十秒の間にdocker container lsコマンドを実行してみよう。

すると、現在実行されているコンテナとしてretry_container:latestがまだ実行されているはず。

なぜdate.logは書き込まれているのに、echoがホストマシン側に出力されないかというと、リトライされたコンテナプロセスはバッググラウンドプロセスで実行されるからだ。

数分待ったあとにdocker container lsを実行して、retry_container:latestコンテナが実行されていなければ10回分のリトライ処理が終了したということになる。

確認してみよう。

$ cat ./date.log | wc -l
12

書かれた手順通りに進めたなら12という数字が出力されるはず。

  • コンテナが正しく実行されるかどうかの確認として1回
  • リトライ処理に入る前に実行されたので1回
  • リトライ処理として10回

restartフラグに引数として渡した値分リトライ処理されていることが分かった。

リトライインターバルに関しては不明。

時間があれば調べてみよう。。

リトライ処理される度にインターバルが長くなっている気はする。

所感

AWS Batchのリトライ処理に関してはrestartフラグ使ってリトライ処理を実現してそう。

改めてリファレンスは時間のある時に目を通した方が良いなというのを強く感じた。

hey1you1
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away