NGINXチュートリアル:GitHub Actionsを使用してマイクロサービスのカナリアデプロイを自動化する方法

NGINX | 2023年3月21日

この投稿は、「Microservices March 2023: Start Delivering Microservices」の概念を実践するための4つのチュートリアルのうちの1つです:

ほとんどのプロジェクトを成功させるには、デプロイの自動化が不可欠です。しかし、コードをデプロイするだけでは十分ではありません。ダウンタイムを最小限に抑える(またはなくす)とともに、障害発生時に迅速にロールバックできるようにする必要もあります。一般的には、カナリアデプロイとブルーグリーンデプロイを組み合わせて、新しいコードが実用に耐えられることを確認します。この戦略は、次の2つのステップで構成されます。

  • ステップ1:分離環境でテストするためのカナリアデプロイ – コードを環境外の分離されたノード、サーバー、またはコンテナにデプロイし、意図したとおりに動作することを確認します。
  • ステップ2:本番環境でテストするためのブルーグリーンデプロイ – カナリアデプロイでコードが正常に動作することを確認したら、本番環境で現行バージョンのサーバーと並行して新たに作成したサーバー(またはノードやコンテナ)にコードを移行します。次に、本番トラフィックの一部を新しいバージョンに振り向け、負荷が高い状況でも引き続き正常に動作するかテストします。通常は、まず少量(たとえば10%)のトラフィックを新しいバージョンに振り向け、すべてのトラフィックが新しいバージョンに送られるまで段階的に割合を増やします。増加幅は、新しいバージョンがトラフィックを処理できるという確信の度合いに応じて決めます。1回で新しいバージョンへ完全に切り替えることもできます。

アプリやWebサイトの異なるバージョン間でトラフィックを分散するさまざまなユースケース(「トラフィック分割」)について詳しくない場合は、F5のブログ記事「高度なトラフィック管理でKubernetesのレジリエンスを向上させる方法」をご覧ください。ブルーグリーンデプロイ、カナリアリリース、A/Bテスト、レート制限、サーキットブレーカーなどの概念を理解できます。この記事はKubernetesに特化していますが、これらの概念はマイクロサービスアプリにも幅広く適用できます。

チュートリアルの概要

このチュートリアルでは、GitHub Actionsを使用して、カナリア方式のブルーグリーンデプロイの最初のステップを自動化する方法を説明します。チュートリアルの4つの課題では、Microsoft Azure Container Appsを使用してアプリケーションの新しいバージョンをデプロイし、続いてAzure Traffic Managerを使用してトラフィックを旧環境から新環境へ移行します。

注:このチュートリアルではAzure Container Appsを使用していますが、ここで紹介する概念と手法は、あらゆるクラウドベースのホストに適用できます。

前提条件とセットアップ

前提条件

ご自身の環境でこのチュートリアルを実施するには、以下が必要です。

  • 組織に関連付けられていないAzureアカウント。組織アカウントを使用すると権限の問題が発生する可能性があるため、組織に関連付けられていないアカウントの使用を推奨します。
  • The Azure CLI.
  • ブラウザベースのGitHub GUIの代わりに(または併用して)使用する場合は、GitHub CLI。

セットアップ

必要な基本リソースを作成して構成します。チュートリアル用のリポジトリをフォークしてクローンし、Azure CLIにログインして、Azure Container Apps用の拡張機能をインストールします。

  1. ホームディレクトリにmicroservices-marchディレクトリを作成します。(別のディレクトリ名を使用し、それに応じて手順を読み替えることもできます。)注:このチュートリアルでは、コマンドをターミナルにコピー&ペーストしやすいように、Linuxコマンドラインのプロンプトを省略しています。
