はじめに

前回に引き続き、コンテナ化アプリケーションをAzure上で動作させる方法について説明します。今回はAzure Container Registry(ACR)の提供するコンテナイメージビルドの手法であるACRタスクと、コンテナの実行サービスであるAzure Container Instances(ACI)を使ったコンテナの実行方法について紹介します。

ACRタスクとは

ACRタスクはAzure Container Registryの機能の一つで、DockerイメージのビルドやプッシュをAzure上で行うことができます。
ACRタスクを使用することで、ローカルマシン上であったりCI/CD環境のようなビルド環境でのDockerコマンドの実行が不要になります。これにより環境依存による問題を抑えることができたり、マシンリソースの有効活用ができるようになります。
またACRタスクは複数のタスクをファイルに定義することができるため、コンテナのビルドからプッシュに至るまでの手順をコードとして管理することもできるようになります。

ACRタスクによるコンテナのビルドとプッシュ

それでは早速ACRタスクを使ってDockerイメージの作成とコンテナレジストリへのプッシュを実際に行ってみましょう。今回はOSSのWebサーバであるnginxのコンテナイメージから新たなコンテナイメージを作成していきます。最終的にはコンテナを起動し、Webブラウザでnginxデフォルトのindex.htmlが表示されることを確認していきます。
まずはnginxのコンテナイメージをベースイメージとした、新たなコンテナイメージのビルド手順をDockerfileを使って記述します。

nginxイメージをベースとしたDockerfile

FROM nginx:stable

EXPOSE 80

FROM命令にベースとなるイメージとして、nginxの安定バージョンである「nginx:stable」を指定します。また、EXPOSE命令を使って、コンテナが開放するポートを明示しています。nginxの場合は80番ポートでHTTPリクエストを受信するため、80番ポートを開放するように記述しています。

通常であれば、ここで「docker build」コマンドを実行してDockerイメージを作成し、その後「docker push」コマンドでコンテナレジストリへイメージをプッシュしていきます。ACRタスクの場合は、以下のコマンドを用いてACR上でビルドおよびプッシュを実行するようにします。

ACRタスクによるDockerイメージのビルドとプッシュの実行

$ cd <Dockerfilesのあるディレクトリ>

$ az acr build --registry zerokara --image zerokara-nginx:v1 .

「az acr build」コマンドを実行すると、Dockerfileが「--registry」で指定したACR上で実行され「--image」で指定したイメージ名およびタグ名で保存されます。 上記のコマンドの実行ログは以下のようになります。

ACRタスクによるDockerイメージのビルドとプッシュの実行結果

# DockerfileやソースコードなどのファイルのACRへのアップロード・・・①
Packing source code into tar to upload...
Sending context (568.000 Bytes) to registry: zerokara...
# ACR上でのビルドの実行・・・②
Queued a build with ID: ce1
Waiting for an agent...
・・・中略
Step 1/2 : FROM nginx:stable
・・・中略
Step 2/2 : EXPOSE 80
・・・中略
Successfully built 43f3e4104221
Successfully tagged zerokara.azurecr.io/zerokara-nginx:v1
2022/01/15 08:26:00 Successfully executed container: build
# ACR上でのプッシュの実行・・・③
2022/01/15 08:26:00 Executing step ID: push. Timeout(sec): 3600, Working directory: '', Network: ''
2022/01/15 08:26:00 Pushing image: zerokara.azurecr.io/zerokara-nginx:v1, attempt 1
The push refers to repository [zerokara.azurecr.io/zerokara-nginx]
・・・中略
2022/01/15 08:26:07 Successfully pushed image: zerokara.azurecr.io/zerokara-nginx:v1
# ACRタスク全体の実行結果の表示・・・④
2022/01/15 08:26:07 Step ID: build marked as successful (elapsed time in seconds: 9.492725)
2022/01/15 08:26:07 Populating digests for step ID: build...
2022/01/15 08:26:08 Successfully populated digests for step ID: build
2022/01/15 08:26:08 Step ID: push marked as successful (elapsed time in seconds: 7.433483)
・・・中略

Run ID: ce1 was successful after 21s

