NGINX.COM
Web Server Load Balancing with NGINX Plus

この記事は、Microservices July 2023: マイクロサービスのStart Delivering Microservicesの方法を実行するための4つのチュートリアルの1つです。

ほとんどのプロジェクトにおいて、その成功の鍵を握るのはデプロイメントの自動化です。ただし、自動化とは、コードを展開するだけでは十分ではありません。ダウンタイムをできる限り少なく (または排除)し、障害発生時には、迅速にロールバックを実行する必要があります。カナリアデプロイメントブルーグリーンデプロイメントを組み合わせることは、新しいコードを実行可能にするための一般的なアプローチです。 この戦略には、以下の2つの手順があります。

  • 手順1: 隔離された環境でのカナリアデプロイメントによるテスト – 環境外の隔離されたノード、サーバー、またはコンテナでコードを展開し、コードが意図したとおりに動作することをテストします。
  • 手順2: 本番環境でのブルーグリーンデプロイメントによるテスト – コードがカナリアデプロイメントで動作すると想定される際に、現在のバージョンのサーバーだけではなく、本番環境に新しく作成されたサーバー(またはノードやコンテナ)にコードを移植します。移植後、本番環境のトラフィックの一部を新しいバージョンにリダイレクトして、より高い負荷下でも正常に動作するか、テストします。ほとんどの場合、最初は新しいバージョンに小さな割合(たとえば10%)のトラフィックを転送し、徐々に量を増やして、新しいバージョンがすべてのトラフィックを受信できるかどうか、確認します。通信を増加させる量は、新しいバージョンがトラフィックをどの程度処理できると想定されるかによって決めますが、ワンステップで新しいバージョンに完全に切り替えることもできます。

異なるバージョンのアプリやWebサイト間でトラフィックを分散する様々なユースケース(トラフィック分割)についてあまりご存じではない場合は、当社ブログの「高度なトラフィック管理でKubernetesの耐障害性を向上させる方法」を読んで、ブルーグリーンデプロイ、カナリアリリース、A/Bテスト、レート制限、サーキットブレーカーなどのコンセプトをご理解されることをお勧めします。このブログは Kubernetesに特化していますが、コンセプトはマイクロサービスアプリに広く適用できます。

チュートリアルの概要

このチュートリアルでは、GitHub Actionsを使って、カナリア/ブルーグリーンデプロイメントの最初の手順を自動化する方法を説明します。以下に示すチュートリアルの4つの課題では、Microsoft Azure Container Appsを使用して新しいバージョンのアプリケーションを展開し、Azure Traffic Managerを使用してトラフィックを古い環境から新しい環境へと移行します。

注:このチュートリアルではAzure Container Appsを使用していますが、コンセプトとテクニックはどのクラウドベースのホストにも適用できます。

前提条件とセットアップ

前提条件

このチュートリアルをご自身の環境で行う場合は、以下の条件が必要となります。

  • Azureアカウント。ご自分の組織のアカウントを使用した際に権限に関する問題が生じる場合があるため、組織と連動していないアカウントをご使用になることをお勧めします。
  • Azure CLI
  • GitHub CLI。ブラウザベースのGitHub GUIの代わりに(または追加で)使用します。

