サーバレスって言いたいだけじゃないです
Linux向けAzure BatchのPreviewがはじまりました。地味ですが、なかなかのポテンシャルです。
クラウドでバッチを走らせる時にチャレンジしたいことの筆頭は「ジョブを走らせる時だけサーバ使う。待機時間は消しておいて、 節約」でしょう。
ですが、仕組み作りが意外に面倒なんですよね。管理サーバを作って、ジョブ管理ソフト入れて、Azure SDK/CLI入れて。クレデンシャルを安全に管理して。可用性確保して。バックアップして。で、管理サーバは消せずに常時起動。なんか中途半端です。
その課題、Azure Batchを使って解決しましょう。レッツ管理サーバレスバッチ処理。
コンセプト
- 管理サーバを作らない
- Azure Batchコマンドでジョブを投入したら、あとはスケジュール通りに定期実行される
- ジョブ実行サーバ群(Pool)は必要な時に作成され、処理が終わったら削除される
- サーバの迅速な作成とアプリ可搬性担保のため、dockerを使う
- セットアップスクリプト、タスク実行ファイル、アプリ向け入力/出力ファイルはオブジェクトストレージに格納
サンプル
Githubにソースを置いておきます。
バッチアカウントとストレージアカウント、コンテナの作成とアプリ、データの配置
公式ドキュメントで概要を確認しましょう。うっすら理解できたら、バッチアカウントとストレージアカウントを作成します。
ストレージアカウントに、Blobコンテナを作ります。サンプルの構成は以下の通り。
.
├── blob
│ ├── application
│ │ ├── starttask.sh
│ │ └── task.sh
│ ├── input
│ │ └── the_star_spangled_banner.txt
│ └── output
applicationコンテナに、ジョブ実行サーバ作成時のスクリプト(starttask.sh)と、タスク実行時のスクリプト(task.sh)を配置します。
- starttask.sh - docker engineをインストールします
- task.sh - docker hubからサンプルアプリが入ったコンテナを持ってきて実行します。サンプルはPythonで書いたシンプルなWord Countアプリです
また、アプリにデータをわたすinputコンテナと、実行結果を書き込むoutputコンテナも作ります。サンプルのinputデータはアメリカ国歌です。
コンテナ、ファイルには、適宜SASを生成しておいてください。inputではreadとlist、outputでは加えてwrite権限を。
さて、いよいよジョブをJSONで定義します。詳細は公式ドキュメントを確認してください。ポイントだけまとめます。
- 2016/04/29 05:30(UTC)から開始する - schedule/doNotRunUntil
- 4時間ごとに実行する - schedule/recurrenceInterval
- ジョブ実行後にサーバプールを削除する - jobSpecification/poolInfo/autoPoolSpecification/poolLifetimeOption
- ジョブ実行時にtask.shを呼び出す - jobSpecification/jobManagerTask/commandLine
- サーバはUbuntu 14.04とする - jobSpecification/poolInfo/autoPoolSpecification/virtualMachineConfiguration
- サーバ数は1台とする - jobSpecification/poolInfo/autoPoolSpecification/pool/targetDedicated
サーバプール作成時にstarttask.shを呼び出す - jobSpecification/poolInfo/autoPoolSpecification/pool/startTask
{ "odata.metadata":"https://myaccount.myregion.batch.azure.com/$metadata#jobschedules/@Element", "id":"myjobschedule1", "schedule": { "doNotRunUntil":"2016-04-29T05:30:00.000Z", "recurrenceInterval":"PT4H" }, "jobSpecification": { "priority":100, "constraints": { "maxWallClockTime":"PT1H", "maxTaskRetryCount":-1 }, "jobManagerTask": { "id":"mytask1", "commandLine":"/bin/bash -c 'export LC_ALL=en_US.UTF-8; ./task.sh'", "resourceFiles": [ { "blobSource":"yourbloburi&sas", "filePath":"task.sh" }], "environmentSettings": [ { "name":"VAR1", "value":"hello" } ], "constraints": { "maxWallClockTime":"PT1H", "maxTaskRetryCount":0, "retentionTime":"PT1H" }, "killJobOnCompletion":false, "runElevated":true, "runExclusive":true }, "poolInfo": { "autoPoolSpecification": { "autoPoolIdPrefix":"mypool", "poolLifetimeOption":"job", "pool": { "vmSize":"STANDARD_D1", "virtualMachineConfiguration": { "imageReference": { "publisher":"Canonical", "offer":"UbuntuServer", "sku":"14.04.4-LTS", "version":"latest" }, "nodeAgentSKUId":"batch.node.ubuntu 14.04" }, "resizeTimeout":"PT15M", "targetDedicated":1, "maxTasksPerNode":1, "taskSchedulingPolicy": { "nodeFillType":"Spread" }, "enableAutoScale":false, "enableInterNodeCommunication":false, "startTask": { "commandLine":"/bin/bash -c 'export LC_ALL=en_US.UTF-8; ./starttask.sh'", "resourceFiles": [ { "blobSource":"yourbloburi&sas", "filePath":"starttask.sh" } ], "environmentSettings": [ { "name":"VAR2", "value":"Chao" } ], "runElevated":true, "waitForSuccess":true }, "metadata": [ { "name":"myproperty", "value":"myvalue" } ] } } } } }
そろそろ人類はJSONに変わるやり口を発明すべきですが、XMLよりはいいですね。
それはさておき、面白そうなパラメータたち。並列バッチやジョブリリース時のタスクなど、今回使っていないものもまだまだあります。応用版はまたの機会に。
ではスケジュールジョブをAzure BatchにCLIで送り込みます。
azure batch job-schedule create -f ./create_jobsched.json -u https://yourendpoint.location.batch.azure.com -a yourbatchaccount -k yourbatchaccountkey
以上です。あとはAzureにお任せです。4時間に1回、アメリカ国歌の単語を数える刺身タンポポなジョブですが、コツコツいきましょう。
Azure Automationとの使い分け
Azure Automationを使っても、ジョブの定期実行はできます。大きな違いは、PowerShellの要否と並列実行フレームワークの有無です。Azure AutomationはPowerShell前提ですが、Azure BatchはPowerShellに馴染みのない人でも使うことができます。また、今回は触れませんでしたが、Azure Batchは並列バッチ、オートスケールなど、バッチ処理に特化した機能を提供していることが特長です。うまく使い分けましょう。