LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

【Azure】ACR(コンテナレジストリ)にコンテナイメージをプッシュして、ACI(コンテナインスタンス)で実行してみる

Last updated at Posted at 2023-12-09

概要

ACR(コンテナレジストリ)にコンテナイメージをプッシュして、ACI(コンテナインスタンス)で実行してみます。

acr_aci_drawio.png

Azure Container Registry(ACR)とは

Microsoft Azureが提供するコンテナイメージを安全かつ効率的に管理&保管できるレジストリサービスです。

そもそもコンテナのイメージとは

コンテナのイメージは、アプリケーションを実行するのにアプリケーションのコード、ランタイム、ライブラリ、設定ファイルなどがパッケージ化されたものです。ACIなどのコンテナ実行サービスは、このイメージを元にコンテナを実行します。実行環境を含めてパッケージされているため、プラットフォームや環境が異なる場合でも同じように動作するので大変便利です。

ACRの料金

Container Registry の価格

2023年12月現在、Basicプランで1日約25円程度掛かります。

acr_price.png

Azure Container Instances(ACI)とは

Azure Container Instances(ACI)は、Azureの環境でコンテナを実行するためのサービスです。ACIを利用すれば、物理サーバを管理することなくクラウド上でコンテナを作成・デプロイ・実行&停止することができます。これらの操作は、Azure PortalやAzure CLIから簡単に実施可能です。

ACIは、ACRなどのコンテナレジストリサービスからイメージをプルしてコンテナを実行します。

ACIでは、ACR以外のコンテナイメージのレジストリサービス(DockerHub, Amazon ECRなど)も使用することができます。しかし、同じAzureサービスのACRの相性が良いため、特別な理由がない限りACRを使うのが一般的です。

料金

ACIの料金は、使用時間(秒単位)とCPUコア数やメモリ量によって決まります。

CPUコア数やメモリ量を増やせば増やすほど、秒単価も高くなります。

Container Instances の価格

ハンズオン

ACRとACIの概要説明が終わりましたので、ここからは実際にコンテナを実行してみます。

次の手順で進めて行きます。

  • コンテナで実行するサンプルアプリケーションを準備する
  • ACRを作成する
  • ACRへイメージをプッシュする
  • ACIがACRからイメージをプルするロールを準備する
  • ACIでコンテナを実行する

サンプルアプリケーションの準備

Node.jsで"Hello, World!"を表示するだけの簡単なアプリケーションです。

app.js
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
  res.end('Hello, World!\n');
});

const port = 8080;
server.listen(port, () => {
  console.log(`Server running at ${port} port/`);
});
# Node.jsのLTSバージョンを使用
FROM node:lts

# アプリケーションディレクトリを作成
WORKDIR /usr/src/app

# アプリケーションの依存関係をインストール
COPY package*.json ./
RUN npm install

# アプリケーションのソースをバンドル
COPY . .

# ポート8080で実行
EXPOSE 8080
CMD [ "node", "app.js" ]

まずはローカルPCで挙動を確認してみます。

$ npm init

$ npm install http
# test-node-appという名前を付けてビルドします
$ docker build -t test-node-app .

# イメージが作成されたことを確認します
$ docker images
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
test-node-app   latest    **********   2 minutes ago   1.1GB

# コンテナを起動します
$ docker run -p 8080:8080 -d test-node-app

# コンテナの起動を確認します
$ docker ps -a
CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS         PORTS                    NAMES
********   test-node-app   "docker-entrypoint.s…"   5 minutes ago   Up 5 minutes   0.0.0.0:8080->8080/tcp   upbeat_leavitt

ブラウザでhttp://localhost:8080/を打ち込むと「Hello World!」が表示されるのを確認できました。

local_hello_world.png

ACRリソースを作成する

まず、コンテナイメージをプッシュする先であるレジストリを作成する必要がありますので、ACRのリソースを作って行きます。

Azure portalからACRリソースを作成します。

まず、コンテナレジストリのページに遷移します。portalで「レジストリ」と検索すると出てきます。

acr_page.png

作成ボタンを押し、以下の内容を入力します。

基本
リソースグループ rg-acr-dev(新規作成/任意の名前)
レジストリ名 acrdevys(任意の名前) 英数字のみの5~50文字の制限あり
場所 Japan East
料金プラン Basic 1番安いプランを選択
ネットワーク
接続の構成 パブリックアクセス(全てのネットワーク) Basicプランではパブリックしか選択できません

プライベートはPremiumプランでのみ選択できます。

「確認および作成」タブまで進み、作成ボタンを押します。

acr_created.png

新しいACRが作成されました。

ACRへコンテナイメージをプッシュする

ACRへのコンテナイメージプッシュは、Azure CLIを使って行います。

Azureにログインする

まず、Azure CLIを使ってAzureにログインします。

$ az login
A web browser has been opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. Please continue the login in the web browser. If no web browser is available or if the web browser fails to open, use device code flow with `az login --use-device-code`.

ブラウザが立ち上がるので認証を済ませます。

az_login_auth_page.png

ログインしたユーザー情報が表示されたらログイン完了です。

