毎秒 "Hey, Yo!" と言い続けるコンテナ

1秒ごとに “Hey, Yo!” というログを吐き続けるだけのコンテナをちょうど1年前くらいにデバッグ用に作って GitHub と Docker Hub に置いていたんですが、ふと昨日見てみたらすでに 10,000 回以上 pull されていました. いったい誰がどんな目的で使っているのか非常に興味があります.

僕以外の人が何に利用してくれているのかは全くもって不明ですが、もしかしたら他にもこれを便利だと思ってくれる人がいるかもしれないので記事に起こしてみました.

ちなみに

に置いてます.

Everlasting “Hey, Yo” per second

この “Hey-Yo” コンテナはもともと ECS でタスク内コンテナの起動・停止順の指定ができるようになった際に、合わせてサポートされた --stop-timeout (Docker CLI のオプション)をテストするために作りました.

--stop-timeout オプションを利用すると、docker stop コマンドでコンテナに SIGTERM が送られてから SIGKILL で非業の死を遂げるまでの時間をコントロールすることができます.
もちろん本来は SIGTERM を受け取ったらサクッとグレースフルに終了すべきですが、世の中にはのっぴきならない事情でサクッと停止できない、停止処理が長引くアプリケーションも存在します

で、停止までのタイムアウトが正しく機能しているかをテストするために、

  • 毎秒 “Hey, Yo!” と標準出力にログを吐きつつ
  • SIGTERM を受け取ったら受け取ったことをログに出力し
  • その後も SIGKILL で停止されるまで淡々とログを吐き続ける

というだけのシェルスクリプトを含んだコンテナを作りました.

“Hey, Yo!” in Action

試しに Docker for Desktop とかで実行するとこんな感じになります.

$ docker run toricls/everlasting-hey-yo:latest
Hey, Yo!
Hey, Yo!
Hey, Yo!
...

ターミナルの別タブなどを開き、docker ps コマンドで Hey-Yo コンテナのコンテナ ID が分かりますので、そのまま別タブの方で docker stop コマンドを利用してコンテナを止めてみます.

$ docker stop YOUR_CONTAINER_ID

すると、ログが以下のような感じになります. “Hey, Hey, Hey, Yo!!!” となっているところで Hey-Yo コンテナが SIGTERM を受け取り、その10秒後(Docker のデフォルト)に強制的に停止させられている(SIGKILL)のが分かります.

...
Hey, Yo!
Hey, Hey, Hey, Yo!!! <- ここで SIGTERM を受け取った
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo! <- このあと SIGKILL で殺られた

stop-timeout を伸ばしてみる

SIGTERM から SIGKILL までのタイムアウトを15秒に伸ばしてみます.

$ docker run --stop-timeout=15 toricls/everlasting-hey-yo:latest
Hey, Yo!
Hey, Yo!
...

途中で先ほどと同じように docker stop コマンドで止めてみます.

...
Hey, Hey, Hey, Yo!!! <- ここで SIGTERM を受け取った
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo!
Hey, Yo! <- このあと SIGKILL で殺られた

ちゃんと SIGKILL の送出まで15秒程度待ってくれたようです.

Hey-Yo コンテナの実行時オプション

なんの意味があるのかは分かりませんが、現時点で全部で3つの実行時オプションがあり、環境変数を使って有効化できます. 複数のオプションの併用もたぶん可能です.

1. LET_ME_DIE: SIGTERM を受け取ったら大人しく停止するオプション

もともと SIGTERM から SIGKILL までのタイムアウトが意図した通りに動いているかを調べるためのコンテナのはずなので、SIGTERM で大人しく停止したらもはや意味がないかもしれませんが、一応指定できます.

$ docker run -e LET_ME_DIE=1 toricls/everlasting-hey-yo:latest
Hey, Yo!
Hey, Yo!
...

ここで docker stop などで停止すると、

...
Hey, Yo!
Hey, Yo!
Hey, he... <- SIGTERM を受け取った

というログが出力され、その3秒後に大人しく停止します.

2. GIVE_ME_PATTERN: ログメッセージの種類が増えます

全部 “Hey, Yo!” でつまらないというあなたのために、このオプションを用意しました. パラメータ名からはなんだかパターンが増えそうに見えますが、50% の確率で “Hey, Yo!” ではない別のメッセージ(1種類)が出力されるだけです.

$ docker run -e GIVE_ME_PATTERN=1 toricls/everlasting-hey-yo:latest
Hey, Yo!
Check It Out! Yo!
Hey, Yo!
Check It Out! Yo!
...

これだけです.

3. TIMESTAMP: ログメッセージの頭にタイムスタンプを追加します

今回この記事を書くにあたり、せめて一つくらいはいかにもそれらしいオプションが欲しいと思い追加しました. ログメッセージの頭にタイムスタンプが出ます.

$ docker run -e TIMESTAMP=1 toricls/everlasting-hey-yo:latest
2020-05-07T11:45:24+0000 Hey, Yo!
2020-05-07T11:45:25+0000 Hey, Yo!
2020-05-07T11:45:26+0000 Hey, Yo!
2020-05-07T11:45:27+0000 Hey, Yo!

併用してみる

併用すると少し華やかになります.

$ docker run -e LET_ME_DIE=1 -e GIVE_ME_PATTERN=1 -e TIMESTAMP=1 toricls/everlasting-hey-yo:latest
2020-05-07T11:46:15+0000 Hey, Yo!
2020-05-07T11:46:16+0000 Check It Out! Yo!
2020-05-07T11:46:17+0000 Hey, Yo!
2020-05-07T11:46:18+0000 Hey, Yo!
2020-05-07T11:46:19+0000 Check It Out! Yo!
2020-05-07T11:46:20+0000 Hey, Yo!
2020-05-07T11:46:21+0000 Check It Out! Yo!
2020-05-07T11:46:22+0000 Check It Out! Yo!
2020-05-07T11:46:23+0000 Hey, Yo!
2020-05-07T11:46:24+0000 Check It Out! Yo!
2020-05-07T11:46:25+0000 Hey, Yo!
2020-05-07T11:46:26+0000 Hey, he...

ちなみに

GitHub には以下のキャプチャのような感じでリポジトリにタグのようなものを付けられる「トピック」という機能があります.

どうでもいい話ですが、“hey-yo” というトピックを利用しているパブリックレポジトリは現時点ではこの everlasting-hey-yo リポジトリだけのようです. 他にも “hey-yo” トピックなリポジトリが増えたらいいなーなどと思っています.

何か役立ちそうだったら使ってみてください.