介绍
Azure DevOps,以前称为Visual Studio Team Services(VSTS),可帮助个人和组织更快地规划,协作和发布产品。其中一项值得注意的服务是Azure Pipelines,它可以帮助开发人员构建持续集成(CI)和持续交付(CD)管道,从而自动化和标准化软件开发过程的构建,测试和部署阶段。此外,Azure Pipelines还提供本机容器支持,可与任何语言,平台和云配合使用。像软件开发这样的机器学习也是一个包括构建,测试和部署阶段的过程,这使其成为自动化和标准化的良好候选者。在Build 2018,微软宣布推出ML.NET,.NET的开源,跨平台机器学习框架。如果我们将所有这些工具和服务放在一起,这意味着我们可以自动化和标准化使用ML.NET构建的机器学习模型的训练,将其打包到Docker容器中并将其部署到Azure Container Instances(ACI) 。在本文中,我将介绍在Azure Devops中构建CI / CD管道的过程,该管道训练,打包和部署ML.NET机器学习模型,以使用各种测量来预测鸢尾花属于哪一类。
先决条件
应用程序
因为这篇文章的目的是演示Azure Devops的功能而不是ML.NET的功能,所以我将从一个预构建的应用程序开始。有关ML.NET功能的更多信息和详细信息,请查看官方文档页面以及我以前的一些帖子:
- 使用ML.NET和Azure Function进行机器学习 - 第1部分
- 使用ML.NET和Azure Function进行机器学习 - 第2部分
- 使用ML.NET + ASP.NET Core + Docker + Azure Container Instances部署.NET机器学习模型
本文中使用的应用程序包含三个.NET Core项目。一个是类库,我们将使用它来为训练模型包装ML.NET功能,以及加载预先训练的模型,然后将其用于进行预测。另一个是.NET Core控制台应用程序,它引用类库来训练和持久化ML.NET模型。最后,还有ASP.NET Core Web API,它还引用了类库应用程序来加载由控制台应用程序创建的预先训练的模型,然后通过HTTP进行预测。此应用程序可以单独使用和部署,但在本文中,它将打包到Docker镜像中,然后将其部署到Azure Container Instances。
Class Library
可以在MLModel
目录中找到类库。类库定义观察和预测数据类,它们分别可以在IrisData.cs
和IrisPrediction.cs
文件中找到。此外,Model
该类包含辅助方法,用于训练和保存机器学习模型,加载预先训练的模型并使用这些模型进行预测。
控制台应用
在解决方案目录中,我们在目录中也有一个控制台应用程序ModelTrainer
。此应用程序引用MLModel
目录中的类库来训练和持久化机器学习模型。
API
该ModelApi
目录包含一个ASP.NET Core Web API应用程序,该应用程序引用MLModel
类库项目以加载由ModelTrainer
控制台应用程序训练并通过HTTP进行预测的预训练模型。可以在ModelApi应用程序Controllers目录中的PredictController.cs
类中找到进行预测的逻辑。
CI / CD管道流程
从概念上讲,当手动构建和部署应用程序时,机器学习模型在MLModel
类库中定义和开发。一旦对模型满意,就会构建类库。MLModel
构建引用类库的控制台应用程序以及运行以在称为的文件中训练和持久化分类模型model.zip
。该MLModel
类库也被引用的ModelApi
ASP.NET核心项目。因为ModelApi
我们要部署的应用程序是为了公开我们预先训练好的机器学习模型,所以我们需要找到一种方法来打包它以进行部署。我们将使用Azure Container Instances部署ModelApi
意味着我们需要创建项目的Docker镜像,然后将其推送到Docker注册表,以供公众使用。可以使用Azure DevOps标准化和自动化构建多个项目以及将Docker镜像构建,发布和部署到Azure Container Instances。本文的其余部分将重点介绍如何使用Azure管道通过Azure DevOps中的CI / CD管道逐步操作此机器学习应用程序。
获取代码
在开始之前,您要做的第一件事就是将mlnetazdevopssample GitHub存储库分成您自己的GitHub帐户。
创建项目
导航到https://devops.azure.com,单击Start Free
并按照提示创建新帐户或登录现有帐户。
登录后,单击Create Project
。
输入项目名称以及简短说明。然后,单击Create
。
持续集成(CI)管道
使用Azure管道,我们将为应用程序的构建和打包步骤配置CI管道。以下是我们的CI管道中涉及的所有步骤的说明:
- 构建类库应用程序
- 构建控制台应用程序
- 通过运行控制台应用程序来训练和持久化ML.NET模型。
- 将控制台应用程序创建的ML.NET模型文件复制到ASP.NET Core Web API应用程序目录中
- 构建ASP.NET Core Web API应用程序
- 构建Docker镜像
- 将Docker镜像推送到Docker Hub
CI管道设置
创建项目后,在主项目页面中,将鼠标悬停在上Pipelines
,然后单击Builds
。
在Builds
管道页面中,单击New pipeline
。
选择GitHub作为源,并将您的GitHub帐户与Azure DevOps连接。
一旦您授权Azure DevOps使用您的GitHub帐户,请选择将用于此构建管道的存储库和分支。在我们的例子中,我们将使用mlnetazdevopssample
存储库的主分支。完成配置后,单击Continue
。
下一步是选择要在我们的管道中执行的作业。因为这个构建管道中有多个步骤,所以让我们从一个开始,Empty Job
并根据我们的需要进行自定义。
在构建管道页面内部,在我们开始添加作业之前,让我们选择将执行作业的代理。对于此管道,请Hosted Ubuntu 1604
从下拉列表中选择该选项。
1.构建类库应用程序
我们的CI管道的第一步是构建我们的类库,其中包含包含ML.NET框架和持久模型的训练,加载和预测功能的方法。
为此,我们将向我们添加一个.NET Core任务Agent Job 1
。
添加到管道后,让我们配置此任务。为了使其更具描述性,我们可以给它一个名称,如Build Class Library
。因为此任务将负责构建.NET Core类库,所以我们将保留默认的build
Command设置。
我们要配置的另一个设置是Working Directory
。我们可以通过单击Advanced
选项卡来完成。
对于此任务,我们将使用该MLModel
目录。
完成配置后,单击顶部工具栏上的Save & Queue
- > Save
。
输入描述管道更改的详细注释,然后单击Save
。
2.构建控制台应用程序
一旦我们构建了我们将从.NET Core控制台和ASP.NET Core Web API应用程序引用的类库应用程序,就可以构建控制台应用程序,这将用于训练和持久化ML.NET模型。
与上一步类似,将新的.NET Core 构建任务添加到管道。将为此任务更改的唯一设置是Working Directory
具有值的值ModelTrainer
。
虽然不是必需的,但在完成任务配置后,单击Save & Queue
- > Save
以保存并注释对管道的更改。
3.训练并持久化ML.NET模型
现在我们的控制台应用程序已经构建完毕,是时候运行它来训练和持久化ML.NET模型了。为此,我们将添加另一个.NET Core任务。不同之处在于Command
现在将使用该run
值配置设置。
在Working Directory
将被设置为ModelTrainer
在前面的任务一样。
请记住保存并注释管道的新更改。
4.将ML.NET模型复制到Web API目录
运行控制台应用程序并训练ML.NET模型后,它将保留model.zip
在ModelTrainer调用
目录中。我们可以使用此持久化版本的模型从控制台应用程序或我们选择的任何其他应用程序进行预测。在这种情况下,我们将通过ASP.NET Core Web API进行预测。为了让我们的API引用此文件,我们需要将其复制到我们ModelApi
目录的根目录中。执行该任务的方法是通过bash脚本。要向我们的管道添加bash脚本,我们需要做的就是向它添加一个Bash任务。
一旦添加到我们的管道,就可以配置任务了。我们将设置的Type
设置Inline
将显示一个文本框,供我们输入脚本。
在文本框内,输入以下内容:
# Write your commands here cp ../ModelTrainer/model.zip . # Use the environment variables input below to pass secret variables to this script
我们可以Working Directory
将此步骤设置为ModelApi
。此命令将model.zip
文件从ModelTrainer
目录复制到ModelApi
目录。
完成后,将新更改保存并注释到管道。
5.构建ASP.NET Core Web API应用程序
现在我们在ModelApi
应用程序中有了必要的文件,是时候构建它了。我们将向我们的管道添加一个.NET Core任务并设置Command
为build
。这Working Directory
将ModelApi
像上一个任务一样。
完成后,保存并注释管道的新更改。
6.构建ASP.NET Core Web API Docker镜像
ASP.NET Core Web API应用程序的部署方法是通过容器。因此,在构建应用程序之后,我们必须为它构建一个Docker镜像,然后可以将其推送到您选择的Docker注册表。要构建Docker镜像,我们将向管道添加Docker任务。
当我们配置任务时,我们将从设置为Container Registry Type
开始Container Registry
。
这将提示设置与Docker注册表的服务连接(如果尚不存在)。
我们将使用的Docker注册表类型是Docker Hub。为连接命名,输入Docker Hub帐户的凭据,然后单击Verify this connection
以确保您的凭据有效,并且可以与Docker Hub建立连接。完成后点击OK
。
该Command
设置将build
因此我们可以保留默认值是还有Dockerfile
其中会使用到Dockerfile在根目录设置mlnetazdevopssample
目录。
最后,我们将配置Image name
设置。我们将使用的惯例是<docker-hub-username>/<image-name>
。就我而言,lqdev
是我的Docker Hub的用户名,并在lqdev/mlnetazdevopssample命名我的镜像为mlnetazdevopssample
。此外,选中Include latest tag
复选框以使每个构建都是最新的,而不是使用版本号标记它。
请记住保存并注释最近对管道的更改。
7.将Docker Image推送到Docker Hub
CI管道的最后一步是将新构建的镜像推送到Docker Hub。为此,我们将使用anoter Docker任务。
与上一个任务一样,我们将设置Container registry type
为Container Registry
。Docker registry service connection
通过从下拉列表中选择连接,将其设置为最近创建的连接。我们将更Command
改为push
并设置Image name
为上一步中构建的图像的名称。命名约定是<docker-hub-username>/<image-name>:latest
。我们以前的Docker构建任务添加了最新的标记,因此请确保将其包含在此任务中。
完成后,单击Save & Queue
- > Save & Queue
。此操作将手动触发CI管道。
不要忘记注释您的更改,然后单击Save & queue
以启动CI管道。
监控构建
构建开始时,您可以单击左窗格中Builds
的Pipelines
部分下方。
从列表中选择第一个构建以获取有关构建的更多详细信息。
这将带您进入实时显示管道状态的日志。
确认CI管道成功
如果构建成功,请导航到https://hub.docker.com/以检查Docker镜像是否已推送到注册表。
持续交付(CD)管道
现在我们已经建立了CI管道,它将构建和打包我们的应用程序,现在是时候部署它了。我们可以自己做或者使用CD管道自动化它。我们的应用程序将部署到Azure Container Instances,这是一项Azure服务,提供了一种快速运行容器的方法,而无需担心虚拟机或业务流程服务的管理。我们的CD管道涉及的步骤如下:
- 创建Azure资源组以进行部署
- 将应用程序部署到Azure Container Instances
CD管道设置
要开始设置CD管道,请从Azure DevOps项目主页面悬停Pipelines
并单击Releases
。
进入该页面后,单击New pipeline
。
与我们的CI管道一样,我们将从稍后开始Empty Job
配置。
触发部署
创建管道后,就可以配置它了。我们要做的第一件事是添加一个工件。工件可以是各种各样的东西,包括构建管道的输出。在我们的例子中,我们的CI管道将成为我们CD管道的触发器。要添加工件,请单击Add an artifact
。
在配置表单,设置Source type
到Build
和Source
在前面的步骤中创建的CI管道的名称。完成后,单击Add
。
在配置我们的工件之后,是时候配置CD管道中的步骤了。为此,请单击发布管道页面部分中的Stage 1
选项,Stages
并将名称更改为更具描述性的名称。
完成后,关闭表单并单击Stages标题下方的超链接。
您现在应该位于类似于CI管道作业配置页面的页面上。在此页面上,我们将要单击Agent Job
面板以将Agent pool
设置设置为Hosted Ubuntu 1604
。
完成后,就可以在CD管道中配置任务了。
1.创建Azure资源组
开始向Azure CLI
管道添加任务。在此任务中,我们将在Azure中创建一个资源组,我们将部署应用程序。
在执行任何其他操作之前,将DevOps链接到Azure订阅,方法是从下拉列表中选择一个,然后单击Authorize
该订阅将提示您对订阅进行身份验证。
连接Azure订阅后,让我们将Script Location
设置更改为Inline Script
。
在Inline Script
文本框中输入以下内容:
az group create --name mlnetazdevopssampleresourcegroup --location eastus
这个脚本会在Azure中创建位于eastus的
资源组命名为mlnetazdevopssampleresourcegroup
。这两个配置项可以根据您的喜好进行调整。
2.将Docker镜像部署到Azure Container Instances
CD管道中的下一步也是最后一步是部署到Azure Container Instances。要部署我们的应用程序,我们将添加另一项Azure CLI
任务。这一次,由于我们已经Azure subscription
在上一个任务中配置了我们,因此我们可以选择服务连接而不是下拉列表中的订阅。
与上一个任务一样,我们的脚本将是Inline的。
在Inline Script
文本框中输入以下内容:
az container create --resource-group mlnetazdevopssampleresourcegroup --name mlnetcontainer --image lqdev/mlnetazdevopssample:latest --ports 80 --ip-address public
配置完此步骤后,请确保通过单击保存并注释所有更改Save
。此脚本在由管道的上一个任务创建的资源组中创建一个容器,其中包含mlnetcontainer
来自Docker图像的名称,该图像由CI管道推送到Docker Hub。此外,它打开端口80并为外部访问的容器分配可公开访问的IP地址。
然后,为了使其易于识别,请通过将鼠标悬停在附近New release pipeline
并单击铅笔图标来编辑管道的名称。
确保保存并注释您的更改。
自动化CI / CD管道
在前面的步骤中,我们配置了CI和CD管道。但是,我们仍然没有完全自动化启动这两者的触发器。
CI管道触发器
首先,让我们通过自动化CI管道开始。为此,请转到项目的主页面,将鼠标悬停在上面Pipelines
并单击Builds
。
这将带您进入CI管道页面。在此页面上,单击Edit
。
然后,单击Triggers
。
进入此页面后,选中Enable continous integration
复选框,然后单击Save & Queue
- > 保存并注释您的更改Save
。
CD管道触发器
要自动化CD管道触发器,请单击页面Releases
下方Pipelines
以自动化CD管道。
进入CD管道的页面后,单击Edit
。
然后,单击Artifacts部分中的闪电图标,该图标将显示配置表单。在此表单中,将Continuous deployment trigger
设置切换为Enabled
。
完成后,保存并注释您的更改。
运行CI / CD管道
虽然在将新更改签入mlnetazdevopssample
存储库的主分支时将启动前进构建和部署,但出于演示目的,我们将手动启动我们刚刚配置的CI / CD管道。为此,请单击左窗格中的Pipelines
下方的Builds。
从CI管道页面单击Queue
。
这将提示显示一个模式,您可以在其中单击Queue
以启动构建。
这将启动一个新的CI构建,随后也将启动您的应用程序的CD管道。
测试部署
如果一切都成功,ASP.NET Core Web API应用程序的Docker镜像将部署到Azure Container Instances,可以通过公共IP地址访问。
要查看部署是否有效,请导航至https://portal.azure.com/并单击Resource groups
。
此时,您应该看到CD管道创建的资源组。如果是这种情况,请单击它。
然后,这将显示一个页面,显示部署到此资源组的容器。点击它。
容器页面将显示有关容器的诊断和配置信息。我们感兴趣的信息是IP address
。将鼠标悬停在其右侧并单击显示的图标Click to copy
。这会将地址复制到剪贴板。
在像Postman或Insomnia这样的应用程序中,向Azure 发出一个HTTP POST请求,http://<ip-address>/api/predict
其中ip-address
包含Azure中容器的公共IP地址,具有以下正文。
{ "SepalLength":3.3, "SepalWidth":1.6, "PetalLength":0.2, "PetalWidth":5.1 }
如果成功,响应将是Iris-virginica
。
小结
在这篇文章中,我们实现了ML.NET应用程序的构建,打包和部署,该应用程序使用Azure DevOps实现对鸢尾花的分类进行预测。我们创建了Continous Integration和Continous Delivery管道,它将ASP.NET Core Web API的Docker镜像部署到Azure Container Instances。请记住,这只是其中一种方法,Azure DevOps可以灵活地配置所有这些任务和工作流以满足您的要求。