[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "***",
    "id": "***",
    "isDefault": true,
    "managedByTenants": [],
    "name": "Azure サブスクリプション 1",
    "state": "Enabled",
    "tenantId": "***",
    "user": {
      "name": "***",
      "type": "user"
    }
  }
]

ロールを確認する

この後実施する作業は、以下のロールが割り当てられたユーザーで実施する必要があります。

  • AcrPush ロール: 名前の通り、ACRへコンテナイメージをプッシュする権限です

ここでは、権限の強い所有者ロールを割り当てられたユーザーを用いて以下の作業を実施します。

※ 実環境では、所有者のような強権限のロールを持つユーザーで作業することは推奨されません。必要なロールのみを付与したユーザーで作業することを検討してください(最小権限の原則)。

イメージをACRにプッシュする

先ほど作成したコンテナレジストリ(ACR)にイメージをプッシュします。

これは、az acr buildコマンドを使って行います。

az acr buildコマンドは、ローカルコードをビルドして、ビルドの成果物(コンテナイメージ)をACRにプッシュするコマンドです。

# Dockerfileを含む今回のプロジェクトのディレクトリに移動します
$ cd node

$ az acr build --image node-app:v1.0.0 --registry acrdevys .

--imageオプションで、ビルドして生成されるイメージの名前やタグを指定します。イメージの名前:タグの形式で指定できます。

--registryオプションでは、先ほど作成したACRのリソース名を指定します。

$ az acr build --image node-app:v1.0.0 --registry acrdevys .
....
2023/12/02 02:21:12 Successfully pushed image: acrdevys.azurecr.io/node-app:v1.0.0
2023/12/02 02:21:12 Step ID: build marked as successful (elapsed time in seconds: 31.661096)
2023/12/02 02:21:12 Populating digests for step ID: build...
2023/12/02 02:21:13 Successfully populated digests for step ID: build
2023/12/02 02:21:13 Step ID: push marked as successful (elapsed time in seconds: 39.552949)
2023/12/02 02:21:13 The following dependencies were found:
2023/12/02 02:21:13 
- image:
    registry: acrdevys.azurecr.io
    repository: node-app
    tag: v1.0.0
    digest: sha256:****
  runtime-dependency:
    registry: registry.hub.docker.com
    repository: library/node
    tag: lts
    digest: sha256::****
  git: {}
Run ID: ce1 was successful after 1m15s

このコマンドを実行すると、以下のことが行われます。

  • ローカルのソースコード(Dockerfile含む)がACRにアップロードされる
  • アップロードされたローカルコードがビルドされ、コンテナイメージが生成される
  • 生成されたコンテナイメージを--registryで指定したレジストリにプッシュする

コンテナレジストリ > サービス > リポジトリを確認すると、今ビルド&プッシュをしたイメージ(node-app:v1.0.0)が確認できます。

arc_build_success.png

ACIがACRからコンテナイメージをプルする権限を準備する

前提

この後、ACIを使ってコンテナを実行していきます。

コンテナ実行時、ACIはACRのイメージをプル(ダウンロード)するため、ACIにはイメージをプルする権限が必要です。

ここでは、この認証をマネージドIDを使用して行います。

aci_acr_mangedid.png

マネージドIDを作成する

Azure Portalで「マネージドID」のページに行き、作成ボタンを押します。

基本
リソースグループ rg-acr-dev
リージョン Japan East
名前 aci-image-pull-id

上記の条件で、マネージドIDを作成します。

userassignmanegedid_created.png

マネージドIDが作成されました。

マネージドIDにACRのイメージをプルする権限を付与する

コンテナレジストリのページに行き、アクセス制御(IAM)を選択します。

ロールの割り当ての追加を押します。

acr_add_iam.png

AcrPullを選択し、「次へ」を押します。

acr_add_role.png

アクセスの割り当て先で「マネージドID」を選択し、「メンバーを選択する」を押します。先ほど作成したマネージドID(aci-image-pull-id)を選択します。

acr_add_managedid.png

「レビューと割り当て」を押します。

アクセス制御 (IAM)を確認すると、今追加した「ユーザー割り当てマネージド ID」が反映されていることが分かります。

managedid_added.png

コンテナを実行する

Azure CLIから実行する

Azure CLIのaz container createコマンドでACIを作成し、コンテナを実行します。

$ az container create \
  --name node-app-container \
  --resource-group rg-acr-dev \
  --image acrdevys.azurecr.io/node-app:v1.0.0 \
  --assign-identity [ユーザー割り当てマネージドIDのリソースID] \
  # ACRへのアクセスに使用されるマネージドIDを指定
  --acr-identity [ユーザー割り当てマネージドIDのリソースID] \
  # コンテナー再起動ポリシーを指定
  --restart-policy Never \
  --ip-address Public \
  --ports 80

ユーザー割り当てマネージドIDのリソースIDは、以下のコマンドやPortal(管理 > プロパティ)で確認できます。

$ az identity show --name <マネージドIDの名前> --resource-group <リソースグループ名> --query id

--restart-policyは、コンテナー再起動ポリシーを指定するものです。