ログを確認すると、ACRタスクでどの様な処理が行われているかが分かります。まずはローカルマシン上にあるビルドに必要なファイル群をACR上に転送する処理から始まります(①)。今回の場合ですとDockerfileのみが転送対象ですが、Dockerイメージのビルド時に必要なソースコードや設定ファイルなどがある場合は、それらをまとめてACRへ転送します。ファイルの転送が完了すると、ACR上でのDockerイメージのビルドが開始されます(②)。ここで表示されるログは、ローカルマシン上で「docker build」コマンドを実行した時のものとほぼ同じ内容が出力されます。Dockerfileに記述した命令を順に実行し、その実行結果が出力されます。イメージのビルドが成功したら、次にプッシュが実行されます(③)。DockerイメージのビルドはACR上で行われますが一時的な作業領域で行われるため、ここで正規の配置場所であるレジストリ内のリポジトリへとプッシュされます。プッシュまで完了すると、ACRタスク全体の実行結果のサマリを表示します(④)。各処理の実行結果や所要時間をここで確認することができます。
実行ログの最終行に「Run ID: xxx was successful ・・・」と表示されていれば、ACRタスクは成功になります。Run IDはコマンド実行の度に変わります。

ここでAzureポータルで「コンテナーレジストリ」を選択し「zerokara」レジストリの左側にあるメニューから「リポジトリ」を選択します。「zerokara-nginx」というリポジトリと「v1」というタグでDockerイメージが登録されていることが確認できます。

  • 図1:ACR上のDockerイメージ

これでACRタスクを用いてACR上でDockerイメージのビルドとレジストリへのプッシュができることを確認することができました。

複数のタスクをACRタスクで実行する

次は別の方法でACRタスクを実行してみましょう。ビルドやプッシュなどACRタスクを実行する時の処理をより細やかに制御したい場合は、タスクの実行手順について記述した定義ファイルを用意すると便利です。定義ファイルはGit等でバージョン管理ができるので、チーム間でのACRタスクの実行方法の共有がしやすくなるといったメリットもあります。
以下はビルドとプッシュに加え、コンテナの起動テストも行う定義ファイルの例です。定義ファイルはYAMLファイルとして記述していきます。

ACRタスクの実行手順を記した定義ファイル(task.yaml)

version: v1.1.0
steps:
# Dockerイメージのビルド・・・①
- build: -t $Registry/zerokara-nginx:$ID -t $Registry/zerokara-nginx:latest .
# コンテナの起動テスト・・・②
- cmd: -t $Registry/zerokara-nginx:$ID
  id: test
  detach: true
  ports: ["80:80"]
- cmd: docker stop test
# Dockerイメージのプッシュ・・・③
- push:
  - $Registry/zerokara-nginx:$ID
  - $Registry/zerokara-nginx:latest

この内容を「task.yaml」というファイル名でDockerfileと同じフォルダに保存します。定義ファイルでは「steps」というブロック内にACRタスクで実行したい手順を順に記述していきます。まずはDockerイメージのビルド方法について、「build」というステップに記述します(①)。なおここで使用されている「$」から始まる文字列($Registryや$ID)は、Run変数と呼ばれるACRタスクで既定の変数です。「$Registry」はACRのレジストリの完全修飾子名(FQDN)を表します。「$ID」はACRタスクの実行ごとに割り振られるユニークな文字列を表します。
buildステップでは「docker build」コマンドと同様に「-t」で作成するイメージのタグを指定します。この例ではACRタスクの実行IDである「$ID」を付与したタグと、最新のイメージであることを表す際に用いられる「latest」タグの2つのタグを付与したイメージを同時に作成するようにしています。 次は「cmd」ステップです(②)。cmdステップはDockerイメージからコンテナを起動することができます。主にテストの用途としてコンテナが期待どおりに起動することを検証したい場合にcmdステップを使用します。今回の例ではcmdステップを2つ用意しています。1つ目のcmdステップでは、起動したいDockerイメージを「-t」で指定し、「id」プロパティで起動したコンテナに「test」というIDを付与しています。また「detach: true」でバックグラウンド実行するように設定したり、「ports」プロパティで公開するポートを設定しています。コンテナの起動に成功すると、2つ目のcmdステップが実行されます。2つ目のcmdステップは1つ目のcmdステップで起動したコンテナを「docker stop」コマンドで停止し、ACR上のリソースをクリーンアップするステップです。
最後は「push」ステップです(③)。このステップでACRのレジストリへDockerイメージをプッシュします。buildステップで作成した2つのイメージそれぞれをプッシュするように記述しています。

定義ファイルが作成できたら、以下のコマンドを使ってACRタスクを実行します。

定義ファイルを使ったACRタスクの実行

$ cd <Dockerfilesおよびtask.yamlのあるディレクトリ>

$ az acr run -r zerokara -f task.yaml .

定義ファイルを用いたACRタスクの実行には「az acr run」コマンドを使用します。「-f」で定義ファイル名を指定し、コマンドの最後にある「.」で定義ファイルおよびDockerファイル等のACRタスクに必要なファイルの配置されているローカルマシンの場所を相対パスで指定します。上記コマンドの実行ログに関しては、前項で実行した「az acr build」コマンドとほぼ同等の内容のため割愛しますが、cmdステップで実行したテスト用コンテナの起動に関するログとして、「Step ID: test marked as successful」等の内容が追加で出力されていることを確認することができます。
Azureポータル上では、今回のACRタスク実行によってレジストリに新しいタグが追加されたことを確認することができます。

  • 図2:ACR上にプッシュされたイメージ一覧