mkdir ~/microservices-marchcd ~/microservices-march
  1. 次のリポジトリをフォークし、GitHub CLIまたはGUIを使用して個人のGitHubアカウントにクローンします:Microservices March platform。
    • GitHub GUIを使用する場合:
      1. ウィンドウの右上にある[Fork]をクリックし、[Owner]メニューで個人のGitHubアカウントを選択します。
        このチュートリアル用リポジトリのフォークを示すGitHub GUIのスクリーンショット
      2. アカウント名を「<your_GitHub_account>」に置き換えて、リポジトリをローカルにクローンします:
git clone https://github.com/<your_GitHub_account>/platform.gitcd platform
  • GitHub CLIを使用する場合は、次のコマンドを実行します:
gh repo fork microservices-march/platform -–clone
  1. 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"
    }
  }
]
  1. Install the containerapp拡張機能をインストールします:
az extension add --name containerapp -upgradeThe installed extension 'containerapp' is in preview.

課題1:NGINXコンテナアプリの作成とデプロイ

この最初の課題では、カナリアブルーグリーンデプロイのベースラインとして使用するアプリケーションの初期バージョンとして、NGINX Azure Container Appを作成します。Azure Container Appsは、コンテナにパッケージ化されたアプリケーションコードを、本番環境に対応したコンテナ環境で簡単に実行できるMicrosoft Azureサービスです。

  1. コンテナアプリ用の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"
}
  1. コンテナを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/
...
  1. ステップ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に置き換えます。
  2. ブルーグリーンデプロイに必要なコンテナアプリのリビジョンを有効にします:
az containerapp revision set-mode --name my-container-app --resource-group my-container-app-rg --mode multiple
"Multiple"
  1. (任意)コンテナ内の/healthエンドポイントにクエリを送信し、デプロイが正常に動作していることをテストします:
curl <ACR_URL>/healthOK

課題2:Azure Container Appのデプロイ自動化に必要な権限を設定する

この課題では、Azure Container Appsのデプロイを自動化するためのJSONトークンを取得します。

まず、Azure Container Registry(ACR)のIDを取得し、次にAzure マネージドIDのプリンシパルIDを取得します。続いて、ACR用のAzure組み込みロールをマネージドIDに割り当て、コンテナーアプリでマネージドIDを使用するように構成します。最後に、GitHub ActionsがAzureへの認証に使用する、マネージドIDのJSON資格情報を取得します。

この一連の手順は煩雑に思えるかもしれませんが、新しいアプリケーションを作成するときに一度実行するだけで済み、プロセス全体をスクリプト化できます。このチュートリアルでは、手順に慣れるために手動で実行します。

注: このデプロイ用の認証情報を作成するプロセスは、Azure固有のものです。

  1. マネージド ID のプリンシパル 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
  1. 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
  1. ACR用のAzure組み込みロールをコンテナーアプリのマネージドIDに割り当てます。その際、<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"
}
  1. 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": ""
  }
]
  1. ご利用の「AzureサブスクリプションID」を確認します。
az account show --query id --output tsv0efafl2-38ad-41w8-g49a-0ecc6723l97c
  1. GitHub Actionで使用する認証情報を含むJSONトークンを作成します。その際、<subscription_ID>をAzureサブスクリプションIDに置き換えます。出力を保存し、AZURE_CREDENTIALSという名前のシークレットの値として、GitHubリポジトリへのシークレットの追加で貼り付けます。--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ワークフローを実行します。

シークレット管理の詳しい概要については、F5ブログのMicroservices March 23第2回チュートリアル「コンテナでシークレットを安全に管理する方法」をご覧ください。

GitHubリポジトリにシークレットを追加する

