演習 - Kubernetes クラスターにマルチコンテナー ソリューションをデプロイする

完了

プロジェクトに付属するリリース パイプラインは、ソリューションを Docker コンテナーとしてビルドし、Azure App Service にデプロイするように設計されています。 Kubernetes クラスターへの複数のコンテナーのデプロイをサポートするには、このパイプラインを変更する必要があります。

このユニットでは、以下の方法を学習します。

  • メイン ブランチへのコミットでトリガーするようにパイプラインを更新します。
  • パイプライン全体で共有する変数を定義します。
  • Docker イメージをビルドして発行します。
  • Kubernetes マニフェストを発行します。
  • Kubernetes とコンテナー レジストリ インスタンスの間で使用するイメージ プル シークレットを作成するタスクを追加します。
  • 更新されたイメージを Kubernetes クラスターにデプロイします。

トリガーをサポートするようにパイプラインを更新する

  1. Azure DevOps 組織にサインインしてから、プロジェクトに移動します。

  2. [パイプライン] を選択し、使用するパイプラインを選択します。

  3. [ 編集] を 選択して azure-pipelines.ymlを編集します。

    アンディ: これは、前の単一コンテナー ソリューションのビルド ステージでした。 私はそれが正しく実行されないと知っていたので、私はそれを無効にしました。 最初に、 main ブランチへのコミットでトリガーを再度有効にすることができます。

  4. ファイルの先頭にある既存の trigger 行を次のスニペットに置き換えます。 これにより、メイン ブランチにコミットされるたびにパイプラインの実行がトリガーされます。

    trigger:
    - 'main'
    

パイプライン間でアクセス可能な変数を定義する

アンディ: 2 つのパイプライン変数を追加する必要があります。 ランキング リポジトリの名前 ( ランキング) を指定するための 1 つ。 もう 1 つは、デプロイ時に AKS インスタンスと ACR インスタンス間の共有に使用されるイメージ プル シークレットの名前です。

  1. 次の強調表示されたコードを variables セクションに追加します。

    variables:
      buildConfiguration: 'Release'
      leaderboardRepository: 'leaderboard'
      webRepository: 'web'
      tag: '$(Build.BuildId)'
      imagePullSecret: 'secret'
    

Docker イメージをビルドして Azure Container Registry に発行する

アンディ: Web アプリを Docker コンテナーとして構築するためのタスクが既に存在します。このタスクは、コンテナー レジストリに発行します。 2 番目のタスクを使用して、ランキングに対して同じ操作を行うことができます。

  1. 次の強調表示されたスニペットを使用して、ランキング コンテナーをビルドして発行する 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 マニフェストを発行する

アンディ: 次のステージに進むことができると思います。 何か不足していることがわかりますか?

マラ: デプロイを定義するマニフェスト ファイルがいくつかソース プロジェクトに存在し、デプロイ時に Kubernetes に必要なサービスがあることを説明しました。 このステージを完了する前に公開する必要があります。

アンディ: 必要ですか? それらはまだローカル ディスクに存在するのではありませんか。

マラ: これは、ビルドと同じステージ内にデプロイ タスクを追加する場合です。 ただし、デプロイ タスクは独自の デプロイ ステージで行われるので、新しい環境 (おそらく別のエージェントでも) で実行されます。 このステージで生成されるものは、他のステージで必要なものは必ず公開する必要があります。

アンディ: それは素晴らしいポイントです。 簡単に行うことができますか? マニフェスト フォルダーが新しいエージェントにコピーされていることを確認する必要があります。

Mara: それが PublishBuildArtifacts@1 タスクの目的です。 それは非常に一般的なので、 publish、その短縮形さえあります。

  1. 次のコード スニペットに示すように、将来のステージのマニフェスト フォルダーを格納する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
    

デプロイ ステージを置き換える

マラ: 既存のデプロイ ステージを デプロイ ジョブを使用するステージに置き換えます。 デプロイ ジョブは、先ほど作成した Azure DevOps 環境にデプロイを関連付けることができます。 これにより、デプロイ履歴の追跡が容易になります。これは、ソリューションがより高度になるにつれて特に役立ちます。

  1. 既存の デプロイ ステージ (ビルド ステージの後のすべてのもの) を削除し、次のスニペットに置き換えます。 使用するデプロイ環境を示す強調表示された行を書き留めます。

    - 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:
    

    マラ: 配置ステージで追加する最初の手順は、 DownloadBuildArtifacts@0 タスクを使用して、先ほど発行したマニフェスト成果物をダウンロードすることです。

    アンディ: 私は推測してみましょう、そのタスクの download 短縮形はありますか?

    マラ: その通り! current指定子を使用して、パイプラインの現在の実行からの成果物が必要であることを示すことができます。

  2. 強調表示された行を デプロイ ステージの最初の手順として追加します。

    - 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
    

    アンディ: 次に、ACR インスタンスと AKS インスタンス間で共有されるイメージ プル シークレットを作成する必要があります。 使用できるタスクがあるかどうかを知っていますか?

    Mara: それについて調べたのですが、ラッキーです。 KubernetesManifest@0 タスクは、必要なシークレットを作成するアクションをサポートします。

