こんにちは、サイオステクノロジー技術部 武井です。今回は、Azure Container InstancesとAzure Automationを使って、超格安なバッチ実行基盤を構築します。
バッチを実行するためには?
バッチを実行するためには、もちろんバッチを実行する基盤が必要です。代表的なものは、オンプレミスに設置する物理サーバーであったり、パブリッククラウド上に作成する仮想マシンであったりします。でも、バッチを実行する基盤ってバッチを実行するときだけ必要なのであって、それ以外は不要ですよね。パブリッククラウド上の仮想マシンの場合、多くは時間による従量課金なので、無駄が発生してしまうことがあります。夜中に一回だけ動かすバッチなのに、ずっと仮想マシン動かしてるとかってかなりムダですよね。
そこで、今回ご紹介するのは、バッチを実行するときにだけ課金される仕組みの、オンデマンドなバッチ基盤です。これをAzure Container InstancesとAzure Automationで作ります。
Azure Container Instancesって?
Azureが提供するサーバーレスコンテナプラットフォームです。普通コンテナを使う場合は、Dockerを自分のPCなり、どこかのサーバーなりにインストールして、そこでイメージをpullなりbuildなりすると思います。
でも、そのサーバーさえ用意するのも手間ですし、サーバーを保守管理する手間も増えます。そこで、Azureにはコンテナをサーバーレスで動作できる環境があります。それがAzure Container Instancesです。AWSやGCPにも同様のものがあります。
コンテナを稼働させる実行基盤として、AzureにはWeb App for ContainersやAzure Kubernetes Serviceがあります。ただ、そちらは稼働させるまでに結構時間かかりますよね。Azure Container Instancesは、先の2つのような高機能はありません。Blue Green Deployもできませんし、高度なスケーリングもできません。単一もしくは複数のコンテナをサクッと動かすだけです。でもその分、AzureにはWeb App for ContainersやAzure Kubernetes Serviceに比べて、カジュアルな感じでコンテナを実行できます。とにかくコンテナをささっと動かしたいというときに便利です。
コンテナについて詳細をお知りになりたい方は以下の記事をご覧ください( ー`дー´)キリッ
Azure Automationって?
Azure AutomationではAzure上でPowerShellなどを定期実行するサービスです。Runbookと呼ばれるテンプレートに実行する内容を記述してジョブとして登録することで、定期実行を実現します。
システム構成
今回のバッチ実行基盤のシステム構成は以下の通りとなります。まずバッチ(今回はecho hogeする簡単なもの)を実行するDockerイメージを作成してAzure Container RegistryにPushします。そのDockerイメージをAzure Container InstancesからPullしてバッチのDockerコンテナを作成します。最後にAzure AutomationのRunbookに、Azure Container Instances上のDockerコンテナを起動するPowerShellを書いて、スケジュール実行するようにします。
なにがうれしいの?
このシステムのメリットは、なんと言っても自由な構成のバッチがフルマネージドな基盤で格安に実行できるという点です。
先程も申し上げましたように仮想マシンやオンプレミス上のマシン上にバッチの実行基盤を立ち上げてしまうと、そのバッチが動いていない時間はムダですよね。
そして、AzureにはAzure Functionsというサーバーレスなアプリケーションを実行する基盤があり、こちらもタイマートリガーを使うことで定期実行させることができます。Azure Functionsの詳細は以下の記事をご覧ください。
では、Azure FunctionsとAzure Container Instancesを用いたバッチ実行基盤はどのように違うのでしょうか?以下は、その2つの違いを表したイメージ図になります。
Azure Functionsは、OSやRuntime、Application Frameworkの部分などはAzure側に隠蔽されていて、上記のMethod(関数)の部分のみを実装するイメージです。なので、お手軽なのですが、自由度が効きません。自分の好きなフレームワーク使ったり、好きなライブラリを導入することはできないことがあります。
対して、Azure Container Instancesは、Dockerコンテナ作ったり、レジストリにPushしたりと色々手間がかかりますが、OSから上のレイヤーをいじることができるので、自由度が高いです。Java使ってもPHP使っても自由ですし、もちろん大好きなフレームワークやライブラリだって導入することができます。しかも、Azure Container Instancesは、プログラムを実行した時間だけ課金されるシステムです。
Azure Container Instancesを使うと、自由度が高く、かつフルマネージドで格安なバッチ実行基盤を実現できるのです。仮想マシンの持つ自由度の高さと、Azure Functionsの持つフルマネージド、低価格という特徴を併せ持つ夢のような実行基盤なのです。
やってみよう!!
では、早速やってみましょう
バッチを実行するDockerイメージの作成
バッチを実行するDockerイメージを作成します。
FROM centos:centos7 CMD ["echo","hoge"]
ビルドします。
$ docker build -t batch .
DockerイメージのAzure Container RegistryへのPush
まずはAzure Container Registryを作成します。Azure Container RegistryはクローズドなDockerレポジトリを提供してくれるマネージドサービスです。
Azureポータルにアクセスして、「リソースの作成」をクリックします。
「container」と入力すると、「Container Registry」が表示されますので、それをクリックします。
「作成」をクリックします。
「サブスクリプション」「リソースグループ」は環境に合わせて適切なものを入力して下さい。「レジストリ名」はレジストリを一意に識別する任意の名称を入力します。後ほどこの値は、レジストリのホスト名の一部になりますので、よく考えて変な名前をつけないようにしましょう。詳細は後ほど説明します。SKUはとりあえず「Standard」にして下さい。最後に「確認および作成」をクリックします。
内容に問題ないことを確認して、「作成」をクリックして下さい。
Azure Container Registryのリソースの作成が完了したら、左部メニューの「アクセスキー」をクリックして、「管理者ユーザー」を「有効」にして下さい。すると「ユーザー名」「パスワード(2つあるうちのいずれか)」が表示されますのでメモして下さい。そして、「ログインサーバー」も合わせてメモして下さい。ちなみにこのユーザーはテスト用に利用する管理用ユーザーです。本番用途では別途サービスプリンシパルを作成して、適切な権限(Azure Container Registryへの読み取り権限のみ)を割り当てて下さい。
タグ付けをします。noriacr.azurecr.ioはAzure Container Registryを作成したときにメモしたログインサーバーを指定します。その後は、イメージ名:バージョンの形式で記述します。必ずこの形式で記述して下さい。
$ docker tag batch ntakeibatch.azurecr.io/batch:1.0
ではAzure Container RegistryにDockerイメージをpushしましょう。その前にAzure Container Registryにログインしましょう。
$ docker login -u ntakeibatch -p XXXXXX ntakeibatch.azurecr.io
Azure Container RegistryにDockerイメージをpushしましょう。
$ docker push ntakeibatch.azurecr.io/batch:1.0
Azure Container Instancesでバッチのコンテナを作成
Azure Container Instancesで、先程PushしたDockerイメージをもとに、バッチが稼働するコンテナを作成します。みんな大好きAzure Cloud Shellを使います。Azureポータル画面上部にあるアイコン(下図赤枠)をクリックします。
コンテナを作成するaz container createコマンドを実行します。書式は以下のとおりです。
$ az container create --resource-group [コンテナを作成するリソースグループ名] \ --name [コンテナの名前] \ --image [Dockerレジストリ内にあるDockerイメージ名] \ --registry-login-server [Dockerリポジトリのホスト名] \ --registry-username [Dockerリポジトリにログインするためのユーザー名] \ --registry-password [Dockerリポジトリにログインするためのパスワード] \ --restart-policy [コンテナ内のプロセスが落ちたときの動作 {Always, Never, OnFailure}]
今回の例では以下のようになります。成功すると「{- Finished ..」と表示され、それより下に作成したコンテナの詳細がJSON形式で表示されます。
$ az container create --resource-group ntakei_batch \ --name mycontainer \ --image ntakeibatch.azurecr.io/batch:1.0 \ --registry-login-server ntakeibatch.azurecr.io \ --registry-username ntakeibatch \ --registry-password XXXXXX \ --restart-policy Never
Azure Automationによるジョブの実行
Azureポータルの画面上部の検索テキストボックスに「Automation」と入力しますと、「Automationアカウント」が表示されますので、それをクリックします。
「名前」にはAutomationアカウントを一意に識別する名称、サブスクリプション・リソースグループ・場所は環境に合わせて適宜入力、「Azure実行アカウントの作成」は「はい」を選択して、「作成」をクリックして下さい。
Automationアカウント一覧から、先程作成したものをクリックします。
「Runbook」をクリックします。
「Runbookの作成」をクリックします。
「名前」にRunbookを一意に識別する任意の名称を入力、「Runbookの種類」にて「PowerShell」を選択して、「作成」をクリックします。
以下のコードを入力します。
# 以前のログイン情報をこのRunbookに反映させないようにする。 Disable-AzContextAutosave –Scope Process # デフォルトで作成される「AzureRunAsConnection」という接続の情報を取得する。 # この接続情報は「共同作成者」という強力な権限を持っているサービスプリンシパルであるため # 本番では適宜権限を絞ったサービスプリンシパルを作成して利用すること。 $connection = Get-AutomationConnection -Name AzureRunAsConnection # 最大10回リトライしてAzureにログインする。 $logonAttempt = 0 while(!($connectionResult) -And ($logonAttempt -le 10)) { $LogonAttempt++ # Logging in to Azure... $connectionResult = Connect-AzAccount ` -ServicePrincipal ` -Tenant $connection.TenantID ` -ApplicationId $connection.ApplicationID ` -CertificateThumbprint $connection.CertificateThumbprint Start-Sleep -Seconds 30 } # Invoke-AzResourceActionでコンテナを起動する。-ResourceGroupNameにはコンテナを作成したリソースグループ、 # -ResourceNameにはコンテナ名を指定する。 Invoke-AzResourceAction -ResourceGroupName ntakei_batch -ResourceName mycontainer -Action Start -ResourceType Microsoft.ContainerInstance/containerGroups -Force
「保存」をクリックします。
作成したRunbookをテストしてみます。「テストウィンドウ」をクリックします。
「開始」をクリックします。
下図のように表示されれば実行は完了です。
では、Azure Container Instances側の画面にアクセスして、コンテナが正常に起動したか確認してみましょう。Azureポータル画面上部の検索テキストボックスに「container」と入力すると、「コンテナーインスタンス」が表示されますので、それをクリックします。
先程作成したコンテナをクリックします。
メニュー内の「コンテナー」をクリックします。
「イベント」のタブにて、Runbookを実行した時刻に「Started container」と表示されていることを確認します。
「ログ」のタブをクリックして「hoge」と表示されていることを確認します。
では、再びAzure Automationに戻ります。先程作成したRunbookを選択して、「編集」をクリックします。
スケジュールを作成するためにはRunbookを公開しなければならないので、「公開」をクリックします。
実行したいRunbookの「スケジュール」をクリックします。
「スケジュール」→「新しいスケジュールを作成します」の順にクリックします。毎日夜中の1:00に起動するバッチのスケジュールを作成します。
「名前」にスケジュールを一意に識別する任意の名称を入力します。「開始時」には初回のスケジュール実行時刻を設定します。タイムゾーンはお住いの地域のもの、「繰り返し」は「定期的」、「間隔」は「1日」を設定します。有効期限の設定は特に設けないので、「いいえ」を設定し、最後に「作成」をクリックします。
これで、毎日夜中の1:00に動作する格安のバッチ実行基盤の出来上がりです!!
気になるお値段は?
例えばAzure Container Instances + Azure Automationで毎日夜中1:00に1時間実行するバッチを起動した場合を例に上げてみます。リソースは1CPU、メモリ1.5GBとします。リージョンは東日本とします。
Azure Container Instances(CPU使用料) |
170円/月 (1vCPU ✕ ¥0.0015743/vCPU 秒 ✕ 3600秒 ✕ 30日 ) |
Azure Container Instances(メモリ使用料) | 65円/月 (3.5GB ✕ ¥0.0001721/GB ✕ 3600秒 ✕ 30日 ) |
Azure Automation |
291円/月 ((60分 ✕ 30日 – 500分) ✕ ¥0.224/分 ) |
合計 | 526円/月 |
なんとたったの526円です!!同程度の仮想マシンを使った場合の金額は、7,599円(DS1_v2)なので、その差は歴然ですね!!
まとめ
さぁ、あなたもAzure Container Instances + Azure Automation使って格安のバッチ実行基盤を作って、浮いたお小遣いでワイハに旅行にでもいきましょう!!No Azure Container Instances, No Life!!