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机器学习模型,以使用各类测量来预测鸢尾花属于哪一类。
html
由于这篇文章的目的是演示Azure Devops的功能而不是ML.NET的功能,因此我将从一个预构建的应用程序开始。有关ML.NET功能的更多信息和详细信息,请查看官方文档页面以及我之前的一些帖子:git
本文中使用的应用程序包含三个.NET Core项目。一个是类库,咱们将使用它来为训练模型包装ML.NET功能,以及加载预先训练的模型,而后将其用于进行预测。另外一个是.NET Core控制台应用程序,它引用类库来训练和持久化ML.NET模型。最后,还有ASP.NET Core Web API,它还引用了类库应用程序来加载由控制台应用程序建立的预先训练的模型,而后经过HTTP进行预测。此应用程序能够单独使用和部署,但在本文中,它将打包到Docker镜像中,而后将其部署到Azure Container Instances。github
能够在MLModel
目录中找到类库。类库定义观察和预测数据类,它们分别能够在IrisData.cs
和IrisPrediction.cs
文件中找到。此外,Model
该类包含辅助方法,用于训练和保存机器学习模型,加载预先训练的模型并使用这些模型进行预测。docker
在解决方案目录中,咱们在目录中也有一个控制台应用程序ModelTrainer
。此应用程序引用MLModel
目录中的类库来训练和持久化机器学习模型。api
该ModelApi
目录包含一个ASP.NET Core Web API应用程序,该应用程序引用MLModel
类库项目以加载由ModelTrainer
控制台应用程序训练并经过HTTP进行预测的预训练模型。能够在ModelApi应用程序Controllers目录中的PredictController.cs
类中找到进行预测的逻辑。bash
从概念上讲,当手动构建和部署应用程序时,机器学习模型在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管道逐步操做此机器学习应用程序。app
在开始以前,您要作的第一件事就是将mlnetazdevopssample GitHub存储库分红您本身的GitHub账户。框架
导航到https://devops.azure.com,单击Start Free
并按照提示建立新账户或登陆现有账户。机器学习
登陆后,单击Create Project
。工具
输入项目名称以及简短说明。而后,单击Create
。
使用Azure管道,咱们将为应用程序的构建和打包步骤配置CI管道。如下是咱们的CI管道中涉及的全部步骤的说明:
建立项目后,在主项目页面中,将鼠标悬停在上Pipelines
,而后单击Builds
。
在Builds
管道页面中,单击New pipeline
。
选择GitHub做为源,并将您的GitHub账户与Azure DevOps链接。
一旦您受权Azure DevOps使用您的GitHub账户,请选择将用于此构建管道的存储库和分支。在咱们的例子中,咱们将使用mlnetazdevopssample
存储库的主分支。完成配置后,单击Continue
。
下一步是选择要在咱们的管道中执行的做业。由于这个构建管道中有多个步骤,因此让咱们从一个开始,Empty Job
并根据咱们的须要进行自定义。
在构建管道页面内部,在咱们开始添加做业以前,让咱们选择将执行做业的代理。对于此管道,请Hosted Ubuntu 1604
从下拉列表中选择该选项。
咱们的CI管道的第一步是构建咱们的类库,其中包含包含ML.NET框架和持久模型的训练,加载和预测功能的方法。
为此,咱们将向咱们添加一个.NET Core任务Agent Job 1
。
添加到管道后,让咱们配置此任务。为了使其更具描述性,咱们能够给它一个名称,如Build Class Library
。由于此任务将负责构建.NET Core类库,因此咱们将保留默认的build
Command设置。
咱们要配置的另外一个设置是Working Directory
。咱们能够经过单击Advanced
选项卡来完成。
对于此任务,咱们将使用该MLModel
目录。
完成配置后,单击顶部工具栏上的Save & Queue
- > Save
。
输入描述管道更改的详细注释,而后单击Save
。
一旦咱们构建了咱们将从.NET Core控制台和ASP.NET Core Web API应用程序引用的类库应用程序,就能够构建控制台应用程序,这将用于训练和持久化ML.NET模型。
与上一步相似,将新的.NET Core 构建任务添加到管道。将为此任务更改的惟一设置是Working Directory
具备值的值ModelTrainer
。
虽然不是必需的,但在完成任务配置后,单击Save & Queue
- > Save
以保存并注释对管道的更改。
如今咱们的控制台应用程序已经构建完毕,是时候运行它来训练和持久化ML.NET模型了。为此,咱们将添加另外一个.NET Core任务。不一样之处在于Command
如今将使用该run
值配置设置。
在Working Directory
将被设置为ModelTrainer
在前面的任务同样。
请记住保存并注释管道的新更改。
运行控制台应用程序并训练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
目录。
完成后,将新更改保存并注释到管道。
如今咱们在ModelApi
应用程序中有了必要的文件,是时候构建它了。咱们将向咱们的管道添加一个.NET Core任务并设置Command
为build
。这Working Directory
将ModelApi
像上一个任务同样。
完成后,保存并注释管道的新更改。
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
复选框以使每一个构建都是最新的,而不是使用版本号标记它。
请记住保存并注释最近对管道的更改。
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
部分下方。
从列表中选择第一个构建以获取有关构建的更多详细信息。
这将带您进入实时显示管道状态的日志。
若是构建成功,请导航到https://hub.docker.com/以检查Docker镜像是否已推送到注册表。
如今咱们已经创建了CI管道,它将构建和打包咱们的应用程序,如今是时候部署它了。咱们能够本身作或者使用CD管道自动化它。咱们的应用程序将部署到Azure Container Instances,这是一项Azure服务,提供了一种快速运行容器的方法,而无需担忧虚拟机或业务流程服务的管理。咱们的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管道中配置任务了。
开始向Azure CLI
管道添加任务。在此任务中,咱们将在Azure中建立一个资源组,咱们将部署应用程序。
在执行任何其余操做以前,将DevOps连接到Azure订阅,方法是从下拉列表中选择一个,而后单击Authorize
该订阅将提示您对订阅进行身份验证。
链接Azure订阅后,让咱们将Script Location
设置更改成Inline Script
。
在Inline Script
文本框中输入如下内容:
az group create --name mlnetazdevopssampleresourcegroup --location eastus
这个脚本会在Azure中建立位于eastus的
资源组命名为mlnetazdevopssampleresourcegroup
。这两个配置项能够根据您的喜爱进行调整。
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管道开始。为此,请转到项目的主页面,将鼠标悬停在上面Pipelines
并单击Builds
。
这将带您进入CI管道页面。在此页面上,单击Edit
。
而后,单击Triggers
。
进入此页面后,选中Enable continous integration
复选框,而后单击Save & Queue
- > 保存并注释您的更改Save
。
要自动化CD管道触发器,请单击页面Releases
下方Pipelines
以自动化CD管道。
进入CD管道的页面后,单击Edit
。
而后,单击Artifacts部分中的闪电图标,该图标将显示配置表单。在此表单中,将Continuous deployment trigger
设置切换为Enabled
。
完成后,保存并注释您的更改。
虽然在将新更改签入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能够灵活地配置全部这些任务和工做流以知足您的要求。