Kubernetes マニフェスト タスク

Kubernetes マニフェスト タスクは、Kubernetes に必要なすべてのメインストリームデプロイ操作を管理するように設計されています。 シークレットの作成からイメージのデプロイまで、複数の action オプションがサポートされています。 この場合、 createSecret アクションは、次のパラメーターと共に使用されます。

  • action は、実行する機能を示します。 この場合、 createSecret は共有シークレットを作成します。
  • connectionType は、使用するサービス接続の種類を指定します。 オプション: azureResourceManager または kubernetesServiceConnection
  • secretName は、作成するシークレットの名前を指定します。
  • dockerRegistryEndpoint は、Azure Container Registry Services 接続の名前を指定します。
  • azureSubscriptionConnection は、ARM サービス接続の名前を指定します。
  • azureResourceGroup は、リソース グループの名前を指定します。
  • kubernetesCluster は、AKS クラスターの名前を指定します。
  • namespace は、このアクションが適用される Kubernetes 名前空間を指定します。
  1. パイプラインの末尾に次のスニペットを追加します。 リソース グループ名とクラスター名の両方が、前に作成した名前と一致していることを確認します。 このタスクのインデントが ダウンロード タスクのインデントと一致していることを確認します。

    - 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'
    

    アンディ: 最後の手順では、Kubernetes クラスターへのイメージのデプロイをトリガーします。 ドキュメントに基づいて、同じタスクを使用できますが、アクションとパラメーターが異なっているように見えます。

    • action は、実行する機能を示します。 この場合は、AKS クラスターにデプロイする deploy
    • connectionType は、使用するサービス接続の種類を指定します。 オプション: azureResourceManager または kubernetesServiceConnection
    • azureSubscriptionConnection は、ARM サービス接続の名前を指定します。
    • azureResourceGroup は、リソース グループの名前を指定します。
    • kubernetesCluster は、AKS クラスターの名前を指定します。
    • namespace は、このアクションが適用される Kubernetes 名前空間を指定します。
    • imagePullSecrets は、コンテナー レジストリからプルするために必要なシークレットの一覧を指定します。
    • containers は、デプロイするコンテナー イメージの一覧を指定します。
  2. 次のスニペットをパイプラインの末尾に追加します。 リソース グループ名とクラスター名の両方が、前に作成した名前と一致していることを確認します。 このタスクのインデントが前のタスクのインデントと一致していることを確認します。

    - 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)
    

パイプラインを実行する

  1. ページの右上隅にある [保存] を 選択します。 [保存] を選択してコミット メッセージを確認します。

  2. [ 実行] を選択し、ブランチ名を確認し、[ 実行 ] を選択してパイプラインの実行をトリガーします。

  3. [ パイプライン] を選択し、パイプラインを選択して、パイプラインの実行時にログを表示します。

  4. パイプラインの実行が完了したら、左側のウィンドウで [環境 ] を選択し、 開発環境 を選択してデプロイ ジョブを表示します。

  5. 次に、デプロイされた Web アプリと API エンドポイントを確認してみましょう。 そのためには、 Web サービスと ランキング サービスの両方の外部 IP アドレスを取得する必要があります。

  6. Azure portal に移動し、AKS クラスターを選択し、[ サービスとイングレス] を選択します。

    Web サービスとランキング サービスの外部 IP を検索する方法のスクリーンショット。

  7. Web サービスの外部 IP を選択して、AKS でサイトを表示します。

    Space Game Web サイトのスクリーンショット。

  8. 中断した Azure portal ウィンドウに戻り、リーダーボード サービスの外部 IP をコピーします。 この IP アドレスは、ランキング API がパブリックにホストされている場所です。

  9. 次のリンクのプレースホルダーを、コピーした外部 IP に置き換えます。 pageSize=10クエリ パラメーターを追加して、ブラウザーで JSON 応答を簡単に表示できるようにすることもできます。 新しいブラウザー タブで、次のような URL を使用します。

    http://[IP]/api/Leaderboard?pageSize=10
    
  10. AKS クラスターでホストされているランキング API から生の JSON 応答を表示できます。 これで、他のアプリケーションから呼び出すことができる REST API が作成されました。

    ランキング サービスからの JSON 応答を示す Web ブラウザーのスクリーンショット。

アンディ: これは素晴らしい結果を得た! Kubernetes を使用することは、より広範なマイクロサービス戦略を採用するための優れた方法になると思います。