「latest」および「ce2」というタグが新たに追加されたことが分かります。「ce2」というタグは、定義ファイルのbuildステップで指定した「$ID」の著者環境での具体的な値となります。

ACRタスクで作成したDockerイメージの動作確認

ここまで2つの方法を使ってACRタスクを実行し、DockerイメージをACRにプッシュすることができました。ここで以下のコマンドをローカルマシン上で実行して、これまで作成したDockerイメージがローカルマシン上には存在しないことを確認します。

ローカルマシンにはまだイメージがないことを確認する

$ docker images zerokara.azurecr.io/zerokara-nginx
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

「docker images」の結果、該当するイメージはローカルマシン上に1つも存在しないことが確認できます。これでACRタスクによって、ローカルマシン上のDockerを使用せずにDockerイメージがACRにプッシュされていることが分かりました。この状態で以下のコマンドを実行し、ACRからイメージをプルしてローカルマシン上でコンテナが起動できるか確認します。

ACRタスクで作成したDockerイメージをローカルマシン上で起動する

$ az acr login --name zerokara
Login Succeeded

$ docker run -p 8080:80 zerokara.azurecr.io/zerokara-nginx:latest
Unable to find image 'zerokara.azurecr.io/zerokara-nginx:latest' locally ・・・①
latest: Pulling from zerokara-nginx ・・・②
・・・中略
Status: Downloaded newer image for zerokara.azurecr.io/zerokara-nginx:latest ・・・③
・・・中略
2022/01/16 04:02:22 [notice] 1#1: nginx/1.20.2
2022/01/16 04:02:22 [notice] 1#1: start worker processes

「az acr login」コマンドでACRのレジストリにログインした後、「docker run」コマンドでコンテナの起動を試みます。すると、ローカルマシン上に該当するDockerイメージが存在しない旨のメッセージが表示されたため(①)、レジストリからイメージをプルしようとします(②)。イメージのプル(ダウンロード)が完了すると(③)、イメージからコンテナを起動し、最終的にnginxの起動ログが表示されます。
この状態でWebブラウザから「http://localhost:8080」にアクセスしてみます。図のように、nginxデフォルトのウェルカム画面(index.html)が表示されればコンテナの起動は成功です。

  • 図3:ローカルマシン上で起動したコンテナの動作確認

これでACRタスクで作成したDockerイメージから、コンテナが起動できることを確認することができました。
なおコンテナは起動したままになっているため、停止する際はターミナルで「Ctrl + C」をタイプしてコンテナを停止します(マシンのスペック等によっては正しくコンテナを停止できない場合があります。その場合はDockerを再起動して下さい)。

Azure Container Instancesでコンテナ化アプリケーションを実行しよう

前回および今回、様々な手段でAzure Container RegistryにDockerイメージをプッシュする方法について説明してきました。しかしDockerコンテナの実行はローカルマシンにインストールしたDocker上で行ってきました。ここからは運用環境として使用可能な、Azureが提供するコンテナ実行サービス上でDockerコンテナを実行していく方法について説明していきます。
前回Azureが提供するコンテナ化アプリケーションの実行サービスをいくつか紹介しましたが、今回はその中からAzure Container Instances(ACI)を使ったDockerコンテナの実行方法について説明します。

Azure Container Instancesとは

Azure Container Instances(ACI)は、Azureのクラウドリソース上でDockerコンテナを実行することができるサービスのひとつです。ACIはPaaSに位置づけられるサービスのため、コンテナの実行に際して仮想マシン(VM)等のインフラを自身で用意する必要がなく、気軽に利用することができます。 ACIは高速にコンテナを起動することができる反面、複数のコンテナを協調して動作させるようなユースケースには不向きです。そのため単一のコンテナで実行できる比較的単純なアプリケーションであったり、バッチ処理のような自己完結型のアプリケーションを実行する用途に適しています。なお複数のコンテナを使ったアプリケーションを構築する場合は、今後紹介するAzure Kubernetes Service(AKS)等のサービスが選択肢となります。

Azure Container Instancesでコンテナを実行しよう

ここからは実際にACIを使ってコンテナを実行していく方法を説明していきます。ACIを使用する際は事前にDockerイメージを用意する必要があります。今回は、前項で作成した「zerokara-nginx」のDockerイメージを使ってコンテナを実行できるようにしていきます。