セットアップ

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

  1. ホームディレクトリに、microservices-marchディレクトリを作成します(別のディレクトリ名を使って、臨機応変に手順を変更することも可能です)。

    注:このチュートリアルでは、コマンドをターミナルにコピー&ペーストしやすいように、Linuxコマンドラインのプロンプトを省略しています。

    mkdir ~/microservices-march
    cd ~/microservices-march
  2. GitHub CLIまたはGUIを使って、Microservices Marchプラットフォームリポジトリを自分(個人)のGitHubアカウントにフォークおよびクローンします。

    • GitHub GUIを使用する場合は、以下を実行します。

      1. ウィンドウ右上にある「Fork」をクリックし、「Owner」メニューで、自分(個人)のGitHubアカウントを選択します。

        screenshot of GitHub GUI showing fork of the repository for this tutorial

      2. 以下のように、 <your_GitHub_account>を自分のアカウント名に置き換え、リポジトリを自分の環境にクローンします。

        git clone https://github.com/<your_GitHub_account>/platform.git
        cd platform
    • GitHub CLIを使用する場合は、以下を実行します。

      gh repo fork microservices-march/platform -–clone
  3. 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"
        }
      }
    ]
  4. 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サービスです。

  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"
    }
  2. 以下のように、コンテナを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/
    ...
  3. 手順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に置き換えます。

  4. 以下のように、ブルーグリーンデプロイメントの必要に応じて、コンテナアプリのリビジョンを有効にします。

    az containerapp revision set-mode \
        --name my-container-app \
        --resource-group my-container-app-rg \
        --mode multiple
    "Multiple"
  5. (オプション)以下のように、コンテナ内の /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特有のものです。

  1. マネージド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
  2. 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
  3. 以下のように、コンテナアプリのマネージド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"
    }
  4. 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": ""
      }
    ]
  5. AzureサブスクリプションIDを確認します。

    az account show --query id --output tsv
    0efafl2-38ad-41w8-g49a-0ecc6723l97c
  6. <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を利用する場合は、以下を実行します。

    1. フォークしたGitHubリポジトリに移動します。
    2. 「Settings」 > 「Secrets and variables」 > 「Actions」の順に選択します。
    3. New repository secret」をクリックします。
    4. 表示されたフィールドに以下の値を入力します。

      • Name – AZURE_CREDENTIALS
      • Secret – 課題2の手順6のJSONクレデンシャル
    5. Add secret」をクリックします。
    6. 手順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>
    7. GitHub Actionsワークフローファイルの作成」に進みます。
  • GitHub CLIを使用する場合は、以下を実行します。

    1. リポジトリのルートに、一時ファイルを作成します。

      touch ~/creds.json
    2. 任意のテキストエディタを使ってcreds.jsonを開き、課題2の手順6で作成したJSONクレデンシャルをコピーします。
    3. 以下のように、シークレットを作成します。

      gh secret set AZURE_CREDENTIALS --repo <your_GitHub_account>/platform < ~/creds.json
    4. 以下のように、creds.jsonを削除します。

      rm ~/creds.json
    5. 以下のように、このコマンドを繰り返して、さらに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形式ではスペースが重要です。以下の手順が示すように、必ずインデントを使用してください。

  1. Actionsのワークフロー用ファイルを作成します。

    • GitHub GUIを利用する場合は、以下を実行します。

      1. GitHubのリポジトリに移動します。
      2. 「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
  2. 任意のテキストエディタを使用して、ワークフローのテキストを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を利用する場合は、以下を実行します。

    1. Start commit」をクリックし、必要に応じてコミットメッセージを追加し、ダイアログボックスで 「Commit new file」を選択します。新しいワークフローファイルがメインブランチにマージされ、実行が開始されます。
    2. Actions」をクリックして、ワークフローの進行状況をモニタリングします。
  • GitHub CLIを利用する場合は、以下を実行します。

    1. 以下のように、main.ymlをGitステージングエリアに追加します。

      git add .github/workflows/main.yml
    2. 以下のように、ファイルをコミットします。

      git commit -m "feat: create GitHub Actions workflow"
    3. 以下のように、変更内容をGitHubにプッシュします。

      git push
    4. 以下のように、ワークフローの進捗状況をモニタリングします。

      gh workflow view main.yml --repo <your_GitHub_account>/platform

課題4:GitHub Actionsのワークフローをテストする

この課題では、ワークフローをテストします。最初に、Ingressロードバランサの正常な更新が行われるケースをシミュレートし、アプリケーションが正しく更新されたことを確認します。次に、更新に失敗するケース(内部サーバーエラーになるケース)をシミュレートし、公開したアプリケーションが変更されないことを確認します。

正常な更新を成功させる

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

  • GitHub GUIを利用する場合は、以下を実行します。

    1. 「Code」 > 「ingress」 > 「default.conf.template」の順に選択します。
    2. このファイルを編集するには、「Edit this file」で鉛筆アイコンを選択し、default.conf.templateを開きます。
    3. ファイル末尾近くのlocation /healthブロックで、以下のように、returnディレクティブを変更します。

      location /health {
          access_log off;
          return 200 "Successful Update!\n";
      }
    4. ダイアログボックスで、「Create a new branch for this commit and start a pull request」を選択し、その後、「Propose changes」を選択します。
    5. 「Create pull request」をクリックし、プルリクエストのテンプレートにアクセスします。
    6. 「Create pull request」をもう一度クリックし、プルリクエストを作成します。
    7. ワークフローの進捗を確認するため「Actions」をクリックします。
    8. ワークフローが完了したら、<ACR_URL>/healthエンドポイントのコンテナアプリに移動します。ここでの<ACR_URL>課題1の手順3でメモしたURLです。「Successful Update!」というメッセージが表示されます。
    9. ターミナルセッションを開始し、ヘルスチェックのリクエストをアプリに送信し、再度<ACR_URL>課題1の手順3でメモした値に置き換え、メッセージを確認します。

      curl <ACR_URL>/health
      Successful Update!
    10. 更新を失敗させるに進みます。
  • GitHub CLIを利用する場合は、以下を実行します。

    1. 以下のように、patch-1という名称で新しいブランチを作成します。

      git checkout -b patch-1
    2. 任意のテキストエディタで、ingress/default.conf.templateを開き、以下のように、ファイル末尾近くのlocation /healthブロックで、returnディレクティブを変更します。

      location /health {
          access_log off;
          return 200 "Successful Update!\n";
      }
    3. 以下のように、default.conf.templateをGitのステージングエリアに追加します。

      git add ingress/default.conf.template
    4. ファイルをコミットします。

      git commit -m "feat: update NGINX ingress"
    5. 変更をGitHubにプッシュします。

      git push --set-upstream origin patch-1
    6. 以下のように、プルリクエスト(PR)を作成します。

      gh pr create --head patch-1 --fill --repo <your_GitHub_account>/platform
    7. ワークフローの進捗を確認します。

      gh workflow view main.yml --repo <your_GitHub_account>/platform
    8. ワークフローが完了したら、以下のように、<ACR_URL>課題1の手順3でメモした値に置き換え、ヘルスチェックのリクエストをアプリケーションに送信します。

      curl <ACR_URL>/health
      Successful Update!

更新を失敗させる

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

  • GitHub GUIを利用する場合は、以下を実行します。

    1. 「Code」 > 「ingress」 > 「default.conf.template」の順に選択します。
    2. 左上で「main」を選択した後、patch-1で終わるブランチの名前を選択します。これは前のセクションで作成したものです。
    3. このファイルを編集するには、「Edit this file」で鉛筆アイコンを選択し、default.conf.templateを開きます。
    4. 以下のように、returnディレクティブを変更します。

      location /health {
          access_log off;
          return 500 "Unsuccessful Update!\n";
      }
    5. Commit directly to the -patch-1 branch」を選択した後、「Commit changes」を選択します。
    6. Actions」を選択し、ワークフローの進行状況を確認します。ただし、 PR内のファイルが更新されると、ワークフローが再び実行されることに注意してください。
    7. ワークフローが完了したら、<ACR_URL>/healthエンドポイントのコンテナアプリに移動します。<ACR_URL>は、課題1の手順3でメモしたURLです。

      (前回の正常な更新と同じく)「Successful Update! 」というメッセージが表示されることに注意してください。これは、一見逆に思えるかもしれませんが、実際は更新が成功していません。更新を試みた結果、ステータス500 (Internal Server Errorを意味する)となり、更新は実行されていません。

    8. ターミナルセッションを開始し、ヘルスチェックのリクエストをアプリに送信し、再度<ACR_URL>課題1の手順3でメモした値に置き換え、メッセージを確認します。

      curl <ACR_URL>/health
      Successful Update!
  • GitHub CLIを利用する場合は、以下を実行します。

    1. 以下のように、前のセクションで作成したpatch-1ブランチをチェックアウトします。

      git checkout patch-1
    2. 任意のテキストエディタで、ingress/default.conf.templateを開き、以下に示すように、returnディレクティブを再度変更します。

      location /health {
          access_log off;
          return 500 "Unsuccessful Update!\n";
      }
    3. Gitのステージング領域にdefault.conf.templateを追加します。

      git add ingress/default.conf.template
    4. ファイルをコミットします。

      git commit -m "feat: update NGINX ingress again"
    5. 変更をGitHubにプッシュします。

      git push
    6. ワークフローの進捗を確認します。

      gh workflow view main.yml --repo <your_GitHub_account>/platform
    7. ワークフローが完了したら、以下のように、<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を利用する場合は、以下を実行します。

    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ドキュメントの以下の記事をお読みください。

カナリアデプロイメントの2番目の手順(本番環境でのテスト)を試す準備ができている場合は、当社ブログのMicroservices March 2022のチュートリアル「Improve Uptime and Resilience with a Canary Deployment(カナリアデプロイメントで、動作時間と復元力を改善する)」をご確認ください。NGINXサービスメッシュを使用することで、新しいアプリのバージョンに段階的に移行できます。デプロイメントがサービスメッシュを必要とするほど複雑ではない、あるいはKubernetesを使用しない場合でも、イングレスコントローラやロードバランスのみを使用する単純なデプロイメントにおいて、段階的移行が可能となります。

マイクロサービスへの理解度をさらに深めるためには、「Microservices July」をご覧ください。Unit3:自動化でマイクロサービスのデプロイを加速するでは、デプロイメントの自動化について詳しく説明しています。

anner reading 'Microservices March 2023: Sign Up for Free, Register Today'

Hero image
NGINXクックブック 設定レシピ集(日本語版)

待望の【O'Reilly】NGINX Cookbook日本語版がついに完成!NGINXクックブックは、NGINXを最大限に活用する方法を解説しています。



著者について

Christopher Harrison

Enterprise Advocate

About F5 NGINX

F5 NGINXについて
F5, Inc.は、人気のオープンソースプロジェクト「NGINX」を支援しています。NGINXはモダンアプリケーションを開発・構築するためのテクノロジースイートを提供しています。NGINXとF5製品との併用で、コードからユーザーまでの広範なアプリケーション領域をサポートし、マルチクラウドアプリケーションサービスとしてNetOpsとDevOps間の課題を解決します。

詳しくはnginx.co.jpをご覧ください。Twitterで@nginxをフォローして会話に参加することもできます。