チュートリアル: Kubernetes 向けカナリア デプロイ戦略
Azure DevOps Services | Azure DevOps Server 2022
この段階的なガイドは、canary
戦略で Kubernetes マニフェスト タスクを使用する方法を説明します。 カナリア デプロイ戦略は、アプリケーションの新しいバージョンを安定した次の運用バージョンの隣にデプロイします。
関連するワークフローを使用してコードをデプロイし、ベースラインとカナリア アプリのデプロイを比較します。 評価に基づいて、カナリア デプロイを昇格または拒否するかどうかを決定します。
このチュートリアルでは、Docker Registry と Azure Resource Manager サービス接続を使用して Azure リソースに接続します。 Azure Kubernetes Service (AKS) プライベート クラスターまたはローカル アカウントが無効になっているクラスターの場合は、Azure Resource Managerサービス接続は、より適切な接続方法です。
前提条件
少なくとも、User アクセス許可がある Azure DevOps プロジェクト。
Azure アカウント。 無料でアカウントを作成できます。
Push アクセス許可がある Azure Container Registry。
デプロイ済みの Azure Kubernetes Service (AKS) クラスタ。 AKS クラスターをデプロイする際またはデプロイした後に、AKS クラスターを Azure Container Registry クラスターに接続できます。
GitHub アカウント。 無料の Github アカウントを作成します。
https://github.com/MicrosoftDocs/azure-pipelines-canary-k8s Github リポジトリのフォーク。
重要
次の手順中に、GitHub サービス接続の作成を求められる、サインインするために Github にリダイレクトされる、Azure Pipeline をインストールするように求められる場合があります。 画面上の指示に従って、プロセスを完了します。 詳細については、「Github リポジトリへのアクセス」を参照してください。
GitHub リポジトリ ファイル
GitHub リポジトリには、次のファイルが含まれています。
ファイル | 説明 |
---|---|
./app/app.py | Flask ベースのシンプルな Web サーバー。 このファイルは、success_rate 変数の値に基づいて、良い応答と悪い応答の数のカスタム カウンタを設定します。 |
./app/Dockerfile | app.py に変更するたびにイメージをビルドするために使用されます。 変更が発生するたびに、ビルド パイプラインがトリガーされ、イメージがビルドされ、コンテナー レジストリにプッシュされます。 |
./manifests/deployment.yml | 公開イメージに対応する sampleapp デプロイ ワークロードの仕様が含まれます。 このマニフェスト ファイルは、デプロイ オブジェクトの安定バージョンと、ワークロードのベースラインとカナリアのバリアントを派生させるために使用します。 |
./manifests/service.yml | sampleapp サービスを作成します。 このサービスは、安定版、ベースライン、およびカナリア デプロイによってスピンアップされたポッドにリクエストをルーティングします。 |
./misc/fortio.yml | fortio デプロイを設定します。 このデプロイは、デプロイされた sampleapp サービスに要求のストリームを送信するロード テスト ツールです。 リクエスト ストリームは、安定版、ベースライン、カナリアの 3 つのデプロイメントのポッドにルーティングされます。 |
サービス接続を作成する
- Azure DevOps のプロジェクトで、[プロジェクト設定]>[パイプライン]>[サービス接続] の順に選択します。
- Azure Container Registry インスタンスに関連付けられている azure-pipelines-canary-acr という名前の Docker Registry サービス接続を作成します。
- リソース グループに対して、azure-pipelines-canary-k8s という名前のワークロード ID を使用して Azure Resource Manager サービス接続を作成します。
ビルド ステージを追加する
Azure DevOps プロジェクトで、[パイプライン]>[パイプラインを作成] または [新規パイプライン] の順に選択します。
コードの場所として、[Github] を選択し、フォーク下 azure-pipelines-canary-k8s リポジトリを選択します。
[構成] タブで、[スタート パイプライン] を選びます。
[レビュー] タブで、パイプライン YAML を次のコードに置き換えます。
trigger: - main pool: vmImage: ubuntu-latest variables: imageName: azure-pipelines-canary-k8s # name of ACR image dockerRegistryServiceConnection: azure-pipelines-canary-acr # name of ACR service connection imageRepository: 'azure-pipelines-canary-k8s' # name of image repository containerRegistry: example.azurecr.io # name of Azure container registry tag: '$(Build.BuildId)' stages: - stage: Build displayName: Build stage jobs: - job: Build displayName: Build pool: vmImage: ubuntu-latest steps: - task: Docker@2 displayName: Build and push image inputs: containerRegistry: $(dockerRegistryServiceConnection) repository: $(imageName) command: buildAndPush Dockerfile: app/Dockerfile tags: | $(tag)
作成した Docker レジストリ サービス接続が、
example.azurecr.io
という名前のコンテナ レジストリに関連付けられている場合、イメージはexample.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId)
に設定されます。[保存して実行] を選択して、ジョブが正常に実行されているか確認します。
サービス マニフェスト ファイルを編集する
リポジトリ フォークで、manifests/deployment.yml を編集して、<foobar>
を example.azurecr.io/azure-pipelines-canary-k8s
などの コンテナー レジストリの URL に置き換えます。
Azure App Service での GIT による継続的なデプロイ
次に、継続的デプロイを設定し、カナリア ステージをデプロイし、手動承認でカナリアを昇格または拒否します。
環境の作成
YAML またはクラシックを使ってデプロイできます。
- Azure DevOps プロジェクトで、[パイプライン]>[環境] の順に選択し、[環境を作成] または [新規環境] の順に選択します。
- 最初の [新規環境] 画面の [名前] に akscanary と入力し、[リソース] で [Kubernetes] を選択し、[次へ] を選択します。
- [Kubernetes リソース] 画面で次のように入力します。
- プロバイダー: Azure Kubernetes サービス を選択します。
- Azure サブスクリプション: Azure サブスクリプションを選択します。
- クラスター: AKS クラスターを選択します。
- 名前空間: [新規] を選択し、canarydemo と入力します。
- [検証と作成] を選択します。
カナリア ステージを追加する
[パイプライン] に移動し、作成したパイプラインを選択したら、[編集] を選択します。
パイプライン YAML 全体を次のコードに置き換えます。
このコードは、ステージを使用するために前に実行した
Docker@2
ステップを変更し、マニフェストと misc ディレクトリを連続して使用するアーティファクトとしてコピーする 2 つの手順を追加します。また、このコードでは、パイプラインの後半で使用しやすくするために、いくつかの値を変数に移動します。
containerRegistry
変数で、<example>
をコンテナ レジストリの名前に置き換えます。trigger: - main pool: vmImage: ubuntu-latest variables: imageName: azure-pipelines-canary-k8s dockerRegistryServiceConnection: azure-pipelines-canary-acr imageRepository: 'azure-pipelines-canary-k8s' containerRegistry: <example>.azurecr.io tag: '$(Build.BuildId)' stages: - stage: Build displayName: Build stage jobs: - job: Build displayName: Build pool: vmImage: ubuntu-latest steps: - task: Docker@2 displayName: Build and push image inputs: containerRegistry: $(dockerRegistryServiceConnection) repository: $(imageName) command: buildAndPush Dockerfile: app/Dockerfile tags: | $(tag) - publish: manifests artifact: manifests - publish: misc artifact: misc
YAML ファイルの最後に別のステージを追加して、カナリア バージョンをデプロイします。
my-resource-group
およびmy-aks-cluster
は、実際のリソース グループと Azure Kubernetes Service クラスター名に置き換えてください。trigger: - main pool: vmImage: ubuntu-latest variables: imageName: azure-pipelines-canary-k8s dockerRegistryServiceConnection: azure-pipelines-canary-acr imageRepository: 'azure-pipelines-canary-k8s' containerRegistry: yourcontainerregistry.azurecr.io #update with container registry tag: '$(Build.BuildId)' stages: - stage: Build displayName: Build stage jobs: - job: Build displayName: Build pool: vmImage: ubuntu-latest steps: - task: Docker@2 displayName: Build and push image inputs: containerRegistry: $(dockerRegistryServiceConnection) repository: $(imageName) command: buildAndPush Dockerfile: app/Dockerfile tags: | $(tag) - publish: manifests artifact: manifests - publish: misc artifact: misc - stage: DeployCanary displayName: Deploy canary dependsOn: Build condition: succeeded() jobs: - deployment: Deploycanary displayName: Deploy canary pool: vmImage: ubuntu-latest environment: 'akscanary' strategy: runOnce: deploy: steps: - task: KubernetesManifest@1 displayName: Create Docker Registry Secret inputs: action: 'createSecret' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' secretType: 'dockerRegistry' secretName: 'my-acr-secret' dockerRegistryEndpoint: 'azure-pipelines-canary-acr' - task: KubernetesManifest@1 displayName: Deploy to Kubernetes cluster inputs: action: 'deploy' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' strategy: 'canary' percentage: '25' manifests: | $(Pipeline.Workspace)/manifests/deployment.yml $(Pipeline.Workspace)/manifests/service.yml containers: '$(containerRegistry)/$(imageRepository):$(tag)' imagePullSecrets: 'my-acr-secret' - task: KubernetesManifest@1 displayName: Deploy Forbio to Kubernetes cluster inputs: action: 'deploy' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' manifests: '$(Pipeline.Workspace)/misc/*'
[検証して保存] を選択して、パイプラインを直接メイン ブランチに保存します。
カナリア デプロイの昇格または拒否に対して手動認証を追加する
YAML またはクラシックを使って手動で介入できます。
- akspromote という新しい Kubernetes 環境を作成します。
- 環境リストから新しい akspromote 環境を開き、[承認と確認] タブで [承認] を選択します。
- [承認] 画面での [承認者] で独自のユーザー アカウントを追加します。
- [詳細設定] を展開し、[承認者が独自に実行を承認できるようにする] が選択されているかを確認します。
- [作成] を選択します
昇格と拒否ステージをパイプラインに追加する
[パイプライン] に移動し、作成したパイプラインを選択したら、[編集] を選択します。
変更を促進する YAML ファイルの最後に次の
PromoteRejectCanary
ステージを追加します。- stage: PromoteRejectCanary displayName: Promote or Reject canary dependsOn: DeployCanary condition: succeeded() jobs: - deployment: PromoteCanary displayName: Promote Canary pool: vmImage: ubuntu-latest environment: 'akspromote' strategy: runOnce: deploy: steps: - task: KubernetesManifest@1 displayName: Create Docker Registry Secret for akspromote inputs: action: 'createSecret' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' secretType: 'dockerRegistry' secretName: 'my-acr-secret' dockerRegistryEndpoint: 'azure-pipelines-canary-acr' - task: KubernetesManifest@1 displayName: promote canary inputs: action: 'promote' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' strategy: 'canary' manifests: '$(Pipeline.Workspace)/manifests/*' containers: '$(containerRegistry)/$(imageRepository):$(tag)' imagePullSecrets: 'my-acr-secret' ```
変更をロール バックするファイルの最後に次の
RejectCanary
ステージを追加します。- stage: RejectCanary displayName: Reject canary dependsOn: PromoteRejectCanary condition: failed() jobs: - deployment: RejectCanary displayName: Reject Canary pool: vmImage: ubuntu-latest environment: 'akscanary' strategy: runOnce: deploy: steps: - task: KubernetesManifest@1 displayName: Create Docker Registry Secret for reject canary inputs: action: 'createSecret' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'kubernetes-testing' kubernetesCluster: 'my-aks-cluster' secretType: 'dockerRegistry' secretName: 'my-acr-secret' dockerRegistryEndpoint: 'azure-pipelines-canary-acr' - task: KubernetesManifest@1 displayName: Reject canary deployment inputs: action: 'reject' connectionType: 'azureResourceManager' azureSubscriptionConnection: 'azure-pipelines-canary-sc' azureResourceGroup: 'my-resource-group' kubernetesCluster: 'my-aks-cluster' namespace: 'default' strategy: 'canary' manifests: '$(Pipeline.Workspace)/manifests/*' ```
[検証して保存] を選択して、パイプラインを直接メイン ブランチに保存します。
安定バージョンをデプロイする
パイプラインの初回実行の場合、ワークロードの安定したバージョン、そのベースラインまたはカナリア バージョンは、クラスタに存在しません。 次のように、sampleapp
ワークロードの安定したバージョンをデプロイします。
YAML またはクラシックを使って安定バージョンをデプロイできます。
- app/app.py で、
success_rate = 50
をsuccess_rate = 100
に変更します。 この変更により、パイプラインがトリガーされ、イメージがビルドされてコンテナー レジストリにプッシュされ、DeployCanary
ステージもトリガーされます。 akspromote
環境で承認を構成したため、そのステージが実行する前に、リリースは待機します。 ビルド概要パイプラインで、[レビュー] > [承認] の順に選択します。
承認されると、パイプラインは、manifests/deployment.yml の sampleapp
ワークロードの安定したバージョンを名前空間にデプロイします。
カナリア ワークフローを開始して承認を拒否する
これで、sampleapp
ワークロードの安定したバージョンがクラスターに既存します。 次に、シミュレーション アプリケーションに対して以下の変更を行います。
- app/app.py で、
success_rate = 50
をsuccess_rate = 100
に変更します。 この変更により、パイプラインがトリガーされ、イメージがビルドされてコンテナー レジストリにプッシュされ、DeployCanary
ステージもトリガーされます。 akspromote
環境で承認を構成したため、そのステージが実行する前に、リリースは待機します。- ビルド実行の概要ページで、[確認] を選択し、後続のダイアログ ボックスで [拒否] を選択します。 これにより、デプロイが拒否されます。
拒否した後は、コードのデプロイがパイプラインによって阻止されます。
クリーンアップ
このアプリケーションを引き続き使用しない場合は、Azure portal のリソース グループと Azure DevOps のプロジェクトを削除します。