「zerokara-nginx」DockerイメージをACIから参照できるようにするために、ACRの設定を一部変更します。Azureポータルで「zerokara」のレジストリに移動し、「アクセスキー」メニューを選択して、「管理者ユーザー」を有効に設定変更します。管理者ユーザーを有効にすることで、ACIが管理者ユーザーとしてこのレジストリにログインすることができるようになります。

  • 図4:ACRで管理者ユーザーを有効にする

次にAzureポータルで「コンテナーインスタンス」を検索します。コンテナーインスタンスの一覧画面が表示されたら、画面左上の「作成」ボタンか画面下部の「コンテナーインスタンスの作成」ボタンを選択します。

  • 図5:コンテナーインスタンスの一覧画面

作成画面が表示されたら、必要項目を入力していきます。「サブスクリプション」と「リソースグループ」は任意のものを選択します。「コンテナー名」にはコンテナーインスタンスの名称を入力します。ここでは「zerokara-nginx-instance」という名称にしました。「地域」ではコンテナーインスタンスをデプロイするリージョンを選択します。「イメージのソース」はコンテナーインスタンスで実行するコンテナのもととなる、Dockerイメージのありかを指定します。今回はACRからDockerイメージを参照するため、「Azure Container Registry」を選択します。ACRの設定で管理者ユーザーを有効にしていない場合、ここでエラーが発生してしまうので注意して下さい。「レジストリ」、「イメージ」、「イメージタグ」では、ACR内のDockerイメージの具体的な配置場所について指定します。プルダウンでACR内のリソースが表示されるので、使用したいDockerイメージに合った内容を選択していきます。「サイズ」でコンテナーインスタンスが利用できるリソース(vcpu数、メモリサイズ、gpu数)の割当てを増減することができます。
ここまで入力ができたら、画面下部の「次: ネットワーク」ボタンを選択します。

  • 図6:コンテナーインスタンスの作成画面(基本)

ネットワークの設定画面では、コンテナーインスタンスの公開方法について設定していきます。今回はWebブラウザからインターネット経由で動作を確認したいので、「ネットワークの種類」は「パブリック」を選択します。「DNS名ラベル」はコンテナーインスタンスをパブリックに公開する際のDNS名の一部(サブドメイン)を指定することができます。今回は「zerokara-web」というDNS名ラベルとします。「ポート」ではコンテナーインスタンスが公開するポートを指定することができます。今回実行する「zerokara-nginx」コンテナは80番ポートでHTTPリクエストを受信するため「ポート:80」、「ポートのプロトコル:TCP」を指定しておきます。ここまで設定ができたら、「確認および作成」ボタンを選択します。

  • 図7:コンテナーインスタンスの作成画面(ネットワーク)

確認画面で設定した内容に問題がないか確認し、「作成」ボタンを選択してコンテナーインスタンスの作成を開始します。しばらく待つと作成が完了するので、コンテナーインスタンスの画面へ移動します。

  • 図8:コンテナーインスタンスのFQDNの確認

Azureポータルで作成したコンテナーインスタンスの画面に移動し、FQDNの項目にある内容をコピーします。WebブラウザでFQDNをURLとして貼り付けて、nginxのウェルカムページが表示されることを確認します。

  • 図9:コンテナーインスタンス上で起動しているコンテナの確認

図のようにウェルカムページが表示されれば、ACRからプルしたDockerイメージがACI上でコンテナとして正しく起動していることになります。このように、ACRとACIを組み合わせることで、非常に簡単にサービスを公開することができるようになることが分かりました。

なおコンテナーインスタンスは実行中は課金対象となるため、動作確認が終わったら停止または削除します。コンテナーインスタンスの停止や削除は、Azureポータルのコンテナーインスタンスの画面から行うことができます。 同様にACRについても、不要であればレジストリは削除して下さい。ACRのレジストリの削除方法については、前回の記事を参照して下さい。

まとめ

今回はAzure Container Registry(ACR)のACRタスクを使ったAzure上でのDockerイメージのビルドおよびプッシュの手法と、Azure Container Instances(ACI)を使ったコンテナの実行方法について紹介しました。ACRタスクを使用することで、開発者の環境に依存することなくACR上でDockerイメージのビルドやプッシュができること、またACIを使って非常に簡単にコンテナ化アプリケーションをAzure上で実行、公開することができることが分かりました。次回も引き続きコンテナ化アプリケーションの実行方法について、他のAzureサービスを使った事例を紹介していく予定です。

WINGSプロジェクト 秋葉龍一著/山田祥寛監修
<WINGSプロジェクトについて>テクニカル執筆プロジェクト(代表山田祥寛)。海外記事の翻訳から、主にWeb開発分野の書籍・雑誌/Web記事の執筆、講演等を幅広く手がける。一緒に執筆をできる有志を募集中