しばらく時間が掛かりますが、コンテナ作成が終わると以下のようなJSONが返却されます。

{
  "confidentialComputeProperties": null,
  "containers": [
    {
      "command": null,
      "environmentVariables": [],
      "image": "acrdevys.azurecr.io/node-app:v1.0.0",
      "instanceView": {
        ....以下略

Azure PortalのACIのページに行くと、今作成したnode-app-containerが作成されていることを確認できます。

aci_list_created.png

ステータスは実行中になっています。

node-app-container_created.png

アプリ側で出力したログも確認できました。

log.png

続いて、コンテナにブラウザからアクセスしてみます。

http://{コンテナのIPアドレス}:80をブラウザに打ち込みます。コンテナのIPアドレスは、Portalから確認できます。また、コンテナ作成時に返却されたJSONにもIPアドレスが記載されています。

aci_ipaddress.png

アクセスできませんでした。

node-app-container_error.png

ACIにはDockerで使用されるようなポートマッピング機能がありません。必ず、コンテナ内のポートと外部に公開するポートを一致させる必要があります

今回のケースでは、コンテナ内のポートを8080に設定しています。そのため、コンテナ作成時に指定するポートも8080である必要がありました。指定ポートを8080に変更の上、再度コンテナを実行します。

先ほど作成したコンテナを削除します。コンテナの削除は、Portalから実施します。

aci_delete.png

az container createでACIを作成し、コンテナを実行します。

$ az container create \
  --name node-app-container \
  --resource-group rg-acr-dev \
  --image acrdevys.azurecr.io/node-app:v1.0.0 \
  --assign-identity [ユーザー割り当てマネージドIDのリソースID] \
  --acr-identity [ユーザー割り当てマネージドIDのリソースID] \
  --restart-policy Never \
  --ip-address Public \
  --ports 8080 # コンテナ内のポートと一致させる

http://{コンテナのIPアドレス}:8080にアクセスします。

今度は、期待通りHello, World!が表示されました。

hello.png

動作を確認できたので、コンテナインスタンスは削除しておきます。

アプリを修正して再デプロイする

おさらいの意味も込めて、アプリケーションの内容を変更して、再度デプロイし、コンテナを実行してみます。

アプリケーションに変更を加える

アプリケーションコードを修正し、表示する文字列を変えます。

app.js
const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
  // 表示する文字列を変更する
  res.end('コンテナインスタンス実行中です。\n');
});

ACRにコンテナイメージをプッシュする

アプリケーションに変更を加えたので、この内容でビルドし、コンテナイメージをACRにプッシュします。

バージョンもv1.0.0 から v1.0.1に変更しておきます。

# Dockerfileのあるディレクトリに移動してから実施します
$ cd node
#  バージョンを v1.0.0 から v1.0.1 に上げます
$ az acr build --image node-app:v1.0.1 --registry acrdevys .

コンテナイメージを確認する

PortalのACRのページに行きます。

今追加したv1.0.1が追加されていることを確認できます。

acr_image_versionup.png

なお、以下のコマンドでもイメージのタグ一覧を確認できます。

$ az acr repository show-tags --name acrdevys --repository node-app --output table

Result
--------
v1.0.0
v1.0.1

コンテナを実行する

az container createでACIを作成し、コンテナを実行します。

$ az container create \
  --name node-app-container \
  --resource-group rg-acr-dev \
  # 今追加した新しいバージョンを指定します
  --image acrdevys.azurecr.io/node-app:v1.0.1 \
  --assign-identity [ユーザー割り当てマネージドIDのリソースID] \
  --acr-identity [ユーザー割り当てマネージドIDのリソースID] \
  --restart-policy Never \
  --ip-address Public \
  --ports 8080

http://{コンテナのIPアドレス}:8080にアクセスします。

すると、今加えた変更が反映されたのが分かります。

aci_success.png

今回の作業で掛かった料金

ACR

今回はBasicプランを選択したので、1日24.64円掛かりました。

acr_cost.png

注意点

  • 作成したままにしておくと、月額750円ほど掛かります。終わったら必ず、コンテナレジストリ自体を削除するのを忘れないでください。
  • 今回選択したプランはBasicです。Basicよりも上のプランを選択すればさらに追加の料金が掛かります。Container Registry の価格

ACI

今回の検証で5,6回ACIを作成しましたが、総額14.70円でした。

「勉強のために少しだけ動かしてみる」という用途であれば、許容できる金額に収まりそうです。

aci_cost.png

注意点

  • ACIは、使用時間に応じて料金が掛かります。余計な課金を防ぐため、不要なインスタンスは削除してください。
  • 今回、ACIは1 vCPU と 1.5 GBで実行しました。これより上のスペックを指定した場合、さらに料金が掛かります。

CPUやメモリは、ACI作成時に返却されるJSONデータのresourcesで確認できます。

コンテナ作成時に何も指定しない場合、デフォルト値の1 vCPU と 1.5 GBが指定されます。

  "resources": {
    "limits": null,
    "requests": {
      "cpu": 1.0,
      "gpu": null,
      "memoryInGb": 1.5
    }
  }
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up