NGINX.COM
Web Server Load Balancing with NGINX Plus

本文是“Microservices June 微服务之月 2023”系列教程的延伸阅读之一,旨在帮助您将概念付诸实践。该系列教程包括:

该系列教程包括:

自动化部署对于大多数项目的成功而言至关重要。但是,仅仅部署代码还不够,您还需确保减少(或消除)停机时间,并能够在发生故障时迅速回滚。结合使用灰度部署和蓝绿部署是确保新代码成功部署的一种常见方法。该策略包括两个步骤:

  • 第一步:利用灰度部署进行单独测试——将您的代码部署到环境外部的单独节点、服务器或容器上,并进行测试以确保代码按预期运行。
  • 第二步:利用蓝绿部署在生产环境中进行测试——假设代码在灰度部署中正常运行,将它移植到您生产环境中的新建服务器(或节点或容器),与支持当前版本的服务器并列运行。然后将一部分生产流量重定向到新版本,以测试它能否在更高负载下继续良好运行。首先将一小部分(例如 10%)的生产流量定向到新版本,然后逐步增加,直至新版本接收所有流量。增量的大小取决于您对新版本的流量处理能力的信心;您甚至可以一步彻底转入新版本。

I如果您尚不熟悉在不同版本的应用或网站之间分配流量(流量分割)的各种用例,请参阅我们的博文《如何通过高级流量管理提高 Kubernetes 的弹性》,以获得对蓝绿部署、灰度发布、A/B 测试、速率限制、断路等的概念性理解。虽然本文主要针对 Kubernetes,但这些概念广泛适用于微服务应用。

 

教程概述

在本教程中,我们将展示如何使用 GitHub Actions 自动执行灰度蓝绿部署的第一步。在本教程的四个挑战中,您将使用 Microsoft Azure Container Apps 来部署新版本的应用,然后使用 Azure 流量管理器将流量从旧环境转移到新环境:

注:虽然本教程使用 Azure Container Apps,但相关概念和技术可应用于任何基于云的主机。

 

准备工作和设置

准备工作

如果您想在自己的环境中学习本教程,则需要:

  • 一个 Azure 帐户。我们建议您使用一个与您的企业没有关联的帐户,因为如果您使用企业帐户,可能会遇到权限问题。
  • Azure CLI
  • GitHub CLI,如果您想用它来代替(或补充)基于浏览器的 GitHub GUI。

设置

创建并配置必要的基础资源。创建分支(Fork)并克隆本教程所用的代码库,登录 Azure CLI,并为 Azure Container App 安装扩展插件。

  1. 在您的主目录下,创建 microservices-march 目录。(您也可以使用其他目录名称,相应修改指令即可)。

    注:本教程中省略了 Linux 命令行提示符,以便您将命令复制和粘贴到终端。

    mkdir ~/microservices-march
    cd ~/microservices-march
  2. 使用 GitHub CLI 或 GUI Fork 为 Microservices March 平台代码库创建分支(Fork),并克隆到您的个人 GitHub 帐户。

    • 如果使用 GitHub GUI:

      1. 在窗口的右上角点击 Fork,并在 Owner(所有者)菜单中选择您的个人 GitHub 帐户。

      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 容器应用

在首个挑战中,您需要创建一个 NGINX Azure 容器应用作为应用初始版本,用作灰度蓝绿部署基线。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. 在第二步的输出结果中,找到您在 Azure 容器注册表 (ACR) 中创建的容器应用的名称和 URL。在示例输出结果中,它们以橙色高亮显示。在整个教程中,您需要用输出结果中的值(不同于第二步中的示例输出结果)来替换命令中的指定变量:

    • 容器应用的名称——在 image.registry 键中,是指 .azurecr.io 前面的字符串。在第二步的示例输出结果中,它是 cac085021b77acr

      在随后的命令中,用这个字符串替换 <ACR_name>

    • 容器应用的 URL——以 Container app created 开头的一行中的 URL。在第二步的示例输出结果中,它是 https://my-container-app.delightfulmoss-eb6d59d5.westus.azurecontainerapps.io/

      在随后的命令中,用这个 URL 替换 <ACR_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:设置权限以支持 Azure 容器应用部署自动化

在这个挑战中,您需要获取 JSON 令牌,以自动执行 Azure 容器应用部署。

首先,您需要获取用于 Azure 容器注册表 (ACR) 的 ID 以及您的 Azure 托管身份的主 ID。然后,将用于 ACR 的内置 Azure 角色分配给托管身份,并将容器应用配置为使用该托管身份。最后,获取托管身份的 JSON 凭证,GitHub Action 将使用该凭证向 Azure 进行身份验证。

虽然这一系列步骤可能看起来很繁琐,但您只需在新建应用时执行一次,便可将该流程完全脚本化。在本教程中,您可以通过手动执行这些步骤加深印象。