アプリケーションの新しいバージョンをデプロイするには、セットアップでフォークしたGitHubリポジトリに一連のシークレットを作成する必要があります。シークレットには、チャレンジ 2で作成したマネージドIDのJSON認証情報と、新しいバージョンのNGINXイメージをAzureにデプロイするために必要な、デプロイ固有の機密パラメーターが含まれます。次のセクションでは、これらのシークレットをGitHub Actionで使用して、カナリアブルーグリーンデプロイを自動化します。

  • GitHub GUIを使用する場合:
    1. フォークしたGitHubリポジトリに移動します。
    2. [Settings > Secrets and variables > Actions]を選択します。
    3. [New repository secret]をクリックします。
    4. 指定されたフィールドに次の値を入力します:
    5. [Add secret]をクリックします。
    6. 手順3~5を3回繰り返し、表に記載されているシークレットを作成します。GUIの[Secret Name]列と[Secret Value]列の値を、それぞれ[Name]フィールドと[Secret]フィールドに入力します。3つ目のシークレットでは、<ACR_name>を、Challenge 1の手順3で記録したコンテナアプリに割り当てられた名前に置き換えます。シークレット名 シークレット値CONTAINER_APP_NAME my-container-appRESOURCE_GROUP my-container-app-rgACR_NAME <ACR_name>
    7. 次の手順に進みます:GitHub Actionsワークフローファイルの作成。
  • GitHub CLIを使用する場合:
    1. リポジトリのルートに一時ファイルを作成します。
touch ~/creds.json
  1. 任意のテキストエディターで「creds.json」を開き、「Challenge 2」のステップ6で作成したJSON認証情報をコピーします。
  2. シークレットを作成します:
gh secret set AZURE_CREDENTIALS --repo <your_GitHub_account>/platform < ~/creds.json
  1. 削除します:creds.json:
rm ~/creds.json
  1. このコマンドを繰り返し実行して、さらに3つのシークレットを作成します:
gh secret set <secret_name> --repo <your_GitHub_account>/platform
  1. 繰り返すたびに、<secret_name>を表の[シークレット名]列にあるいずれかの値に置き換えます。プロンプトが表示されたら、対応する[シークレット値]列の値を貼り付けます。3つ目のシークレットでは、<ACR_name>を、チャレンジ1のステップ3で記録したコンテナーアプリに割り当てられた名前に置き換えます。シークレット名 シークレット値CONTAINER_APP_NAME my-container-appRESOURCE_GROUP my-container-app-rgACR_NAME <ACR_name>

GitHub Actionsワークフローファイルの作成

マネージドIDとシークレットを設定したら、カナリア方式のブルーグリーンデプロイを自動化するGitHub Actionのワークフローファイルを作成できます。

注:ワークフローファイルはYAML形式で定義され、空白文字にも意味があります。以下の手順に示すインデントを必ず維持してください。

  1. Actionワークフロー用のファイルを作成します。
    • GitHub GUIを使用する場合:
      1. GitHubリポジトリに移動します。
      2. [Actions]>[New workflow]>[Skip this and set up a workflow yourself]を選択します。.
    • GitHub CLIを使用する場合は、​.github/workflowsディレクトリを作成し、main.ymlという名前の新しいファイルを作成します:
mkdir .github/workflowstouch .github/workflows/main.yml
  1. 任意のテキストエディターを使用して、ワークフローの内容をmain.ymlに追加します。最も簡単な方法は、完全なワークフローファイルに記載されている内容をコピーすることです。または、この手順で説明する一連のスニペットを追加して、ファイルを手動で作成することもできます。注:ワークフローファイルはYAML形式で定義されており、空白には意味があります。スニペットをコピーする場合は、インデントを必ず維持してください。さらに確実を期すには、作成したファイルを完全なワークフローファイルと比較してください。
    • ワークフロー名を定義します:
name: Deploy to Azure
  • mainブランチへのプッシュまたはプルリクエストが行われたときにワークフローが実行されるように設定します:
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  • In the 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
  • 新しくデプロイされたリビジョンのステージングURLを取得し、GitHub Actionを使用してAPIエンドポイント「test-deployment」ジョブを定義します。このジョブは、/health」にpingを送信して、新しいリビジョンが応答していることを確認します。ヘルスチェックが成功すると、コンテナアプリのAzure Traffic Managerが更新され、すべてのトラフィックが新しくデプロイされたコンテナに転送されます。注:「test-deployment」キーは、前の箇条書きで定義した「build-deploy」キーと同じレベルにインデントしてください。
  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"

