この記事は、Microservices July 2023: マイクロサービスのStart Delivering Microservicesの方法を実行するための4つのチュートリアルの1つです。
- マイクロサービスのデプロイと構成方法
- コンテナ環境での安全なシークレット管理方法
- GitHub Actionsを使ってマイクロサービスのカナリアデプロイメントを自動化する方法(この記事)
- OpenTelemetryトレーシングを使ったマイクロサービスの可視化方法
ほとんどのプロジェクトにおいて、その成功の鍵を握るのはデプロイメントの自動化です。ただし、自動化とは、コードを展開するだけでは十分ではありません。ダウンタイムをできる限り少なく (または排除)し、障害発生時には、迅速にロールバックを実行する必要があります。カナリアデプロイメントとブルーグリーンデプロイメントを組み合わせることは、新しいコードを実行可能にするための一般的なアプローチです。 この戦略には、以下の2つの手順があります。
- 手順1: 隔離された環境でのカナリアデプロイメントによるテスト – 環境外の隔離されたノード、サーバー、またはコンテナでコードを展開し、コードが意図したとおりに動作することをテストします。
- 手順2: 本番環境でのブルーグリーンデプロイメントによるテスト – コードがカナリアデプロイメントで動作すると想定される際に、現在のバージョンのサーバーだけではなく、本番環境に新しく作成されたサーバー(またはノードやコンテナ)にコードを移植します。移植後、本番環境のトラフィックの一部を新しいバージョンにリダイレクトして、より高い負荷下でも正常に動作するか、テストします。ほとんどの場合、最初は新しいバージョンに小さな割合(たとえば10%)のトラフィックを転送し、徐々に量を増やして、新しいバージョンがすべてのトラフィックを受信できるかどうか、確認します。通信を増加させる量は、新しいバージョンがトラフィックをどの程度処理できると想定されるかによって決めますが、ワンステップで新しいバージョンに完全に切り替えることもできます。
異なるバージョンのアプリやWebサイト間でトラフィックを分散する様々なユースケース(トラフィック分割)についてあまりご存じではない場合は、当社ブログの「高度なトラフィック管理でKubernetesの耐障害性を向上させる方法」を読んで、ブルーグリーンデプロイ、カナリアリリース、A/Bテスト、レート制限、サーキットブレーカーなどのコンセプトをご理解されることをお勧めします。このブログは Kubernetesに特化していますが、コンセプトはマイクロサービスアプリに広く適用できます。
チュートリアルの概要
このチュートリアルでは、GitHub Actionsを使って、カナリア/ブルーグリーンデプロイメントの最初の手順を自動化する方法を説明します。以下に示すチュートリアルの4つの課題では、Microsoft Azure Container Appsを使用して新しいバージョンのアプリケーションを展開し、Azure Traffic Managerを使用してトラフィックを古い環境から新しい環境へと移行します。
- NGINXコンテナアプリを作成し展開する
- Azure Container Appのデプロイメント自動化に向け、権限を設定する
- GitHub Actionsを使って、カナリア/ブルーグリーンデプロイメントを作成する
- GitHub Actionsワークフローをテストする
注:このチュートリアルではAzure Container Appsを使用していますが、コンセプトとテクニックはどのクラウドベースのホストにも適用できます。
前提条件とセットアップ
前提条件
このチュートリアルをご自身の環境で行う場合は、以下の条件が必要となります。
- Azureアカウント。ご自分の組織のアカウントを使用した際に権限に関する問題が生じる場合があるため、組織と連動していないアカウントをご使用になることをお勧めします。
- Azure CLI。
- GitHub CLI。ブラウザベースのGitHub GUIの代わりに(または追加で)使用します。
セットアップ
必要な基本リソースを作成し設定を行います。チュートリアルのリポジトリをフォーク、クローンした後、Azure CLIにログインし、Azure Container Appsの拡張機能をインストールします。
-
ホームディレクトリに、microservices-marchディレクトリを作成します(別のディレクトリ名を使って、臨機応変に手順を変更することも可能です)。
注:このチュートリアルでは、コマンドをターミナルにコピー&ペーストしやすいように、Linuxコマンドラインのプロンプトを省略しています。
mkdir ~/microservices-march cd ~/microservices-march
-
GitHub CLIまたはGUIを使って、Microservices Marchプラットフォームリポジトリを自分(個人)のGitHubアカウントにフォークおよびクローンします。
-
GitHub GUIを使用する場合は、以下を実行します。
-
GitHub CLIを使用する場合は、以下を実行します。
gh repo fork microservices-march/platform -–clone
-
-
Azure CLI にログインします。ブラウザを使用し、以下のようにプロンプトに従ってログインします。
az login [ { "cloudName": "AzureCloud", "homeTenantId": "cfd11e0f-1435-450s-bdr1-ffab73b4er8e", "id": "60efapl2-38ad-41w8-g49a-0ecc6723l97c", "isDefault": true, "managedByTenants": [], "name": "Azure subscription 1", "state": "Enabled", "tenantId": "cfda3e0f-14g5-4e05-bfb1-ffab73b4fsde", "user": { "name": "user@example.com", "type": "user" } } ]
-
containerapp
拡張機能をインストールします。az extension add --name containerapp -upgrade The installed extension 'containerapp' is in preview.
課題1:NGINX Container Appを作成し展開する
この最初の課題では、カナリア/ブルーグリーンデプロイメントのベースラインとして使用するアプリケーションの初期バージョンとしてNGINX Azure Container Appを作成します。Azure Container Appsは、コンテナにパッケージ化されたアプリケーションコードを、本番環境に対応したコンテナ環境で簡単に実行するためのMicrosoft Azureサービスです。
-
以下のように、コンテナアプリのAzureリソースグループを作成します。
az group create --name my-container-app-rg --location westus { "id": "/subscriptions/0efafl2-38ad-41w8-g49a-0ecc6723l97c/resourceGroups/my-container-app-rg", "location: "westus", "managedBy": null, "name": "my-container-app-rg", "properties": { "provisioningState": "Succeeded" }, "tags": null, "type": "Microsoft.Resources/resourceGroups" }
-
以下のように、コンテナをAzure Container Appsに展開します(この手順には時間がかかる場合があります)。
az containerapp up \ --resource-group my-container-app-rg \ --name my-container-app \ --source ./ingress \ --ingress external \ --target-port 80 \ --location westus ... - image: registry: cac085021b77acr.azurecr.io repository: my-container-app tag: "20230315212413756768" digest: sha256:90a9fc67c409e244195ec0ea190ce3b84195ae725392e8451... runtime-dependency: registry: registry.hub.docker.com repository: library/nginx tag: "1.23" digest: sha256:aa0afebbb3cfa473099a62c4b32e9b3fb73ed23f2a75a65ce... git: {} Run ID: cf1 was successful after 27s Creating Containerapp my-container-app in resource group my-container-app-rg Adding registry password as a secret with name "ca2ffbce7810acrazurecrio-cac085021b77acr" Container app created. Access your app at https://my-container-app.delightfulmoss-eb6d59d5.westus.azurecontainerapps.io/ ...
-
手順2の出力で、Azure Container Registry (ACR)で作成したコンテナアプリの名前とURLを見つけることができます。出力例では、オレンジ色で強調表示されています。このチュートリアルでは、コマンドで指定された変数を、出力の値(手順2の出力例とは異なります)に置き換えます。
-
コンテナアプリの名前 –
image.registry
キーで.azurecr.io
の前の文字列です。手順2の出力例では、cac085021b77acr
です。後続のコマンドでは、
<ACR_name>
をこの文字列に置き換えます。 -
コンテナアプリのURL –
Container
app
created
を開始する行のURLです。手順2の出力例では、https://my-container-app.delightfulmoss-eb6d59d5.westus.azurecontainerapps.io/
です。後続のコマンドでは、
<ACR_URL>
をこのURLに置き換えます。
-
-
以下のように、ブルーグリーンデプロイメントの必要に応じて、コンテナアプリのリビジョンを有効にします。
az containerapp revision set-mode \ --name my-container-app \ --resource-group my-container-app-rg \ --mode multiple "Multiple"
-
(オプション)以下のように、コンテナ内の /healthエンドポイントをクエリし、デプロイメントが動作していることをテストします。
curl <ACR_URL>/health OK
課題2:AzureContainer Appのデプロイメントを自動化するために必要な権限を設定する
この課題では、Azureコンテナアプリのデプロイメントを自動化できるようにするためJSONトークンを取得します。
まず、Azure Container Registry (ACR) のIDを取得し、その後、Azure マネージドIDのプリンシパルIDを取得します。次に、ACR用の組み込みAzureロールをマネージドIDに割り当て、それを使用するようにコンテナアプリを設定します。最後に、マネージドIDのJSONクレデンシャルを取得します。これは、GitHub ActionsがAzureに対して認証を行う際に使用されます。
この一連の手順は、面倒に思えるかもしれませんが、新しいアプリケーションを作成するときに1回実行するだけで、プロセスを完全にスクリプト化できます。このチュートリアルでは、これらの手順に慣れるために手動での操作方法を紹介しています。
注:デプロイメントのためのクレデンシャルを作成するこのプロセスは、Azure特有のものです。
-
マネージドIDのプリンシパルIDを調べます。これは、出力の
PrincipalID
列に表示されています(見やすくするために2行に分割しています)。手順3では、以下のように、 この値を<managed_identity_principal_ID>
の代わりに使用します。az containerapp identity assign \ --name my-container-app \ --resource-group my-container-app-rg \ --system-assigned \ --output table PrincipalId ... ------------------------------------ ... 39f8434b-12d6-4735-81d8-ba0apo14579f ... ... TenantId ... ------------------------------------ ... cfda3e0f-14g5-4e05-bfb1-ffab73b4fsde
-
ACRでコンテナアプリのリソースIDを調べ、
<ACR_name>
を課題1の手順3でメモした名前に置き換えます。次の手順では、以下のように、この値を<ACR_resource_ID>
の代わりに使用します。az acr show --name <ACR_name> --query id --output tsv /subscriptions/60efafl2-38ad-41w8-g49a-0ecc6723l97c/resourceGroups/my-container-app-rg/providers/Microsoft.ContainerRegistry/registries/cac085021b77acr
-
以下のように、コンテナアプリのマネージドIDにACRのビルトインAzureロールを割り当て、
<managed_identity_principal_ID>
を手順1で取得したマネージドIDに、<ACR_resource_ID>
を手順2で取得したリソースIDに、それぞれ置き換えます。az role assignment create \ --assignee <managed_identity_principal_ID> \ --role AcrPull \ --scope <ACR_resource_ID> { "condition": null, "conditionVersion": null, "createdBy": null, "createdOn": "2023-03-15T20:28:40.831224+00:00", "delegatedManagedIdentityResourceId": null, "description": null, "id": "/subscriptions/0efafl2-38ad-41w8-g49a-0ecc6723l97c/resourceGroups/my-container-app-rg/providers/Microsoft.ContainerRegistry/registries/cac085021b77acr/providers/Microsoft.Authorization/roleAssignments/f0773943-8769-44c6-a820-ed16007ff249", "name": "f0773943-8769-44c6-a820-ed16007ff249", "principalId": "39f8ee4b-6fd6-47b5-89d8-ba0a4314579f", "principalType": "ServicePrincipal", "resourceGroup": "my-container-app-rg", "roleDefinitionId": "/subscriptions/60e32142-384b-43r8-9329-0ecc67dca94c/providers/Microsoft.Authorization/roleDefinitions/7fd21dda-4fd3-4610-a1ca-43po272d538d", "scope": "/subscriptions/ 0efafl2-38ad-41w8-g49a-0ecc6723l97c/resourceGroups/my-container-app-rg/providers/Microsoft.ContainerRegistry/registries/cac085021b77acr", "type": "Microsoft.Authorization/roleAssignments", "updatedBy": "d4e122d6-5e64-4bg1-9cld-2aceeb0oi24d", "updatedOn": "2023-03-15T20:28:41.127243+00:00" }
-
ACRから画像を取得するときにマネージドIDを使用するようにコンテナアプリを構成し、
<ACR_name>
を課題1の手順3(前述の手順2でも使用)でメモしたコンテナアプリ名に置き換えます。az containerapp registry set \ --name my-container-app \ --resource-group my-container-app-rg \ --server <ACR_name>.azurecr.io \ --identity system [ { "identity": "system", "passwordSecretRef": "", "server": "cac085021b77acr.azurecr.io", "username": "" } ]
-
AzureサブスクリプションIDを確認します。
az account show --query id --output tsv 0efafl2-38ad-41w8-g49a-0ecc6723l97c
-
<subscription_ID>
をAzureサブスクリプションIDに置き換えて、GitHub Actionsで使用するクレデンシャルを含むJSONトークンを作成します。「GitHubリポジトリにシークレットを追加する」にある、AZURE_CREDENTIALS
という名前のシークレットの値として貼り付けるため、出力を保存します。--sdk-auth
が非推奨になるという警告は無視しても構いません。これは、既知の事象です。az ad sp create-for-rbac \ --name my-container-app-rbac \ --role contributor \ --scopes /subscriptions/<subscription_ID>/resourceGroups/my-container-app-rg \ --sdk-auth \ --output json Option '--sdk-auth' has been deprecated and will be removed in a future release. ... { "clientId": "0732444d-23e6-47fb-8c2c-74bddfc7d2er", "clientSecret": "qg88Q~KJaND4JTWRPOLWgCY1ZmZwN5MK3N.wwcOe", "subscriptionId": "0efafl2-38ad-41w8-g49a-0ecc6723l97c", "tenantId": "cfda3e0f-14g5-4e05-bfb1-ffab73b4fsde", "activeDirectoryEndpointUrl": "https://login.microsoftonline.com", "resourceManagerEndpointUrl": "https://management.azure.com/", "activeDirectoryGraphResourceId": "https://graph.windows.net/", "sqlManagementEndpointUrl": "https://management.core.windows.net:8443/", "galleryEndpointUrl": "https://gallery.azure.com/", "managementEndpointUrl": "https://management.core.windows.net/" }
課題3: カナリア/ブルーグリーンデプロイメントGitHub Actionを作成する
この課題では、GitHubリポジトリ(GitHub Actionワークフローの機密データを管理するために使用)にシークレットを追加し、Actionワークフローファイルを作成してActionワークフローを実行します。
シークレット管理の詳細については、当社ブログに掲載されている、3月23日マイクロサービスの2番目のチュートリアル「How to Securely Manage Secrets in Containers(コンテナ内のシークレットを安全に管理する方法)」を参照してください。
GitHubリポジトリにシークレットを追加する
新しいバージョンのアプリケーションを展開するには、「セットアップ」でフォークしたGitHubリポジトリに一連のシークレットを作成する必要があります。シークレットは、課題2で作成したマネージドIDのJSONクレデンシャルとNGINXイメージの新しいバージョンをAzureに展開するために必要な、デプロイメントに特化した機密度の高いパラメーターです。次のセクションでは、これらのシークレットをGitHub Actionで使って、カナリア/ブルーグリーンデプロイメントを自動化します。
-
GitHub GUIを利用する場合は、以下を実行します。
- フォークしたGitHubリポジトリに移動します。
- 「Settings」 > 「Secrets and variables」 > 「Actions」の順に選択します。
- 「New repository secret」をクリックします。
-
表示されたフィールドに以下の値を入力します。
- Name –
AZURE_CREDENTIALS
- Secret – 課題2の手順6のJSONクレデンシャル
- Name –
- 「Add secret」をクリックします。
-
手順3から5を3回繰り返して、表に示すシークレットを作成します。Secret Name列とSecret Value列の値をGUIのNameフィールドとSecretフィールドそれぞれに入力します。3番目のシークレットでは、
<ACR_name>
を課題1の手順3でメモしたコンテナアプリに割り当てた名前に置き換えます。Secret Name Secret Value CONTAINER_APP_NAME
my-container-app
RESOURCE_GROUP
my-container-app-rg
ACR_NAME
<ACR_name>
- 「GitHub Actionsワークフローファイルの作成」に進みます。
-
GitHub CLIを使用する場合は、以下を実行します。
-
リポジトリのルートに、一時ファイルを作成します。
touch ~/creds.json
- 任意のテキストエディタを使ってcreds.jsonを開き、課題2の手順6で作成したJSONクレデンシャルをコピーします。
-
以下のように、シークレットを作成します。
gh secret set AZURE_CREDENTIALS --repo <your_GitHub_account>/platform < ~/creds.json
-
以下のように、creds.jsonを削除します。
rm ~/creds.json
-
以下のように、このコマンドを繰り返して、さらに3つのシークレットを作成します。
gh secret set <secret_name> --repo <your_GitHub_account>/platform
1回ごとに、
<secret_name>
を表のSecret Name列のいずれかの値に置き換えます。プロンプトが表示されたら、Secret Value列から関連する値を貼り付けます。3番目のシークレットでは、<ACR_name>
を課題1の手順3でメモしたコンテナアプリに割り当てた名前に置き換えます。Secret Name Secret Value CONTAINER_APP_NAME
my-container-app
RESOURCE_GROUP
my-container-app-rg
ACR_NAME
<ACR_name>
-
GitHub Actionsワークフローファイルの作成
マネージドIDとシークレットを配置すると、カナリア/ブルーグリーンデプロイメントを自動化するGitHub Actionsのワークフローファイルを作成できます。
注:ワークフローファイルはYAML形式で定義します。YAML形式ではスペースが重要です。以下の手順が示すように、必ずインデントを使用してください。
-
Actionsのワークフロー用ファイルを作成します。
-
GitHub GUIを利用する場合は、以下を実行します。
- GitHubのリポジトリに移動します。
- 「Actions」 > 「New workflow」 > 「Skip this and set up a workflow yourself」の順に選択します。
-
GitHub CLIを使用する場合は、.github/workflowsディレクトリを作成し、main.ymlという名前のファイルを新規作成します。
mkdir .github/workflows touch .github/workflows/main.yml
-
-
任意のテキストエディタを使用して、ワークフローのテキストをmain.ymlに追加します。 最も簡単な方法は、ワークフローファイル全体に表示されるテキストにコピーすることです。または、この手順で注釈を付けた一連のスニペットを追加して、ファイルを手動でビルドします。
注:ワークフローファイルはYAML形式で定義します。YAML形式ではスペースが重要です。スニペットをコピーする場合は、必ずインデントされた状態でコピーします(コピー後、念のためファイルをワークフローファイル全体と比較します)。
-
以下のように、ワークフローの名前を定義します。
name: Deploy to Azure
-
以下のように、メインブランチに対してプッシュまたはプルのリクエストが行われたときに実行するワークフローを構成します。
on: push: branches: - main pull_request: branches: - main
-
以下のように、
jobs
セクションでコードをチェックアウトし、Azureにログインし、アプリケーションをAzure Container Appに展開するbuild-deploy
ジョブを定義します。jobs: build-deploy: runs-on: ubuntu-22.04 steps: - name: Check out the codebase uses: actions/checkout@v3 - name: Log in to Azure uses: azure/login@v1 with: creds: ${{ secrets.AZURE_CREDENTIALS }} - name: Build and deploy Container App run: | # Add the containerapp extension manually az extension add --name containerapp --upgrade # Use Azure CLI to deploy update az containerapp up -n ${{ secrets.CONTAINER_APP_NAME }}\ -g ${{ secrets.RESOURCE_GROUP }} \ --source ${{ github.workspace }}/ingress \ --registry-server ${{ secrets.ACR_NAME }}.azurecr.io
-
test-deployment
ジョブを定義します。このジョブは、新しく展開されたリビジョンのステージングURLを取得した後、GitHub Actionsを使ってAPIエンドポイント/healthにpingを実行し、新しいリビジョンが応答していることを確認します。このヘルスチェックに問題がなければ、コンテナアプリのAzure Traffic Managerは更新され、すべてのトラフィックは新しく展開されたコンテナに流れます。注:前述の手順で定義した
build-deploy
キーと同じレベルで、test-deployment
キーがインデントされていることを確認してください。test-deployment: needs: build-deploy runs-on: ubuntu-22.04 steps: - name: Log in to Azure uses: azure/login@v1 with: creds: ${{ secrets.AZURE_CREDENTIALS }} - name: Get new container name run: | # Add the containerapp extension manually az extension add --name containerapp --upgrade # Get the last deployed revision name REVISION_NAME=`az containerapp revision list -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --query "[].name" -o tsv | tail -1` # Get the last deployed revision's fqdn REVISION_FQDN=`az containerapp revision show -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --revision "$REVISION_NAME" --query properties.fqdn -o tsv` # Store values in env vars echo "REVISION_NAME=$REVISION_NAME" >> $GITHUB_ENV echo "REVISION_FQDN=$REVISION_FQDN" >> $GITHUB_ENV - name: Test deployment id: test-deployment uses: jtalk/url-health-check-action@v3 # Marketplace action to touch the endpoint with: url: "https://${{ env.REVISION_FQDN }}/health" # Staging endpoint - name: Deploy succeeded run: | echo "Deployment succeeded! Enabling new revision" az containerapp ingress traffic set -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --revision-weight "${{ env.REVISION_NAME }}=100"
-
ワークフローファイル全体
以下のファイルが、Actionワークフローファイルの完全なテキスト(全文)です。
name: Deploy to Azure
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build-deploy:
runs-on: ubuntu-22.04
steps:
- name: Check out the codebase
uses: actions/checkout@v3
- name: Log in to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Build and deploy Container
run: |
# Add the containerapp extension manually
az extension add --name containerapp -upgrade
# Use Azure CLI to deploy update
az containerapp up -n ${{ secrets.CONTAINER_APP_NAME }} \
-g ${{ secrets.RESOURCE_GROUP }} \
--source ${{ github.workspace }}/ingress \
--registry-server ${{ secrets.ACR_NAME }}.azurecr.io
test-deployment:
needs: build-deploy
runs-on: ubuntu-22.04
steps:
- name: Log in to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Get new container name
run: |
# Install the containerapp extension for the Azure CLI
az extension add --name containerapp --upgrade
# Get the last deployed revision name
REVISION_NAME=`az containerapp revision list -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --query "[].name" -o tsv | tail -1`
# Get the last deployed revision's fqdn
REVISION_FQDN=`az containerapp revision show -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --revision "$REVISION_NAME" --query properties.fqdn -o tsv`
# Store values in env vars
echo "REVISION_NAME=$REVISION_NAME" >> $GITHUB_ENV
echo "REVISION_FQDN=$REVISION_FQDN" >> $GITHUB_ENV
- name: Test deployment
id: test-deployment
uses: jtalk/url-health-check-action@v3 # Marketplace action to touch the endpoint
with:
url: "https://${{ env.REVISION_FQDN }}/health" # Staging endpoint
- name: Deploy succeeded
run: |
echo "Deployment succeeded! Enabling new revision"
az containerapp ingress traffic set -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --revision-weight "${{ env.REVISION_NAME }}=100"
Actionsワークフローの実行
-
GitHub GUIを利用する場合は、以下を実行します。
- 「Start commit」をクリックし、必要に応じてコミットメッセージを追加し、ダイアログボックスで 「Commit new file」を選択します。新しいワークフローファイルがメインブランチにマージされ、実行が開始されます。
- 「Actions」をクリックして、ワークフローの進行状況をモニタリングします。
-
GitHub CLIを利用する場合は、以下を実行します。
-
以下のように、main.ymlをGitステージングエリアに追加します。
git add .github/workflows/main.yml
-
以下のように、ファイルをコミットします。
git commit -m "feat: create GitHub Actions workflow"
-
以下のように、変更内容をGitHubにプッシュします。
git push
-
以下のように、ワークフローの進捗状況をモニタリングします。
gh workflow view main.yml --repo <your_GitHub_account>/platform
-
課題4:GitHub Actionsのワークフローをテストする
この課題では、ワークフローをテストします。最初に、Ingressロードバランサの正常な更新が行われるケースをシミュレートし、アプリケーションが正しく更新されたことを確認します。次に、更新に失敗するケース(内部サーバーエラーになるケース)をシミュレートし、公開したアプリケーションが変更されないことを確認します。
正常な更新を成功させる
正常な更新を作成し、ワークフローの更新が成功するのを確認します。
-
GitHub GUIを利用する場合は、以下を実行します。
- 「Code」 > 「ingress」 > 「default.conf.template」の順に選択します。
- このファイルを編集するには、「Edit this file」で鉛筆アイコンを選択し、default.conf.templateを開きます。
-
ファイル末尾近くの
location
/health
ブロックで、以下のように、return
ディレクティブを変更します。location /health { access_log off; return 200 "Successful Update!\n"; }
- ダイアログボックスで、「Create a new branch for this commit and start a pull request」を選択し、その後、「Propose changes」を選択します。
- 「Create pull request」をクリックし、プルリクエストのテンプレートにアクセスします。
- 「Create pull request」をもう一度クリックし、プルリクエストを作成します。
- ワークフローの進捗を確認するため「Actions」をクリックします。
- ワークフローが完了したら、<ACR_URL>/healthエンドポイントのコンテナアプリに移動します。ここでの<ACR_URL>は課題1の手順3でメモしたURLです。「
Successful
Update!
」というメッセージが表示されます。 -
ターミナルセッションを開始し、ヘルスチェックのリクエストをアプリに送信し、再度
<ACR_URL>
を課題1の手順3でメモした値に置き換え、メッセージを確認します。curl <ACR_URL>/health Successful Update!
- 更新を失敗させるに進みます。
-
GitHub CLIを利用する場合は、以下を実行します。
-
以下のように、patch-1という名称で新しいブランチを作成します。
git checkout -b patch-1
-
任意のテキストエディタで、ingress/default.conf.templateを開き、以下のように、ファイル末尾近くの
location
/health
ブロックで、return
ディレクティブを変更します。location /health { access_log off; return 200 "Successful Update!\n"; }
-
以下のように、default.conf.templateをGitのステージングエリアに追加します。
git add ingress/default.conf.template
-
ファイルをコミットします。
git commit -m "feat: update NGINX ingress"
-
変更をGitHubにプッシュします。
git push --set-upstream origin patch-1
-
以下のように、プルリクエスト(PR)を作成します。
gh pr create --head patch-1 --fill --repo <your_GitHub_account>/platform
-
ワークフローの進捗を確認します。
gh workflow view main.yml --repo <your_GitHub_account>/platform
-
ワークフローが完了したら、以下のように、
<ACR_URL>
を課題1の手順3でメモした値に置き換え、ヘルスチェックのリクエストをアプリケーションに送信します。curl <ACR_URL>/health Successful Update!
-
更新を失敗させる
次に、失敗する更新を作成し、ワークフローが失敗することを確認します。これは基本的に、更新を成功させると同様の手順を繰り返しますが、return
ディレクティブの値は異なります。
-
GitHub GUIを利用する場合は、以下を実行します。
- 「Code」 > 「ingress」 > 「default.conf.template」の順に選択します。
- 左上で「main」を選択した後、patch-1で終わるブランチの名前を選択します。これは前のセクションで作成したものです。
- このファイルを編集するには、「Edit this file」で鉛筆アイコンを選択し、default.conf.templateを開きます。
-
以下のように、
return
ディレクティブを変更します。location /health { access_log off; return 500 "Unsuccessful Update!\n"; }
- 「Commit directly to the -patch-1 branch」を選択した後、「Commit changes」を選択します。
- 「Actions」を選択し、ワークフローの進行状況を確認します。ただし、 PR内のファイルが更新されると、ワークフローが再び実行されることに注意してください。
-
ワークフローが完了したら、<ACR_URL>/healthエンドポイントのコンテナアプリに移動します。<ACR_URL>は、課題1の手順3でメモしたURLです。
(前回の正常な更新と同じく)「
Successful
Update!
」というメッセージが表示されることに注意してください。これは、一見逆に思えるかもしれませんが、実際は更新が成功していません。更新を試みた結果、ステータス500
(Internal
Server
Error
を意味する)となり、更新は実行されていません。 -
ターミナルセッションを開始し、ヘルスチェックのリクエストをアプリに送信し、再度
<ACR_URL>
を課題1の手順3でメモした値に置き換え、メッセージを確認します。curl <ACR_URL>/health Successful Update!
-
GitHub CLIを利用する場合は、以下を実行します。
-
以下のように、前のセクションで作成したpatch-1ブランチをチェックアウトします。
git checkout patch-1
-
任意のテキストエディタで、ingress/default.conf.templateを開き、以下に示すように、
return
ディレクティブを再度変更します。location /health { access_log off; return 500 "Unsuccessful Update!\n"; }
-
Gitのステージング領域にdefault.conf.templateを追加します。
git add ingress/default.conf.template
-
ファイルをコミットします。
git commit -m "feat: update NGINX ingress again"
-
変更をGitHubにプッシュします。
git push
-
ワークフローの進捗を確認します。
gh workflow view main.yml --repo <your_GitHub_account>/platform
-
ワークフローが完了したら、以下のように、
<ACR_URL>
を課題1の手順3でメモした値に置き換え、ヘルスチェックのリクエストをアプリケーションに送信します。curl <ACR_URL>/health Successful Update!
(前回の正常な更新と同じく)「
Successful
Update!
」というメッセージは、一見逆であるように思えます。ただ、逆のように思えるだけで、実際はこの更新は成功していません。更新を試みた結果、ステータス500
(Internal
Server
Error
を意味する)となり、更新は実行されていません。
-
リソースのクリーンアップ
将来的に発生しうる料金の請求を回避するために、以下のように、チュートリアルで展開したAzureリソースを削除したい場合があるかもしれません。
az group delete -n my-container-app-rg -y
必要に応じて、作成したフォークを削除することも可能です。
-
GitHub GUIを利用する場合は、以下を実行します。
- 「Settings」をクリックします。
- ページの一番下までスクロールします。
- 「Delete this repository」をクリックします。
- <your_GitHub_account>/platformと入力し、「I understand the consequences, delete this repository」を選択します。
-
GitHub CLIを利用する場合は、以下を実行します。
gh repo delete <your_GitHub_account>/platform -yes
次のステップへ
おめでとうございます!GitHub Actionsによる、マイクロサービスアプリのカナリア/ブルーグリーンデプロイメントの実行方法をご理解いただけたと思います。引き続き、DevOpsに関する知識を深めるには、GitHubドキュメントの以下の記事をお読みください。
- About workflows(ワークフローについて)
- About continuous integration using GitHub Actions(GitHub Actionsを使った継続的インテグレーションについて)
- About continuous deployment using GitHub Actions(GitHub Actionsを使った継続的デプロイメントについて)
- About monitoring and troubleshooting(モニタリングとトラブルシューティングについて)
カナリアデプロイメントの2番目の手順(本番環境でのテスト)を試す準備ができている場合は、当社ブログのMicroservices March 2022のチュートリアル「Improve Uptime and Resilience with a Canary Deployment(カナリアデプロイメントで、動作時間と復元力を改善する)」をご確認ください。NGINXサービスメッシュを使用することで、新しいアプリのバージョンに段階的に移行できます。デプロイメントがサービスメッシュを必要とするほど複雑ではない、あるいはKubernetesを使用しない場合でも、イングレスコントローラやロードバランスのみを使用する単純なデプロイメントにおいて、段階的移行が可能となります。
マイクロサービスへの理解度をさらに深めるためには、「Microservices July」をご覧ください。Unit3:自動化でマイクロサービスのデプロイを加速するでは、デプロイメントの自動化について詳しく説明しています。