ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(二)

By | 2018年10月9日

上文中我介绍了ASP.NET Core应用程序容器化时需要注意的几个问题,并给出了一个案例应用程序:tasklist。今天接着上文的内容,继续了解一下如何使用Azure DevOps进行ASP.NET Core应用程序的持续集成。为了便于讨论,本文会将持续集成(Continuous Integration)缩写为CI,而将持续部署(Continuous Deployment)缩写为CD。

Azure DevOps前身是Visual Studio Team Services(VSTS),从2018年9月10日开始,VSTS改名为Azure DevOps,原来VSTS所提供的服务也作了相应的调整。有关Azure DevOps的介绍,可以参考https://azure.microsoft.com/en-us/blog/introducing-azure-devops/

容器化应用程序的CI/CD流程

下图展示了基于微软技术架构的容器化应用程序的CI/CD流程:

image

大致流程如下:

  1. 开发人员通过Visual Studio Team Services Backlog(也就是最新的Azure Boards)获取一些开发任务
  2. 开发人员使用Visual Studio进行应用程序开发
  3. 开发的代码保存在Visual Studio Team Services Git(也就是最新的Azure Repos)
  4. Visual Studio Team Services CI(也就是最新的Azure Pipelines)从代码库获取代码,进行编译和持续集成
  5. 编译产生的容器被推送到Azure Container Registry
  6. Visual Studio Team Services CD(也就是最新的Azure Pipelines)触发持续部署,从Azure Container Registry获取容器镜像,然后部署到Azure Container Service中(这里使用托管的Kubernetes服务作为例子)
  7. Azure Application Insights对运行的应用程序进行跟踪分析,并将结果反馈给开发人员
  8. 开发人员将结果记录到Visual Studio Team Services Backlog(也就是最新的Azure Boards)中

这个过程还是比较容易理解的。图片来自https://azure.microsoft.com/en-us/solutions/architecture/cicd-for-containers/。对于tasklist而言,我所采用的持续集成/持续部署方案跟上图流程差不多,所不同的是,我没有使用Azure Repos,而是使用众所周知的GitHub,我也没有使用Azure Container Registry,而是使用Docker Hub。接下来,我们一起了解一下Azure DevOps Pipeline持续集成的配置过程。

基于Azure DevOps为tasklist搭建持续集成环境

首先使用你的微软账号(Microsoft Account)登录Azure DevOps,默认还是会进入经典的VSTS界面,此时点击屏幕右上角的大头贴图标,选择Preview features:

image

然后在Preview features中打开New Navigation选项即可进入Azure DevOps的新界面:

image

接下来,我们可以点击界面右上角的Create project按钮来创建一个新的项目。在创建新项目的界面中,输入项目名称和描述,然后决定是否公开该项目,之后在Advanced部分可以选择版本控制方案(Git或者Team Foundation Version Control),并且选择一个开发流程。这里我将项目命名为tasklist-demo,版本控制方案使用Git,开发流程就选择Agile(其实在我们的案例中,这并不重要)。一切就绪之后,点击Create按钮创建项目。

image

