ECSにバッチ処理やらせるときにhako oneshotが便利
要約
ECSにバッチ処理をやらせるときに、 hako oneshotを使うと便利です。
hako oneshotを活用する話
先日(10/12)のDockerの勉強会*1にて、hako oneshot を活用する話をしました!
以下は私の職場での活用の一例。の雰囲気の図。
以下がスライドです。
hakoについてちょっと紹介
Dockerコンテナのデプロイツールです。ECSに対応。
deploy
と oneshot
が主なサブコマンドです。
hako deploy
Dockerコンテナをデプロイする。 使い方はこちらの記事が詳しいです。
hako oneshot
Dockerコンテナにバッチ処理的なタスクをやらせる。 使い方はこちらの記事が詳しいです。
hako oneshotの様子
ECSに何かをやらせるときに、何回かAPIを叩くことになるのですが、 hakoがいろいろとやってくれます。
以下がその様子(簡略化のため分岐とかも適当な図で恐縮)です。
利点・良いと思った機能
上記の通り、hako を使うことにより、このようなECS API叩く自前コードが減る のは大きな利点です。
hako oneshotを使ってみて他に感じた利点・良いと思った機能は
- TaskDefinition重複登録されないようにチェックしてくれる
- scale outも面倒見てくれる
dry-run
があるらしい- あまり使ってないけど使ってる人が便利っぽいと言っていた
- コンテナの終了コードで終了してくれる
- コンテナが終了コード0で終わればhako oneshotも0で終わる
- 手元のシェルで
&&
でつなぐ、とかできそう
- 手元のシェルで
- コンテナが終了コード0で終わればhako oneshotも0で終わる
C-c
でabortできる
というところです。
まとめ
勝手にhako oneshotについて紹介しました!
間違い等ありましたらご指摘ください!
よろしくお願いいたします。
*1:Web Tech Tokyo #1(Docker Tips 共有会) http://web-tech-tokyo.connpass.com/event/40548/
jqの--exit-statusオプションについて調べてまとめたので100ブクマぐらいお願いします
manすると1文が長くてつらい。neither A nor Bとか懐かしい。両方否定ね。
man jq
o -e / --exit-status: Sets the exit status of jq to 0 if the last output values was nei- ther false nor null, 1 if the last output value was either false or null, or 4 if no valid result was ever produced. Normally jq exits with 2 if there was any usage problem or system error, 3 if there was a jq program compile error, or 0 if the jq program ran.
まとめ
command | stdout | exit status |
---|---|---|
$ echo '{}' | jq . |
{} |
0 |
$ echo '{}' | jq --exit-status . |
{} |
0 |
$ echo 'true' | jq . |
true |
0 |
$ echo 'true' | jq --exit-status . |
true |
0 |
$ echo 'false' | jq . |
false |
0 |
$ echo 'false' | jq --exit-status . |
false |
1 |
$ echo 'null' | jq . |
null |
0 |
$ echo 'null' | jq --exit-status . |
null |
1 |
$ echo 'foo' | jq . |
*1 | 4 |
$ echo 'foo' | jq --exit-status . |
*2 | 4 |
以上です
Dockerコンテナが消費するメモリの最大値を知りたいのだが
ECSで、この画面で悩むんですが、皆さんどうされてるんでしょうか。。
「Maximum Memory」にメモリの上限値を入力する。
docker runの-mオプションに相当する。
memory.max_usage_in_bytesを見て調べるということでどうか。
$ # 調べたいコンテナを起動(-dでデタッチ)、コンテナIDを取得する $ CID=$(docker run -d alpine sleep 100) $ $ # 取得したコンテナIDからmax_usage_in_bytes(使用したメモリの最大値) $ cat /cgroup/memory/docker/$CID/memory.max_usage_in_bytes 6422528
手元のubuntuだと、「/cgroup/memory/docker」の部分は「/sys/fs/cgroup/memory/docker」でした。
ちなみに以下はcgroupで取れるmemory関連の値。抜粋。
memory.max_usage_in_bytes
cgroup 内のプロセスによるメモリー最大使用量をレポートします (バイト単位)。
memory.usage_in_bytes
cgroup 内のプロセスによる現在のメモリー総使用量をレポートします (バイト単位)。
memory.limit_in_bytes
ユーザーメモリーの最大値 (ファイルキャッシュを含む) を設定します。単位が指定されていない場合、その値はバイト単位と解釈されますが、より大きな単位を示すサフィックスを使用することが可能です (キロバイトには k または K、メガバイトには m または M、ギガバイトには g または G)。 root cgroup を制限するのには、memory.limit_in_bytes は使用できません。値を適用できるのは、下位階層のグループに対してのみです。 memory.limit_in_bytes に -1 と書き込み、現行の制限値を削除します。
おまけ
Dockerコンテナ内からDockerコンテナが消費したメモリの最大値を知るにはどうすればよいかを考えてみました。
(良い方法は思いつきませんでした、、、、)
-vオプションで/cgroupをマウントする。。。という方法でどうでしょうか。
$ docker run -v /cgroup/memory/docker:/docker:ro ...
rubyコンテナを走らせ、マウントされた/dockerディレクトリを見てmemory.max_usage_in_bytesをチェックする例です。
$ docker run \ -v /cgroup/memory/docker:/docker:ro \ -it \ ruby:2.3.1-alpine irb
# memory.max_usage_in_bytesを取得するヘルパ定義 irb(main):001:0> def memory_max_usage_in_bytes irb(main):002:1> File.read(Dir["/docker/#{ENV.fetch('HOSTNAME')}*/memory.max_usage_in_bytes"].first).to_i/1024.0/1024.0 irb(main):003:1> end => :memory_max_usage_in_bytes irb(main):004:0> memory_max_usage_in_bytes => 11.27734375 # サイズが1万、String配列を作る irb(main):007:0> (1..10_000).map(&:to_s); nil => nil irb(main):008:0> memory_max_usage_in_bytes => 11.80859375 # サイズが10万、String配列を作る irb(main):009:0> (1..100_000).map(&:to_s); nil #ai => nil irb(main):010:0> memory_max_usage_in_bytes => 17.55859375 # サイズが100万、String配列を作る irb(main):011:0> (1..1_000_000).map(&:to_s); nil #ai => nil irb(main):012:0> memory_max_usage_in_bytes => 77.29296875 # サイズが300万、String配列を作る irb(main):013:0> (1..3_000_000).map(&:to_s); nil #ai => nil irb(main):014:0> memory_max_usage_in_bytes => 278.29296875
まわりくどいですが、これはこれで便利な気がします。