演習 - 複数コンテナー ソリューションを Kubernetes クラスターにデプロイする
プロジェクトで提供されるリリース パイプラインは、ソリューションを Docker コンテナーとしてビルドし、Azure App Service にデプロイするように設計されています。 Kubernetes クラスターへの複数のコンテナーのデプロイをサポートするには、このパイプラインを変更する必要があります。
このユニットでは、次の方法を学習します。
- main ブランチへのコミットトリガーするようにパイプラインを更新します。
- パイプライン全体で共有される変数を定義します。
- Docker イメージをビルドして発行します。
- Kubernetes マニフェストを発行します。
- Kubernetes とコンテナー レジストリ インスタンスの間で使用するイメージ プル シークレットを作成するタスクを追加します。
- 更新されたイメージを Kubernetes クラスターにデプロイします。
トリガーをサポートするようにパイプラインを更新する
Azure DevOps 組織にサインインしてから、プロジェクトに移動します。
[パイプライン] を選択し、使用するパイプラインを選択します。
[編集] を選んで azure-pipelines.yml を編集します。
Andy: これは、前の単一コンテナー ソリューション用に設けたビルド ステージでした。 正常に実行されないことがわかったので、無効にしました。
main
ブランチへのコミットでのトリガーを再び有効にすることで開始できます。ファイルの先頭にある既存の
trigger
行を次のスニペットに置き換えます。 これにより、メイン ブランチに対してコミットが行われるたびにパイプライン実行がトリガーされます。trigger: - 'main'
パイプライン全体でアクセスできる変数を定義する
Andy: 2 つのパイプライン変数を追加する必要があります。 1 つはランキング リポジトリの名前 (leaderboard) を指定するためのものです。 もう 1 つは、デプロイの間に AKS と ACR のインスタンス間で共有するために使われる、イメージ プル シークレットの名前用です。
次の強調表示されたコードを
variables
セクションに追加します。variables: buildConfiguration: 'Release' leaderboardRepository: 'leaderboard' webRepository: 'web' tag: '$(Build.BuildId)' imagePullSecret: 'secret'
Docker イメージをビルドして Azure Container Registry に発行する
Andy: Web アプリを Docker コンテナーとしてビルドするためのタスクは既にあります。これを、コンテナー レジストリに発行します。 2 つ目のタスクを使用するだけで、ランキングに対して同じ操作を行うことができます。
次の強調表示されたスニペットを使用して、2 番目の
Docker@2
タスクを追加して、ランキング コンテナーをビルドして発行します。 Web コンテナー タスクのすぐ後にこのタスクを追加します。- task: Docker@2 displayName: 'Build and push the web image to container registry' inputs: command: buildAndPush buildContext: $(Build.Repository.LocalPath) repository: $(webRepository) dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.Web/Dockerfile' containerRegistry: 'Container Registry Connection' tags: | $(tag) - task: Docker@2 displayName: 'Build and push the leaderboard image to container registry' inputs: command: buildAndPush buildContext: $(Build.Repository.LocalPath) repository: $(leaderboardRepository) dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile' containerRegistry: 'Container Registry Connection' tags: | $(tag)
ヒント
YAML ファイルでは空白文字が重要であるため、ここで追加するタスクで前のタスクと同じインデントが使われていることを確認します。
Kubernetes マニフェストを発行する
Andy: 次のステージに進むことができると思います。 何か足りないものがありますか。
Mara:あなたは、デプロイするときに Kubernetes で必要なデプロイとサービスが定義されているいくつかのマニフェスト ファイルがソース プロジェクトにあると言いました。 このステージを完了する前に、それらを発行する必要があります。
Andy: それが必要ですか。 それらはまだローカル ディスクに存在するのではありませんか。
Mara: ビルドと同じステージ内にデプロイ タスクを追加したとしたら、そうでしょう。 ただし、"デプロイ" タスクは独自のデプロイ ステージで実行されるため、新しい環境 (おそらく別のエージェント上でも) で実行されます。 このステージで生成されるもので、他のステージで必要なものは必ず発行する必要があります。
Andy: それは大事なポイントです。 簡単にできますか。 manifests フォルダーが新しいエージェントにコピーされるようにする必要があります。
Mara: それが PublishBuildArtifacts@1
タスクの役割です。 非常に一般的なので、そのための簡単な方法として publish
があります。
次のコード スニペットに示すように、後のステージのために manifests フォルダーを格納する
publish
タスクを追加します。 このタスクのインデントが前のタスクのインデントと一致していることを確認します。- task: Docker@2 displayName: 'Build and push the leaderboard image to container registry' inputs: command: buildAndPush buildContext: $(Build.Repository.LocalPath) repository: $(leaderboardRepository) dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile' containerRegistry: 'Container Registry Connection' tags: | $(tag) - publish: '$(Build.SourcesDirectory)/manifests' artifact: manifests
デプロイ ステージを置き換える
Mara: 既存のデプロイ ステージを、デプロイ ジョブを使用するものに置き換えます。 "デプロイ ジョブ" は特別な種類のジョブであり、前に作成した Azure DevOps 環境にデプロイを関連付けることができます。 これにより、デプロイ履歴を簡単に追跡できるようになり、ソリューションがより洗練されたものになるにつれて特に役立ちます。
既存のデプロイ ステージ (ビルド ステージの後にあるものすべて) を削除し、次のスニペットに置き換えます。 利用するデプロイ環境を示す強調表示された行をメモしておきます。
- stage: 'Deploy' displayName: 'Deploy the containers' dependsOn: Build jobs: - deployment: Deploy displayName: Deploy pool: vmImage: 'ubuntu-20.04' environment: 'Dev' variables: - group: Release strategy: runOnce: deploy: steps:
Mara: デプロイ ステージに追加する最初のステップでは、前に発行されたマニフェスト成果物を、
DownloadBuildArtifacts@0
を使用してダウンロードします。Andy: 当ててみましょうか。そのタスクには
download
の短縮形があるのではないですか。Mara: そのとおりです。
current
指定子を使用して、パイプラインの現在の実行からの成果物が必要であることを示すことができます。強調されている行を、デプロイ ステージの最初のステップとして追加します。
- stage: 'Deploy' displayName: 'Deploy the containers' dependsOn: Build jobs: - deployment: Deploy displayName: Deploy pool: vmImage: 'ubuntu-20.04' environment: 'spike.default' variables: - group: Release strategy: runOnce: deploy: steps: - download: current artifact: manifests
Andy: 次に、ACR と AKS インスタンスの間で共有されるイメージ プル シークレットを作成する必要があります。 使用できるタスクがあるかどうか、わかりますか。
Mara: それについて調べたのですが、ラッキーです。
KubernetesManifest@0
タスクで、必要なシークレットを作成するアクションがサポートされています。
Kubernetes マニフェスト タスク
Kubernetes マニフェスト タスクは、Kubernetes に必要なすべてのメインストリーム デプロイ操作を管理するように設計されています。 シークレットの作成からイメージのデプロイまで、複数の action
オプションがサポートされています。 この場合、createSecret
アクションが次のパラメーターと共に使用されます。
action
は、実行する機能を示します。 この場合、createSecret
によって共有シークレットが作成されます。connectionType
では、使用するサービス接続の種類を指定します。 省略可能: azureResourceManager または kubernetesServiceConnection。secretName
では、作成するシークレットの名前を指定します。dockerRegistryEndpoint
では、Azure Container Registry のサービス接続の名前を指定します。azureSubscriptionConnection
では、ARM のサービス接続の名前を指定します。azureResourceGroup
では、リソース グループの名前を指定します。kubernetesCluster
では、AKS クラスターの名前を指定します。namespace
では、このアクションを適用する Kubernetes 名前空間を指定します。
次のスニペットをパイプラインの末尾に追加します。 リソース グループ名とクラスター名の両方が、前に作成したものの名前と一致していることを確認します。 このタスクのインデントが、"ダウンロード" タスクのインデントと一致していることを確認します。
- task: KubernetesManifest@1 displayName: Create imagePullSecret inputs: action: createSecret connectionType: azureResourceManager secretName: $(imagePullSecret) dockerRegistryEndpoint: 'Container Registry Connection' azureSubscriptionConnection: 'Kubernetes Cluster Connection' azureResourceGroup: 'tailspin-space-game-rg' kubernetesCluster: 'tailspinspacegame-24591' namespace: 'default'
Andy: 最後のステップでは、Kubernetes クラスターへのイメージのデプロイをトリガーします。 ドキュメントに基づくと、同じタスクを使用できるように見えますが、アクションやパラメーターは異なります。
action
は、実行する機能を示します。 この場合は、AKS クラスターにデプロイするためのdeploy
。connectionType
では、使用するサービス接続の種類を指定します。 省略可能: azureResourceManager または kubernetesServiceConnection。azureSubscriptionConnection
では、ARM のサービス接続の名前を指定します。azureResourceGroup
では、リソース グループの名前を指定します。kubernetesCluster
では、AKS クラスターの名前を指定します。namespace
では、このアクションを適用する Kubernetes 名前空間を指定します。imagePullSecrets
では、コンテナー レジストリからプルするために必要なシークレットの一覧を指定します。containers
では、デプロイするコンテナー イメージの一覧を指定します。
次のスニペットをパイプラインの末尾に追加します。 リソース グループ名とクラスター名の両方が、前に作成したものの名前と一致していることを確認します。 このタスクのインデントが前のタスクのものと一致していることを確認します。
- task: KubernetesManifest@1 displayName: Deploy to Kubernetes cluster inputs: action: deploy connectionType: azureResourceManager azureSubscriptionConnection: 'Kubernetes Cluster Connection' azureResourceGroup: 'tailspin-space-game-rg' kubernetesCluster: 'tailspinspacegame-24591' namespace: 'default' manifests: | $(Pipeline.Workspace)/manifests/deployment.yml $(Pipeline.Workspace)/manifests/service.yml imagePullSecrets: | $(imagePullSecret) containers: | $(RegistryName)/$(webRepository):$(tag) $(RegistryName)/$(leaderboardRepository):$(tag)
パイプラインを実行する
ページの右上隅にある [保存] を選択します。 [保存] を選んで、コミット メッセージを確認します。
[実行] を選び、ブランチ名を確認してから、[実行] を選んでパイプラインの実行をトリガーします。
[パイプライン] を選んでから、自分のパイプラインを選んでパイプライン実行のログを表示します。
パイプラインの実行が完了したら、左側のペインで [環境] を選び、開発環境を選んでデプロイ ジョブを表示します。
次に、デプロイされた Web アプリと API エンドポイントを確認します。 そのためには、Web と "ランキング" 両方のサービスの外部 IP アドレスを取得する必要があります。
Azure portal に移動し、自分の AKS クラスターを選んでから、[サービスとイングレス] を選びます。
AKS でサイトを表示するには、Web サービスの [外部 IP] を選びます。
中断した Azure portal ウィンドウに戻り、ランキング サービスの [外部 IP] をコピーします。 この IP アドレスは、ランキング API がパブリックにホストされている場所です。
次のリンクのプレースホルダーを、コピーした外部 IP に置き換えます。
pageSize=10
クエリ パラメーターを追加して、ブラウザーで JSON 応答を簡単に表示できるようにすることもできます。 ブラウザーの新しいタブで、次のような URL を使用します。http://[IP]/api/Leaderboard?pageSize=10
AKS クラスターでホストされているスコアボード API からの生の JSON 応答を見ることができます。 これで、他のアプリケーションから呼び出すことができる REST API ができました。
Andy: これはすばらしい結果になりました! Kubernetes の使用は、幅広いマイクロサービス戦略を導入するための優れた方法だと思います。