65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Microsoft Azure 将 ASP.NET Core Web 应用程序构建并部署为 Docker 容器 - 第 2 部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2019 年 4 月 24 日

CPOL

7分钟阅读

viewsIcon

5840

在本文中,我们将设置一个 Microsoft Azure DevOps 构建管道,以自动化本系列第一篇文章中手动完成的任务。

引言

这是本系列的第二篇文章。在这里,我们将设置一个 Microsoft Azure DevOps 构建管道,以自动化本系列第一篇文章中手动完成的任务。每次我们将更改推送到 master 分支时,都会触发构建以构建我们的应用程序,然后构建 Docker 镜像并将其推送到 Docker Hub。

如果您一直关注,那么您应该拥有

  • 一个 GitHub 存储库
  • 一个正常运行的 ASP.NET Core Web 应用程序(或类似应用程序)
  • 应用程序的 Docker 镜像
  • 一个正在运行的容器来本地托管您的应用程序

系列共三部分

Docker 注册表

首先,您需要在 Docker Hub 上设置一个帐户。之后,创建一个存储库,您可以在其中存储应用程序的 Docker 镜像。

您已经有一个在之前步骤中构建的 Docker 镜像,它运行良好。所以现在,您可以使用存储库名称标记该镜像。但是,在推送镜像之前,运行在本地机器上的 Docker 客户端需要连接到 Docker Hub 帐户。

以下命令将本地镜像标记为 Docker Hub 存储库,授权 Docker 客户端,最后将镜像推送到 Docker Hub。

$ docker tag <image-name> <namespace>/<repository>:<tag> 

// example
$ docker tag webapp quickdevnotes/webapp:v1

// login to your Docker Hub account
$ docker login 
username:
password:
// push the to Docker Hub
$ docker push quickdevnotes/webapp:v1
引用

请注意,我使用的是 Docker Hub 上的公共存储库。如果您使用的是私有存储库,那么您必须首先使用 docker login 命令登录,然后推送镜像。否则,推送将因授权错误而失败。

Azure DevOps - 项目

现在进入有趣的部分。要开始使用 Azure DevOps 管道,您首先需要一个用户帐户。如果您已经有一个帐户,那太好了,您可以立即开始,或者您可以在此处注册。

登录后,它会要求您创建一个组织以及您希望托管项目的位置。将其命名为您喜欢的任何名称,并选择适合您需求的区域

Create organization at Azure DevOps

接下来,我们必须在组织下创建一个项目。从右上角选择 +创建项目,并提供所需的详细信息。

Create a project in Azure DevOps

从“高级”部分,本系列的目的不需要任何东西。所以,我将选择权留给您。

持续集成(构建管道)

终于到了自动化手动步骤的时候了。从 管道 > 构建 中选择 新建管道

您的代码在哪里?

Azure 管道首先需要连接到您的应用程序代码存储库。因此,在 连接 选项卡上,选择 GitHub,连接到您的 GitHub。

Select code source for Build Pipeline

之后,您将收到 OAuth 身份验证提示,以授权 Azure Pipelines 访问 GitHub 存储库。根据需要授予授权并提供凭据。

Authorize Azure Pipelines

选择存储库

授权完成后,您可以看到 GitHub 帐户中的存储库列表。从存储库列表中,选择您的应用程序存储库,然后会提示 安装 Azure Pipelines。使用“仅选择存储库”选项,然后从下拉列表中选择您的应用程序存储库。

Select application repository

如果您想为所有当前和未来的存储库安装 Azure Pipelines,请选择“所有存储库”并单击安装。

Install Azure Pipelines

azure-pipelines.yml

Azure 管道足够智能,可以分析您的应用程序存储库并提供一个基本的 azure-pipelines.yml 文件。这个 yml 文件位于您的 GitHub 存储库的根目录,并被 Azure 构建管道用于执行特定任务,例如构建应用程序、执行测试、构建 Docker 镜像等等。

这是我的构建管道的 azure-pipelines.yml 文件。我知道,它可能令人不知所措;但当我们详细讨论每个任务后,一切都会变得清晰。

trigger:
- master

pool:
  vmImage: 'Ubuntu-16.04'

variables:
  imageName: 'quickdevnotes/webapp:$(build.buildNumber)'

steps:
- script: dotnet test WebApp.Tests/WebApp.Tests.csproj --logger trx
  displayName: Run unit tests
- task: PublishTestResults@2
  condition: succeededOrFailed()
  inputs:
    testRunner: VSTest
    testResultsFiles: '**/*.trx'
- task: Docker@1
  displayName: Build an image
  inputs:
    command: Build an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always