注:这个为部署创建凭证的流程仅限于 Azure。

  1. 查询您托管身份的主 ID。它显示在输出结果的 PrincipalID 栏(为方便阅读,输出结果分成了两行)。您将用这个值替换第三步中的 <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 第三步中记录的名称。您将用这个值替换下一步中的 <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. 将用于 ACR 的内置 Azure 角色分配给容器应用的托管身份,将 <managed_identity_principal_ID> 替换为您在第一步中获得的托管身份,并将 <ACR_resource_ID> 替换为您在第二步中获得的资源 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 中提取镜像时使用的托管身份,并将 <ACR_name> 替换为您在挑战 1 的第三步中记录的容器应用名称(在上面第二步中也用过):

    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. 创建一个 JSON 令牌,其中包含 GitHub Action 要使用的凭证,然后将 <subscription_ID> 替换为您的 Azure 订阅 ID。保存输出结果,在“将密钥添加到您的 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 工作流

有关密钥管理的详细介绍,请参阅我们的博文——Microservices June 23 的第二篇教程《如何安全地管理容器中的密钥》。

将密钥添加到您的 GitHub 代码库中

为了部署新版本的应用,您需要在设置中 fork 过的 GitHub 代码库中创建一系列密钥。这些密钥是在挑战 2 中创建的托管身份的 JSON 凭证,以及将新版本的 NGINX 镜像部署到 Azure 所需的一些敏感的部署参数。在下一部分中,您将在 GitHub Action 中使用这些密钥实现灰度蓝绿部署自动化。

  • 如果使用 GitHub GUI:

    1. 导航到您的 fork 过的 GitHub 代码库。
    2. 选择 Settings(设置)> Secrets and variables(密钥和变量)> Actions
    3. 点击 New repository secret(新代码库密钥)
    4. 在指定字段中输入以下值:

      • 名称——AZURE_CREDENTIALS
      • 密钥——挑战 2 第六步中的 JSON 凭证
    5. 点击 Add secret(添加密钥)
    6. 重复执行第三步到第五步三次,创建表格中所列的密钥。分别将 Secret Name(密钥名称)Secret Value(密钥值)列中的值输入到 GUI 的 Name(名称)Secret(密钥)字段。对于第三个密钥,将 <ACR_name> 替换为您在挑战 1 第三步中记录的分配给容器应用的名称。

      密钥名称 密钥值
      CONTAINER_APP_NAME my-container-app
      RESOURCE_GROUP my-container-app-rg
      ACR_NAME <ACR_name>
    7. 继续创建 GitHub Action 工作流文件
  • 如果使用 GitHub CLI:

    1. 在您代码库的根目录下,创建一个临时文件。

      touch ~/creds.json
    2. 使用您常用的文本编辑器,打开 creds.json 并将您在挑战 2 第六步中创建的 JSON 凭证复制到其中。
    3. 创建密钥:

      gh secret set AZURE_CREDENTIALS --repo <your_GitHub_account>/platform < ~/creds.json
    4. 删除 creds.json

      rm ~/creds.json
    5. 重复运行这个命令,再创建三个密钥:

      gh secret set <secret_name> --repo <your_GitHub_account>/platform

      每次重复操作时,将 <secret_name> 替换为表格内 Secret Name(密钥名称)列中的一个值。根据提示,粘贴 Secret Value(密钥值)列中的相关值。对于第三个密钥,将 <ACR_name> 替换为您在挑战 1 第三步中记录的分配给容器应用的名称。

      密钥名称 密钥值
      CONTAINER_APP_NAME my-container-app
      RESOURCE_GROUP my-container-app-rg
      ACR_NAME <ACR_name>

创建 GitHub Action 工作流文件