Actionワークフローを実行

  • GitHub GUIを使用する場合:
    1. [Start commit]をクリックし、必要に応じてコミットメッセージを追加して、ダイアログボックスで[Commit new file]を選択します。新しいワークフローファイルがmainブランチにマージされ、実行が開始されます。
    2. ワークフローの進行状況を確認するには、[Actions]をクリックします。
  • GitHub CLIを使用する場合:
    1. Gitステージング領域にmain.ymlを追加します:
git add .github/workflows/main.yml
  1. ファイルをコミットします:
git commit -m "feat: create GitHub Actions workflow"
  1. 変更内容をGitHubにプッシュします:
git push
  1. ワークフローの進行状況を監視します:
gh workflow view main.yml --repo <your_GitHub_account>/platform

チャレンジ4:GitHub Actionsワークフローをテストする

この課題では、ワークフローをテストします。まず、Ingressロードバランサーの更新が成功するケースをシミュレーションし、アプリケーションが更新されたことを確認します。次に、更新が失敗するケース(内部サーバーエラーが発生するケース)をシミュレーションし、公開済みのアプリケーションが変更されていないことを確認します。

更新を正常に完了する

更新を正常に作成し、ワークフローが成功することを確認します。

  • GitHub GUIを使用する場合:
    1. 選択します:[Code > ingress > default.conf.template]。
    2. ツールチップが「default.conf.template」と表示される鉛筆アイコンを選択し、Edit this fileを編集用に開きます。
    3. ファイル末尾付近にあるlocation /healthブロックで、次のようにreturnディレクティブを変更します:
location /health {
    access_log off;
    return 200 "Successful Update!n";
}
  1. ダイアログボックスで、[Create a new branch for this commit and start a pull request]を選択し、続いて[Propose changes]を選択します。
  2. [Create pull request]をクリックして、プルリクエストのテンプレートを開きます。
  3. もう一度[Create pull request]をクリックして、プルリクエストを作成します。
  4. ワークフローの進行状況を確認するには、[Actions]をクリックします。
  5. ワークフローが完了したら、コンテナアプリの「<ACR_URL>/health」エンドポイントに移動します。ここで、<ACR_URL>は「Challenge 1」のステップ3で記録したURLです。「Successful Update!」というメッセージが表示されていることを確認します。
  6. ターミナルセッションを開始し、アプリにヘルスチェックリクエストを送信して、このメッセージを確認できます。この場合も、<ACR_URL>をチャレンジ1のステップ3で記録した値に置き換えてください:
curl <ACR_URL>/healthSuccessful Update!
  1. 次に「失敗する更新を実行」へ進みます。
  • GitHub CLIを使用する場合:
    1. 次の名前で新しいブランチを作成します:patch-1:
git checkout -b patch-1
  1. 任意のテキストエディターで「ingress/default.conf.template」を開き、ファイル末尾付近にある「location /health」ブロック内の「return」ディレクティブを、次のように変更します。
location /health {
    access_log off;
    return 200 "Successful Update!n";
}
  1. Gitのステージング領域に「default.conf.template」を追加します:
git add ingress/default.conf.template
  1. ファイルをコミットします:
git commit -m "feat: update NGINX ingress"
  1. 変更内容をGitHubにプッシュします:
git push --set-upstream origin patch-1
  1. プルリクエスト(PR)を作成します:
gh pr create --head patch-1 --fill --repo <your_GitHub_account>/platform
  1. ワークフローの進行状況を監視します:
gh workflow view main.yml --repo <your_GitHub_account>/platform
  1. ワークフローが完了したら、アプリにヘルスチェックリクエストを送信します。その際、<ACR_URL>をチャレンジ1のステップ3で記録した値に置き換えます:
curl <ACR_URL>/health
Successful Update!

失敗する更新を実行