- task: Docker@1
  displayName: Push an image
  inputs:
    command: Push an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always
引用

请注意,为您的构建管道生成的文件将与您在此处看到的文件不同。这是因为我已经使用实现我们最终目标所需的任务更新了该文件。

CI 任务 - 近距离观察

让我们仔细看看上面构建文件中定义的任务。我们将保持在一个较高的级别,只是为了让本系列的事情简单化。

trigger:
- master

触发器指定推送哪个分支将触发持续集成管道运行。在我的例子中,它是 master 分支。

如果您想使用不同的分支,只需更改分支的名称。如果我们不指定任何分支,则推送到任何分支都将触发构建。

pool:
vmImage: 'Ubuntu-16.04'

以上几行说明了管道的作业/任务使用哪个代理池。

variables:
imageName: 'quickdevnotes/webapp:$(build.buildNumber)'

我们使用变量部分来声明我们想在管道中使用的任何变量。例如,我在这里创建一个变量 imageName,它将设置为我想要创建的 Docker 镜像的名称。

持续集成最佳实践建议使用 $(build.buildNumber) 来标记您的 Docker 镜像。因为这使得更新或回滚任何更改变得容易。

- script: dotnet test WebApp.Tests/WebApp.Tests.csproj --logger trx
  displayName: Run unit tests
- task: PublishTestResults@2
  condition: succeededOrFailed()
  inputs:
    testRunner: VSTest
    testResultsFiles: '**/*.trx'

我还为我的应用程序添加了一些基本的单元测试。通过上述脚本,这些测试将在每次运行构建时执行。我们还可以从这些测试运行中获取测试报告。

- task: Docker@1
  displayName: Build an image
  inputs:
    command: Build an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always
- task: Docker@1
  displayName: Push an image
  inputs:
    command: Push an image
    containerregistrytype: Container Registry
    dockerRegistryEndpoint: DockerHub
    dockerFile: Dockerfile
    imageName: $(imageName)
    imageNamesPath: 
    restartPolicy: always

上述两个任务中的第一个任务,使用存储库根目录中可用的 Dockerfile 构建 Docker 镜像。构建镜像后,第二个任务将该镜像推送到 Docker Hub 上的存储库。

引用

要了解有关不同任务和可用选项的更多信息,请参阅文档

为了将镜像推送到您的 Docker Hub 存储库,运行在构建代理上的 Docker 客户端需要首先获得授权。这与您手动推送镜像时所做的类似。

- task: Docker@1
...
    dockerRegistryEndpoint: DockerHub
...

dockerRegistryEndpoint 设置为一个 docker 注册表服务连接,该连接包含 Docker Hub 帐户的凭据,并用于授权。接下来让我们设置它。

Docker 注册表服务连接

从导航窗格的左下方,选择 项目设置。然后在 管道 下,选择 服务连接,您应该会看到您的 GitHub 连接。

要连接 Docker 注册表,单击 新建服务连接,然后从列表中选择 Docker 注册表

Docker Registry Service Connection

在下一个对话框窗口中,选择 Docker Hub 作为注册表类型,并将 DockerHub(必须与构建任务中的 dockerRegistryEndpoint 相同)设置为连接名称。

然后,提供您的 Docker Hub 帐户的 Docker ID 和密码。电子邮件是可选的。请确保选中“允许所有管道使用此连接”。

Docker Registry Service Connection Details

您可以使用“验证此连接”链接来验证连接。点击“确定”,我们就可以开始了。

测试构建管道

我相信,到目前为止,您已经掌握了足够的信息来自定义您的持续集成管道。好的,现在是时候测试它是否符合我们的预期了。

转到 管道 > 构建,然后选择 队列 以排队构建。如果您没有遇到任何错误,您应该会看到正在进行的构建。这是我的构建管道成功构建后的输出

Successful build, triggered manually

管道中的最后一个任务已成功将新构建的 Docker 镜像推送到 Docker Hub。请注意 image 标签,它等于上图中的构建编号

Image pushed to Docker Hub

为了进行最后一次测试,请更改应用程序代码中的某些内容并将其推送到 master 分支。这将触发构建,您将看到提交消息作为构建标题

Build Pipeline triggered by push to master branch

请注意构建描述如何告诉您构建触发器,这证明它不是手动触发器。

恭喜!!

结论

在本文中,我们已经成功设置了一个使用 Microsoft Azure DevOps 的持续集成构建管道。从构建 .NET Core Web 应用程序到设置 CI 管道,我们已经完成了一半。

接下来,我们将设置发布管道,将我们的应用程序作为 Docker 容器部署到 Azure Web App Service。这将非常有趣。

© . All rights reserved.