ローカルコンテナをAzure Container Registoryへプッシュ ~Azure Kubernetesのチュートリアルをはじめから丁寧に①~

今回取り組むチュートリアルはこちら

 

Kubernetesとは

コンテナのスケーリングやデプロイを管理するサービスです。昨今のマイクロサービスアーキテクトの流れにおいて、いかにコンテナを楽に管理するかが重要なようです。かく言う私もまだKubernetes(以下k8s)をよく理解できていないため、触りながら学んでいければと思っています。
今回はk8sを学ぶにあたって、AzureのサービスであるAzure Kubernetes(以下AKS)を使ってみたいと思います。KubernetesそのもののとAzureサービスとしての機能の両方を学べる良い機会かなと思うので頑張ります。

Azureのコンテナサービス

その前に、AKS以外にもAzureのコンテナサービスはたくさんあります。公式サイトにユースケースがありましたので、私の所感も一緒に添えてちょっとまとめておきます。(左二つの列はそのまま公式からパクッてきました)

ユースケース サービス 個人的な所感
マネージド Kubernetes でコンテナーのデプロイとスケーリングを行う Azure Kubernetes Service 大規模なコンテナアーキテクトをKubernetesで管理したいとき。
マネージド Red Hat OpenShift でコンテナーのデプロイとスケーリングを行う Azure Red Hat OpenShift (・・・触ったことがありません)
サーバーレス コンテナーを使用してモダンなアプリとマイクロサービスの構築とデプロイを行う Azure Container Apps AKSとContainer Instanceの中間なケースで使いたいとき。つまり、コンテナ単体では足りないけど、AKS使うほどではないというケース。
実は、このサービスがこれから熱いんじゃないかと密かに注目しています。
エンドツーエンドの開発環境でイベントドリブン型のサーバーレス コードを実行する Azure Functions 従量課金プランでは使えませんが、Appsプランで使用可能になります。
イベント駆動型で、一時的かつ短時間(少なくとも1時間以内には終わる)で終わる処理をさせたいとき。
コンテナー化された Web アプリを Windows および Linux で実行する Web App for Containers コンテナの使用用途の中でも特にWebアプリとして使用したいとき。
AzureにおけるWeb Appsと同じ枠組みで使いたいとき。
ハイパーバイザーの分離を使用してコンテナーを起動する Azure Container Instances ほぼ単体で使いたい時。コンテナグループといって複数のコンテナをグループ化してデプロイも出来ますが、細かな管理やスケーリングは無理です。
常時稼働していてスケーラブルな分散型アプリをデプロイおよび運用する Azure Service Fabric (・・・よくわかりません)
コンテナー イメージと成果物の構築、保存、保護、レプリケートを行う Azure Container Registry Docker RegistoryのAzure版です。Docker imageのレポジトリサービスであるため、これを使ってコンテナを実行する訳では無いです。
Docker hubじゃなくてこっちをあえて使う理由はよく分かりませんが、やはり他のAzure サービスとの連携がしやすいのでしょう。

 

といってもやはりAKSの使い勝手は実際に触ってみないと分からないという事で、チュートリアルを実行しながら、時折アレンジを加えて学んでいきましょう。

AKS用コンテナの準備

githubからコードをプルしてローカルPCのDcoker Composeで動かします。構成は以下の通りで、のちほどDocker Composeファイルで詳細に確認します。

まずはコードをクローンします

git clone https://github.com/Azure-Samples/aks-store-demo.git
cd aks-store-demo
ls

 

色々とファイルが入っているようですが、docker-compose.ymlを見ることで簡単にですがひも解いていきます。

以下のファイルを読むにあたっていくつか事前知識。rabbitmqとはオープンソースのメッセージキューミドルウェアです。ここでの使い方のイメージとしては、フロントからのオーダーをキュー形式で保持して順番にためていく感じです。

version: "3.7"
services:
 rabbitmq: #rabbitmqサーバー
  image: rabbitmq:3.11.17-management-alpine #プルするコンテナイメージバージョン.公開されているものをプルします。
  container_name: 'rabbitmq'
  restart: always
  environment: #環境変数
   - "RABBITMQ_DEFAULT_USER=username" 
   - "RABBITMQ_DEFAULT_PASS=password"
  ports: #リッスンするポート
   - 15672:15672
   - 5672:5672
  healthcheck: #死活監視コマンド
   test: ["CMD", "rabbitmqctl", "status"]
   interval: 30s
   timeout: 10s
   retries: 5
  volumes: #ホストボリューム(/rabbitmq_enabled_plugins)をコンテナボリューム(/etc/rabbitmq/enabled_plugins)にマウント
   - ./rabbitmq_enabled_plugins:/etc/rabbitmq/enabled_plugins
  networks:
   - backend_services
 orderservice:#オーダーサーバー
  build: src/order-service #Dockerイメージはsrc/order-service直下のdockerファイルをビルドして作ります
  container_name: 'orderservice'
  restart: always
  ports: #フロントサーバーからのオーダーをリッスンするポート
   - 3000:3000
  healthcheck:#死活監視コマンド
   test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://orderservice:3000/health"]
   interval: 30s
   timeout: 10s
   retries: 5
  environment: #環境変数 オーダーサーバーとしてrabbitqmへメッセージ送信するための接続情報を定義します
   - ORDER_QUEUE_HOSTNAME=rabbitmq
   - ORDER_QUEUE_PORT=5672
   - ORDER_QUEUE_USERNAME=username
   - ORDER_QUEUE_PASSWORD=password
   - ORDER_QUEUE_NAME=orders
   - ORDER_QUEUE_RECONNECT_LIMIT=3
  networks:後述のbridgeネットワークとして設定
   - backend_services
  depends_on:
   rabbitmq:
   condition: service_healthy
 productservice:#プロダクトサーバー
  build: src/product-service
  container_name: 'productservice'
  restart: always
  ports:
   - 3002:3002
  healthcheck:
   test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://productservice:3002/health"]
   interval: 30s
   timeout: 10s
   retries: 5
  networks:#後述のbridgeネットワークとして設定
   - backend_services
 storefront:#フロントサーバー
  build: src/store-front #src/store-front直下のDockerファイルをビルドしてイメージを作成
  container_name: 'storefront'
  restart: always
  ports:#8080ポートでリッスン
   - 8080:8080
  healthcheck:#死活監視
   test: ["CMD", "wget", "-O", "/dev/null", "-q", "http://storefront:80/health"]
   interval: 30s
   timeout: 10s
   retries: 5
  environment:#プロダクト、オーダーサーバーへAPIリクエストを送るためのURLを環境変数として定義
   - VUE_APP_PRODUCT_SERVICE_URL=http://productservice:3002/
   - VUE_APP_ORDER_SERVICE_URL=http://orderservice:3000/
  networks:後述のbridgeネットワークとして設定
   - backend_services
  depends_on:
   - productservice
   - orderservice