次に、失敗する更新を作成し、ワークフローが失敗することを確認します。基本的には、「更新を成功させる」の手順を繰り返しますが、returnディレクティブには別の値を指定します。

  • GitHub GUIを使用する場合:
    1. 選択します:[Code > ingress > default.conf.template]。
    2. 左上で[main]を選択し、続いてpatch-1で終わるブランチ名を選択します。このブランチは前のセクションで作成したものです。
    3. ツールチップが「default.conf.template」と表示される鉛筆アイコンを選択し、Edit this fileを開いて編集します。
    4. 次のようにreturnディレクティブを変更します:
location /health {
    access_log off;
    return 500 "Unsuccessful Update!n";
}
  1. [-patch-1 ブランチに直接コミットする]を選択し、続いて[変更をコミット]を選択します。
  2. ワークフローの進行状況を確認するには、[Actions]を選択します。PR内のファイルが更新されると、ワークフローが再度実行されます。
  3. ワークフローが完了したら、コンテナアプリの<ACR_URL>/healthエンドポイントに移動します。ここで、<ACR_URL>はチャレンジ1のステップ3で記録したURLです。メッセージが「Successful Update!」になっていることを確認します(前回の更新が成功した後と同じです)。一見矛盾しているように思えますが、実際には今回の更新が失敗したことを示しています。更新処理の結果、ステータス500(Internal Server Error)が返され、更新は適用されませんでした。
  4. ターミナルセッションを開始してアプリにヘルスチェックリクエストを送信すると、メッセージを確認できます。この場合も、<ACR_URL>をチャレンジ1のステップ3で記録した値に置き換えてください:
curl <ACR_URL>/healthSuccessful Update!
git checkout patch-1
  1. 任意のテキストエディターで「ingress/default.conf.template」を開き、次のように再度「return」ディレクティブを変更します:
location /health {
    access_log off;
    return 500 "Unsuccessful Update!n";
}
  1. Gitステージング領域に「default.conf.template」を追加します:
git add ingress/default.conf.template
  1. ファイルをコミットします:
git commit -m "feat: update NGINX ingress again"
  1. 変更内容をGitHubにプッシュします:
git push
  1. ワークフローの進行状況を監視します:
gh workflow view main.yml --repo <your_GitHub_account>/platform
  1. ワークフローが完了したら、アプリにヘルスチェックリクエストを送信します。その際、<ACR_URL>をチャレンジ1のステップ3で記録した値に置き換えます:
curl <ACR_URL>/healthSuccessful Update!
  1. メッセージが「Successful Update!」(前回の正常な更新後と同じ)と表示されるため、矛盾しているように思えるかもしれません。しかし実際には、この表示から今回の更新が失敗したことを確認できます。更新処理の結果、ステータス500(Internal Server Error)が返され、更新は適用されませんでした。

リソースのクリーンアップ

今後料金が発生する可能性を避けるため、チュートリアルでデプロイしたAzureリソースを削除することをお勧めします。

az group delete -n my-container-app-rg -y

必要に応じて、作成したフォークも削除できます。

  • GitHub GUIを使用する場合:
    1. [Settings]をクリックします。
    2. ページの一番下までスクロールします。
    3. [Delete this repository]をクリックします。
    4. 「<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 Docsの以下の記事をご覧ください。

カナリアデプロイの第2段階(本番環境でのテスト)を試す準備ができたら、Microservices March 2022のチュートリアル「カナリアデプロイによる稼働時間とレジリエンスの向上」をF5のブログでご覧ください。このチュートリアルでは、NGINX Service Meshを使用して新しいアプリバージョンへ段階的に移行します。デプロイがまだサービスメッシュを必要とするほど複雑でない場合や、Kubernetesを使用していない場合でも、この原則はIngressコントローラーまたはロードバランサーのみを使用する、よりシンプルなデプロイにも適用できます。

マイクロサービスについてさらに学ぶには、Microservices March 2023をご覧ください。ユニット3:自動化によるマイクロサービスのデプロイの迅速化では、デプロイの自動化について詳しく学べます。


共有
タグ: F5 NGINX, Tech, 2023

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります