练习 - 实现蓝绿部署模式
在使用 Azure Pipelines 创建多阶段管道中,你构建了一个基本部署管道,它将 Web 应用程序部署到开发、测试和过渡阶段中的 Azure 应用服务。
在此,你通过在过渡期间应用蓝绿部署模式来添加到该工作流。
为此,需要:
- 将一个部署槽位添加到与过渡环境对应的应用服务实例。
- 向管道添加一个任务来交换部署槽位。
添加部署槽
在这里,你要将一个部署槽位添加到与过渡环境对应的应用服务实例。
默认情况下,每个应用服务实例都提供一个名为“生产”的默认槽。 在上一部分设置管道时,你已部署到生产槽位。
一个应用服务实例可以有多个槽。 在这里,需要将部署槽位添加到与过渡环境对应的应用服务实例。 该部署槽位被命名为“交换”。
若要添加槽:
转到 Azure 门户并登录。
在菜单上,选择“Cloud Shell”。 出现提示时,选择 Bash 体验。
运行以下命令,来获取与过渡环境对应的应用服务实例的名称,并将结果存储在名为
staging
的 Bash 变量中。staging=$(az webapp list \ --resource-group tailspin-space-game-rg \ --query "[?contains(@.name, 'tailspin-space-game-web-staging')].{name: name}" \ --output tsv)
--query
参数会使用 JMESPath,它是 JSON 的查询语言。 该参数选用name
字段包含“tailspin-space-game-web-staging”的应用服务实例。打印
staging
变量来验证你获取的名称是否正确。echo $staging
下面是输出示例:
tailspin-space-game-web-staging-1234
运行以下命令,将名为“交换”的槽添加到过渡环境中。
az webapp deployment slot create \ --name $staging \ --resource-group tailspin-space-game-rg \ --slot swap
运行以下命令,列出部署槽位的主机名。
az webapp deployment slot list \ --name $staging \ --resource-group tailspin-space-game-rg \ --query [].hostNames \ --output tsv
结果类似于以下输出:
tailspin-space-game-web-staging-25391-swap.azurewebsites.net
请记下此主机名供稍后使用。
(可选)在浏览器中转到你的网站。 你会看到默认主页,因为你尚未向此槽部署代码。
默认情况下,可从 Internet 访问部署槽位。 实际上,你可配置这样一个 Azure 虚拟网络,它将你的交换槽置于不可从 Internet 路由且仅供你的团队访问的网络中。 仍可从 Internet 访问生产槽位。
在过渡环境中交换部署槽位
在这里,你执行 AzureAppServiceManage@0 任务来交换你在过渡环境中的部署槽位。
你可执行此任务来启动、停止或删除槽。 你也可通过它来安装网站扩展或在应用服务上启用持续监视。
在 Visual Studio Code 中,使用以下代码修改 azure-pipelines.yml:
提示
可替换整个文件,也可仅更新突出显示的部分。
trigger: - '*' variables: buildConfiguration: 'Release' stages: - stage: 'Build' displayName: 'Build the web application' jobs: - job: 'Build' displayName: 'Build job' pool: vmImage: 'ubuntu-20.04' demands: - npm variables: wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot' dotnetSdkVersion: '6.x' steps: - task: UseDotNet@2 displayName: 'Use .NET SDK $(dotnetSdkVersion)' inputs: version: '$(dotnetSdkVersion)' - task: Npm@1 displayName: 'Run npm install' inputs: verbose: false - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)' displayName: 'Compile Sass assets' - task: gulp@1 displayName: 'Run gulp tasks' - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt' displayName: 'Write build info' workingDirectory: $(wwwrootDir) - task: DotNetCoreCLI@2 displayName: 'Restore project dependencies' inputs: command: 'restore' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Build the project - $(buildConfiguration)' inputs: command: 'build' arguments: '--no-restore --configuration $(buildConfiguration)' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Publish the project - $(buildConfiguration)' inputs: command: 'publish' projects: '**/*.csproj' publishWebProjects: false arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)' zipAfterPublish: true - publish: '$(Build.ArtifactStagingDirectory)' artifact: drop - stage: 'Dev' displayName: 'Deploy to the dev environment' dependsOn: Build jobs: - deployment: Deploy pool: vmImage: 'ubuntu-20.04' environment: dev variables: - group: Release strategy: runOnce: deploy: steps: - download: current artifact: drop - task: AzureWebApp@1 displayName: 'Azure App Service Deploy: website' inputs: azureSubscription: 'Resource Manager - Tailspin - Space Game' appName: '$(WebAppNameDev)' package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip' - stage: 'Test' displayName: 'Deploy to the test environment' dependsOn: Dev jobs: - deployment: Deploy pool: vmImage: 'ubuntu-20.04' environment: test variables: - group: 'Release' strategy: runOnce: deploy: steps: - download: current artifact: drop - task: AzureWebApp@1 displayName: 'Azure App Service Deploy: website' inputs: azureSubscription: 'Resource Manager - Tailspin - Space Game' appName: '$(WebAppNameTest)' package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip' - stage: 'Staging' displayName: 'Deploy to the staging environment' dependsOn: Test jobs: - deployment: Deploy pool: vmImage: 'ubuntu-20.04' environment: staging variables: - group: 'Release' strategy: runOnce: deploy: steps: - download: current artifact: drop - task: AzureWebApp@1 displayName: 'Azure App Service Deploy: website' inputs: azureSubscription: 'Resource Manager - Tailspin - Space Game' deployToSlotOrASE: 'true' resourceGroupName: 'tailspin-space-game-rg' slotName: 'swap' appName: '$(WebAppNameStaging)' package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip' - task: AzureAppServiceManage@0 displayName: 'Swap deployment slots' inputs: azureSubscription: 'Resource Manager - Tailspin - Space Game' resourceGroupName: 'tailspin-space-game-rg' webAppName: '$(WebAppNameStaging)' sourceSlot: 'swap' targetSlot: 'production' action: 'Swap Slots'
请注意以下变化:
AzureWebApp@1
任务现在指定以下值:deployToSlotOrASE
;如果设置为true
,则部署到现有部署槽位。resourceGroupName
指定资源组的名称。 当deployToSlotOrASE
为true
时,必须提供此值。slotName
指定部署槽位的名称。 在这里,你部署到名为“交换”的槽。
- 新任务
AzureAppServiceManage@0
交换部署槽位。sourceSlot
和targetSlot
指定要交换的槽。action
指定要执行的操作。 回忆一下,你可执行此任务来启动、停止或删除槽。 在这里,“交换槽位”指定要交换源槽和目标槽。
此配置始终部署到交换槽位。 随后,它交换生产槽位和交换槽位。 交换过程可确保生产槽位指向更新的部署。
在集成终端中,将 azure-pipelines.yml 添加到索引中。 提交更改,然后将分支推送到 GitHub。
提示
在运行这些 Git 命令之前,请保存 azure-pipelines.yml。
git add azure-pipelines.yml git commit -m "Swap deployment slots" git push origin blue-green
在 Azure Pipelines 中,跟踪生成的每个步骤。
注意
如果遇到以下错误 ...'staging' slot did not respond to http ping. (CODE: 417)
,请尝试重启应用服务。 如果问题仍然存在,请重置槽的自动交换。
(可选)在浏览器中,转到与每个阶段对应的 URL。
尽管尚未更改网站,但会看到 Space Game 网站已成功部署到每个应用服务环境。