networks: #bridgeネットワーク(詳しく書かれています。ぜひ。https://qiita.com/koizumi_naoto/items/17533c425cf33ff0235d)
 backend_services:
 driver: bridge

ymlファイルが読み解けたところで実際にCompose(ビルドと立ち上げ)します。

docker compose -f docker-compose-quickstart.yml up -d
docker images
docker ps

ウェブブラウザでlocalhost:8080にアクセスすると以下の画面が見れます。カートにいれたりオーダーしたりといった事がバックエンドサーバーで処理出来ているという事ですね。

 

Azure Container Registryにイメージをプッシュする

Azure Conatiner Registry(以下ACR)はAzureでコンテナイメージを管理するレジストリです。チュートリアルではコマンドで行っていましたがせっかくなのでポータル画面から作成しましょう。コマンド打っててもイメージつかないのでね。(ただポータルよりも出来る事が増えるのでcliでやるのがベストなのは事実)

まずはリソースの作成。

レジストリ名はイメージをプッシュしたりプルしたりするためのURLで一意である必要があります。プランはチュートリアルをやる程度ならBasicで十分で、ひと月およそ800円で10GBまで保存できます。ネットワークやその他項目はBasicでは選択不可なのでスキップして作成します。

では続いて先ほどローカルで作成したイメージをこのレジストリにプッシュします。ただしrabibtqmイメージはプッシュしません。なぜならこれはDocker Hubの方で公開されているため、同じものを保存する意味がないからです。

早速WSLを開いてプッシュしていきますが、今回はAzure CLIコマンドではなくDockerコマンドで操作してみようと思います。

まず、作成したACRに対してdocker loginをする必要があります。先ほど作ったACRのリソース画面から管理者ユーザーとパスワードを取得します。アクセスキーのタブから管理者ユーザーのチェックをすると自動生成してくれます。

メモったら、WSLの画面から

docker login レジストリ名.azurecr.io

 

と打ち、ユーザー名とパスワードを入力してlogin succeedと表示されればOKです。

次に、イメージをプッシュするのですが、docker imagesコマンドで現在のイメージを確認すると

となっているはずです。tag(バージョン)がlatestとなっていますがあまり推奨されていないため、以下のようにタグを付けます。また、レジストリにプッシュするためには、イメージ名に作成したレジストリ名を付ける必要があるので以下のコマンドで書き換えます

#ハッシュ値はイメージIDを指す
docker tag 85d5e33811f7 レジストリ名.azurecr.io/aks-store-demo-store-front:1.0
docker tag 77d9ba3244be レジストリ名.azurecr.io/aks-store-demo-product-service:1.0
docker tag dcd91ba363fe レジストリ名.azurecr.io/aks-store-demo-order-service:1.0

#以下はlatestタグがついたイメージを削除
docker rmi aks-store-demo-store-front:latest
docker rmi aks-store-demo-product-service:latest
docker rmi aks-store-demo-order-service:latest

 

再びdocker imagesで見ると

 

となってタグが無事付けれましたね。正しい使い方は別として、私はイメージを書き換えるたびにこのタグをバージョンアップしていくようにしています。そうすると古いバージョンもプル出来ますし、消したい時にもこちらの把握しているタグ番号で削除できるので管理しやすいです。

いよいよイメージをプッシュします。といってもここまで順調にきていれば

docker push tutorial2024.azurecr.io/aks-store-demo-store-front:1.0
docker push tutorial2024.azurecr.io/aks-store-demo-product-service:1.0
docker push tutorial2024.azurecr.io/aks-store-demo-order-service:1.0

 

をとだけ入力すればうまくいくはずです。実際にACRのリポジトリタブを見てみると

aks-store-demo-oeder-sericeをクリックして詳細を見ると

となっており、無事にイメージが格納されていることが分かりますね。

 

以上、長くなってきたので今日はこの辺で終わります。次はAKSをデプロイしましょうー!