有了托管身份和密钥,您可为 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/workflows
      touch .github/workflows/main.yml
  2. 使用您常用的文本编辑器,将工作流的文本添加到 main.yml 中。最简单的方法是直接复制完整工作流文件中显示的文本。或者,您也可以通过添加此步骤中注释的代码段来手动创建文件。

    注:工作流文件以 YAML 格式定义,其中空格是有意义的。复制代码段时,请务必保留缩进(保险起见,请对您的文件与完整工作流文件进行比较)。

    • 定义工作流的名称:

      name: Deploy to Azure
    • 将工作流配置为在向主分支发出 push 或 pull 请求时运行:

      on:
        push:
          branches:
            - main
        pull_request:
          branches:
            - main
    • jobs 部分,定义 build-deploy 作业,该作业会检测代码、登录 Azure 并将应用部署到 Azure 容器应用中:

      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: |
                # 手动添加 containerapp 扩展
                az extension add --name containerapp --upgrade
                # 使用 Azure CLI 来部署更新
                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 Action 对 API 端点 /health 进行 ping 操作,以确保新修订版本可正常响应。 如果健康检查成功,容器应用上的 Azure 流量管理器会进行更新,将所有流量都定向到新部署的容器。

      注:请确保 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: |
                # 手动添加 containerapp 扩展
                az extension add --name containerapp --upgrade
      
                # 获取最新部署修订版本的名称
                REVISION_NAME=`az containerapp revision list -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --query "[].name" -o tsv | tail -1`
                # 获取最新部署修订版本的 fqdn
                REVISION_FQDN=`az containerapp revision show -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --revision "$REVISION_NAME" --query properties.fqdn -o tsv`
                # 将值存储在 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 触达端点
              with:
                url: "https://${{ env.REVISION_FQDN }}/health" # 预发布端点
      
            - 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: |
          # 手动添加 containerapp 扩展
          az extension add --name containerapp -upgrade
       
          # 使用 Azure CLI 来部署更新
          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: |
          # 为 Azure CLI 安装 containerapp 扩展
          az extension add --name containerapp --upgrade
          # 获取最新部署修订版本的名称
          REVISION_NAME=`az containerapp revision list -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --query "[].name" -o tsv | tail -1`
          # 获取最新部署修订版本的 fqdn
          REVISION_FQDN=`az containerapp revision show -n ${{ secrets.CONTAINER_APP_NAME }} -g ${{ secrets.RESOURCE_GROUP }} --revision "$REVISION_NAME" --query properties.fqdn -o tsv`
          # 将值存储在 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 触达端点
        with:
          url: "https://${{ env.REVISION_FQDN }}/health" # 预发布端点

      - 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(提交新文件)。新工作流文件被合并到主分支并开始执行。
    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 Action 工作流

在这个挑战中,您将测试工作流。首先,您需要模拟一次对 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";
      }
    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 第三步中记录的 URL。注意返回的消息是 Successful Update!
    9. 您可以确认该消息,具体方式是启动终端会话并向应用发送健康检查请求,再次将 <ACR_URL> 替换为您在 挑战 1 第三步中记录的值:

      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 第三步中记录的值:

      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";
      }
    5. 选择 Commit directly to the -patch-1 branch(直接提交到 -patch-1 分支),然后 Commit changes(提交更改)
    6. 点击 Actions 以监控工作流的进度。注意,当 PR 中的文件被更新时,工作流会再次执行。
    7. 当工作流完成时,导航到位于 <ACR_URL>/health 端点的容器应用,其中 <ACR_URL> 是您在 挑战 1 第三步中记录的 URL。

      注意返回的消息是 Successful Update! (与上一次更新后显示的消息相同——成功更新)。虽然这似乎自相矛盾,但事实上它证实了此次更新失败——更新尝试生成了状态码 500(表示内部服务器错误),未能成功应用。

    8. 您可以确认该消息,具体方式是启动终端会话并向应用发送健康检查请求,再次将 <ACR_URL> 替换为您在挑战 1 第三步中记录的值:

      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. default.conf.template 添加到 Git 暂存区:

      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 第三步中记录的值:

      curl <ACR_URL>/health
      Successful Update!

      结果看似自相矛盾,返回的消息是 Successful Update!(与上一次更新后显示的消息相同——成功更新)。虽然这似乎自相矛盾,但事实上它证实了此次更新失败——更新尝试导致了状态码 500(代表内部服务器错误),未能成功应用。

 

资源清理

如果您希望删除在操作本教程期间部署的 Azure 资源,以避免任何潜在的费用,输入下面一行代码:

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

您也可以按需删除所创建的 fork。

  • 如果使用 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 Action 来执行微服务应用的灰度蓝绿部署。请查阅 GitHub 文档中的以下文章,继续探索并增进有关 DevOps 的知识:

如果您准备尝试灰度部署的第二步(在生产环境中测试),请参阅我们的博文——Microservices June 2022 教程《NGINX 实操教程:通过灰度部署改善正常运行时间和弹性》。该教程介绍了如何使用 NGINX Service Mesh 逐步过渡到新的应用版本。即使您的部署尚未复杂到需要使用服务网格的程度,或者您并未使用 Kubernetes,这些原则同样适用于只使用 Ingress Controller(Ingress 控制器)或负载均衡器的较简单部署。

如欲进一步了解有关微服务的更多内容,请观看 Microservices June 2023 第三单元:利用 Docker、Kubernetes 和 Gitlab实现微服务自动化部署和 CI/CD 的课程录像,详细了解部署自动化的相关概念。

Hero image
免费 O'Reilly 电子书:
《NGINX 完全指南》

更新于 2022 年,一本书了解关于 NGINX 的一切

关于作者

Christopher Harrison

企业推广大使

关于作者

朱炜良

NGINX 资深架构师

关于 F5 NGINX

F5, Inc. 是备受欢迎的开源软件 NGINX 背后的商业公司。我们为现代应用的开发和交付提供一整套技术。我们的联合解决方案弥合了 NetOps 和 DevOps 之间的横沟,提供从代码到用户的多云应用服务。访问 nginx-cn.net 了解更多相关信息。