项目创建成功之后,就自动进入了如上图所示的项目仪表板(Dashboard),此时我们可以在Boards里创建一些开发任务,然后通过Repos界面来初始化我们的代码库。不过,这两个步骤我们都不需要做,因为我们的代码已经在GitHub中了,我们可以直接进入Pipelines,定义我们的项目构建过程。

  1. 在Pipelines项目下,点击Builds,然后点击New pipeline按钮。在创建Build Pipeline的第一步,需要选择代码来源。Azure DevOps提供各种选择:Azure Repos Git、GitHub、GitHub Enterprise、Subvision、Bitbucket Cloud以及External Git。对于tasklist而言,我们选择使用GitHub。此时,如果你还没有创建GitHub连接,则需要新建一个。如下图指定GitHub连接的名称,然后通过OAuth或者GitHub访问token进行安全认证:

    image

  2. 在认证成功后,即可选择需要编译的代码库,并指定需要编译的代码所在的分支(Branch)。在一切就绪后,点击Continue按钮继续:

    image

  3. 接下来,在Select a template页面中,点击Empty job来创建一个空的构建任务,当然,也可以根据需要,在预定的构建模板中进行选择

    image

  4. 在新建的Buid Pipeline中,可以看到,所有操作的第一步就是获取源代码,这一步已经在上面定义好了,不过还可以在这个界面中进行一些高级设置,比如可以指定在签出代码时,将submodule也同时签出
  5. 我们需要关注的就是Agent Job,一个Build Pipeline中,可以包含多个Agent Job,也就是执行过程需要Build Agent支持的Job;也可以包含多个Agentless Job,也就是执行过程不需要Build Agent支持的Job。Agent Job的执行需要依赖某种环境,比如托管的Linux环境,或者是装有VS2017的Windows环境。而Agentless Job的执行则不需要这样的环境,比如,调用RESTful API,或者设置一个定时器,延迟后续Job的执行等。对于tasklist而言,我们需要一个Linux的环境来执行Docker容器构建,因此,可以选择Hosted Ubuntu 1604的Agent Pool,于是,当代码构建开始执行时,Azure DevOps会从Hosted Ubuntu 1604的Agent池中,选择一个Agent执行构建

    image

  6. 接下来,在这个新建的Agent Job中,点击加号(+),然后在列出的所有任务模板中,选择Docker Compose,并点击Add按钮,将它添加到Agent的任务中。事实上,Azure DevOps Pipelines提供了非常多的任务模板,比如,你可以选择一个执行单元测试的模板并将其添加到Agent Job中,然后根据自己的需要,配置单元测试的运行参数,这样的话,Agent Job就能帮你完成单元测试

    image

  7. 在定义Docker Compose Command的界面中,注意将Container Registry Type切换为Container Registry,然后通过点击New按钮,新建一个Docker Registry连接。由于我们选用Docker Hub作为Registry,因此,选择Docker Hub,填上自己的账号和密码后,确认能够连接就可以了:

    image

  8. 在Docker Compose File文本框中,输入tasklist代码库中docker-compose.yml文件的路径,也可以点击“…“按钮,在弹出的对话框中选择该文件:

    image

  9. 在Action下拉框中,指定所执行的操作为Build service images,然后,在Additional Image Tags中,可以指定$(Build.BuildNumber),表示使用当前的构建编号为构建产生的容器镜像打上tag,同时可以选择Include Latest Tag选项,表示当前构建的容器镜像为最新版本(打上latest Tag)。完成这部分设置之后,参数大致如下:

    image

  10. 在完成了上述步骤之后,我们已经可以完成整个tasklist App的编译了。可以看到,在Azure DevOps中设置Build Pipeline进行代码编译是非常简单的。由于我们已经定义了用于代码编译的Docker Compose文件,所以,只需要在Pipeline中添加一个Docker Compose的编译任务即可。现在测试一下,看看编译是否能够成功完成:

    image

  11. 到目前为止,我们只是成功编译了tasklist的容器镜像,还没有将镜像推送到Docker Hub。在容器镜像被推送到Docker Hub之后,我们才能够将容器部署到Azure Container Service中运行。要推送编译好的容器镜像,只需要重复以上6到10步,在Agent Job下再添加一个Docker Compose的任务,所不同的是,Action需要修改为Push service images,保持其它配置不变。保存完Pipeline之后,再次触发编译:

    image

  12. 打开Docker Hub,看看镜像是否已经成功推送:

    image

  13. 最后一步,就是要将tasklist代码库中的yml文件作为编译结果(Artifacts)公布出来,这样做是为了在下一步做Azure Kubernetes Service(AKS)部署的时候,能够获取到部署的定义文件并根据该文件的内容进行部署。使用上述第6步的方法,添加一个Copy Files的任务和一个Publish Build Artifacts的任务。Copy Files的任务设置如下:

    image

    Publish Build Artifacts的任务设置如下:

    image

  14. 再次启动Build Pipeline,可以看到,tasklist已经成功编译:

    image

    所需的编译结果文件(yml文件)也复制成功:

    image

  15. 在Triggers页面,可以选择Enable continuous integration选项,此时每当有新的代码签入代码库,就会触发一次新的构建。当然,还有一些高级选项,比如选择代码分支等,还可以启用Pull request validation,这些内容与持续集成的流程有关,我们可以在今后学习,在这里,我们先勾选Enable continuous integration选项

    image

 

总结

本文首先简单介绍了容器化应用程序的CI/CD流程,然后基于Azure DevOps,为tasklist案例建立了一个Build Pipeline,成功完成了tasklist App的编译以及Docker容器镜像的发布,最后,启用了持续集成功能,使得每次代码变更提交都会触发CI过程。这部分设置与开发过程以及持续集成的流程有关,不同的项目进行持续集成的方式也会有所不同,我们可以单独在其它篇章中进行深入讨论学习。在接下来的第三部分,让我们一起看看,如何把编译好的tasklist容器部署到Azure Kubernetes Service中。

(总访问量:1,471;当日访问量:1)

3 thoughts on “ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(二)

  1. 彭书锐

    博主你好。我在docker push的时候出了问题。你能告知一下应该从哪些方面下手呢。报错信息是requested access to the resource is denied。我已经验证过docker的连接了

    Reply
    1. daxnet Post author

      您需要在hub.docker.com上创建一个自己的docker repo,比如yourname/tasklist-web这样的,然后,在docker push的时候,使用docker push yourname/tasklist-web。如果您直接docker push我案例中的repo,您将没有权限这么做。

      Reply

回复 Shan 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据