ML.NET机器学习、API容器化与Azure DevOps实践(四):持续集成与k8s持续部署

通过上文所介绍的内容,我们已经完成了RESTful API的开发,现在,就可以使用Azure DevOps来进行持续集成(CI)和k8s持续部署(CD)了。本文我会对使用Azure DevOps进行CI/CD的过程中需要注意的地方进行详细介绍,而对于Azure DevOps配置的详细步骤,我不会做太多注解,大家可以参考我前面写的《ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署》系列文章。

在使用Azure DevOps进行CI/CD之前,首先来了解一下整个开发部署的架构拓扑,下图展示了基于Azure DevOps进行持续集成和持续部署的架构拓扑:

640?wx_fmt=png

我们首先使用Visual Studio 2019来开发ML.NET模型训练的项目,用以生成训练模型,并使用Visual Studio 2019开发了基于ASP.NET Core的RESTful API,这些代码都由Azure DevOps Repo进行托管。然后,Azure DevOps Build Pipeline会对源代码进行编译,将RESTful API应用程序编译成docker镜像然后推送到Azure Container Registry上,并执行模型训练程序,产生训练模型ZIP文件,并由Release Pipeline将训练模型保存到Azure Blob Storage中。Release Pipeline的另一个任务就是通过定义好的Kubernetes部署文件,将RESTful API部署到Azure Kubernetes Services集群。运行于ASP.NET Core中的RESTful API在启动的时候,会访问Azure Blob Storage读取训练模型,同时向客户端提供API端点。整套CI/CD体系,包括代码托管,包括容器注册表,包括容器集群等,全部都由Microsoft Azure提供。不过,出于费用方面的考虑,我没有使用Azure Container Registry,而是使用docker hub,在代码托管方面,也没有使用Azure Repo,而是使用的Github。

总结起来,Build Pipeline和Release Pipeline的任务如下:

  • Build Pipeline:从代码库下载代码,编译并运行训练程序,生成训练模型文件;将ASP.NET Core RESTful API编译成docker镜像并推送到docker hub;最后,将训练模型文件以及用于k8s部署的配置文件进行存档,以供Release Pipeline使用

  • Release Pipeline:读取Build Pipeline所保存的训练模型文件,将其保存到Azure Blob Storage;然后读取Build Pipeline所保存的k8s配置文件,将RESTful API容器镜像部署到k8s环境运行

下面,我简要介绍一下这两个部分的配置过程以及注意事项。

以下是本案例的Build Pipeline的配置:

640?wx_fmt=png

在Build Pipeline里,我定义了两个Agent job:Build Training Model以及Build Web API。前者运行在Hosted VS2017的Agent pool中,后者运行在Hosted Ubuntu 1604的Agent pool中。两者可以并行执行,因为互相并没有依赖。Build Training Model会下载训练程序,在.NET Core下编译并执行这个训练程序,并产生训练模型文件,通过Publish Artifact: Trained Model任务,将训练模型保存起来。而Publish Artifact: Drop k8s deployment script任务则比较简单了,仅仅是将代码库中预先写好的k8s配置文件保存下来,仅此而已。

在Build Web API这个job里,会将ASP.NET Core RESTful API编译成docker容器镜像,并推送到docker hub中,详细配置步骤都比较简单,也就不多说明了。

以下是本案例的Release Pipeline的配置:

640?wx_fmt=png

在Artifacts设置中,会从Build Pipeline将训练模型文件和部署文件复制过来,接下来,在Publish Model to Azure Blob stage中,会将训练模型复制到Azure Blob Storage中,这里使用的是Azure File Copy任务,我们只需要将Azure Subscription的信息以及Azure Blob Storage的连接信息填入即可。

640?wx_fmt=png

在Kubernetes Deployment job中,使用Deploy to Kubernetes任务,即可快速方便地将ASP.NET Core RESTful API方便地部署到Azure Kubernetes Services托管的k8s集群中。需要注意的是,由于RESTful API需要访问Azure Blob Storage来读取机器学习的训练模型(这一点在上一讲已经提到过),因此,在这里就要将访问Blob Storage的连接信息通过ConfigMap配置到k8s集群中:

640?wx_fmt=png

从k8s.deploy.yml文件可以看到,环境变量是如何通过ConfigMap设置到集群中的服务上的:


apiVersion: v1

items:

- apiVersion: extensions/v1beta1

  kind: Deployment

  metadata:

    name: mlnet-webapi-deployment

  spec:

    replicas: 2

    template:

      metadata:

        labels:

          app.name: mlnet

      spec:

        containers:

          - image: daxnet/mlnet_webapi

            name: mlnet-webapi

            ports:

            - containerPort: 80

            env:

            - name: BLOB_DEFAULT_ENDPOINTS_PROTOCOL

              valueFrom:

                configMapKeyRef:

                  name: mlnet-config

                  key: BLOB_DEFAULT_ENDPOINTS_PROTOCOL

            - name: BLOB_ACCOUNT_NAME

              valueFrom:

                configMapKeyRef:

                  name: mlnet-config

                  key: BLOB_ACCOUNT_NAME

            - name: BLOB_ACCOUNT_KEY

              valueFrom:

                configMapKeyRef:

                  name: mlnet-config

                  key: BLOB_ACCOUNT_KEY

            - name: BLOB_ENDPOINT_SUFFIX

              valueFrom:

                configMapKeyRef:

                  name: mlnet-config

                  key: BLOB_ENDPOINT_SUFFIX

        restartPolicy: Always

- apiVersion: v1

  kind: Service

  metadata:

    labels:

      app.name: mlnet

    name: mlnet-webapi-service

  spec:

    type: LoadBalancer

    ports:

      - name: "expose-80"

        port: 80

        targetPort: 80

    selector:

      app.name: mlnet

kind: List

metadata: {}

通过kubectl客户端命令,可以查看我们的API是否已经部署成功:

640?wx_fmt=png

然后,使用mlnet-webapi-service服务的EXTERNAL-IP地址,对API进行测试:

640?wx_fmt=png

已经得到预测结果,API部署和调用成功。

本系列文章一共四个部分,首先介绍了机器学习的基本概念,然后介绍了基于ML.NET的机器学习案例以及训练模型生成、RESTful API的开发,最后简要介绍了基于Azure DevOps实现持续集成、持续部署以及Azure Kubernetes Service k8s集群部署的过程。本系列文章也是我在Microsoft Global Azure Bootcamp 2019上海站活动中所分享的内容。整个案例的源代码可以从Github下载:https://github.com/daxnet/mlnet-trainer。

原文地址:https://sunnycoding.cn/2019/05/15/mlnet-containerize-and-azure-devops-practices-part4/

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P3195 [HNOI2008]玩具装箱

P3195 [HNOI2008]玩具装箱 题意: n件玩具,第i件玩具经过压缩后的一维长度为CiC_iCi​,现在把玩具装入一维容器中,要求: 在一个一维容器中的玩具编号是连续的如果一个一维容器中有多个玩具,那么两件玩具之间要加入一…

卷积与莫比乌斯反演

卷积与莫比乌斯反演 目录 卷积与莫比乌斯反演 0前言 0.1前置技能 0.2问题的引入 1.简单定义 1.1数论函数的定义 1.2卷积的定义 1.3反演的基本形式 2.1莫比乌斯反演 3.1例题:【luogu-P2257 YY的GCD】 题目大意: solution1 solution2 0.前言 莫比…

ML.NET机器学习、API容器化与Azure DevOps实践(三):RESTful API

通过上文所述案例,我们已经选择了最优回归算法来预测学生的综合成绩,并且完成了基于训练数据集的预测模型训练。从实现上,训练好的模型被保存成一个ZIP文件,以便在其它项目中直接调用以完成机器学习的实践场景。在本文中&#xff…

Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)

Manthan, Codefest 19 (open for everyone, rated, Div. 1 Div. 2) 题号题目知识点AXORinacciBUniqueness尺取CMagic Grid构造DRestore Permutation思维线段树ELet Them Slide线段树思维FBits And PiecesGPolygonsHRed Blue Tree

杜教筛

杜教筛 1.概述 杜教筛是用以解决积性函数前缀和的算法。 在学习了莫比乌斯反演之后,杜教筛的过程就会显得简单而自然。 2.基本形式 对于积性函数,我们定义如下函数: 构造积性函数 ,使得 显然 : 进一步转化&#xf…

CF1208D Restore Permutation

CF1208D Restore Permutation 题意&#xff1a; 现在有一个从1到n的一个全排列,但是你不知道这个排列到底是什么,但是你有一个sum[i],其中sum[i]表示∑j1i−1(aj<ai)?aj:0∑_{j1}^{i−1}(a_j<a_i)?a_j:0∑j1i−1​(aj​<ai​)?aj​:0,现在给你sum数组,让你求出这…

ML.NET机器学习、API容器化与Azure DevOps实践(二):案例

在上文中&#xff0c;我简单地介绍了机器学习以及ML.NET的相关知识&#xff0c;从本讲开始&#xff0c;我会基于一个简单的案例&#xff1a;学生成绩预测&#xff0c;来介绍使用ML.NET进行机器学习以及API部署的基本过程。本案例的数据来源为加州大学尔湾分校的机器学习公开样本…

业界萌新对斯坦纳树的小结

业界萌新对斯坦纳树的小结 0.简介 斯坦纳树问题是组合优化问题&#xff0c;与最小生成树相似&#xff0c;是最短网络的一种。最小生成树是在给定的点集和边中寻求最短网络使所有点连通。而最小斯坦纳树允许在给定点外增加额外的点&#xff0c;使生成的最短网络开销最小。 ——…

cf1208E. Let Them Slide

cf1208E. Let Them Slide 题意&#xff1a; 都放在一个长度为W的框里面。有n个序到&#xff0c;第i个序列的长度是1。这些序到并排放在一起&#xff0c;每一个序列都放在一个长度为w的框里 这些序列可以在框里面滑动&#xff0c;但是不能划出框。 对于每一个位置&#xff0…

结合eShopOnWeb全面认识领域模型架构

一.项目分析在上篇中介绍了什么是"干净架构"&#xff0c;DDD符合了这种干净架构的特点&#xff0c;重点描述了DDD架构遵循的依赖倒置原则&#xff0c;使软件达到了低藕合。eShopOnWeb项目是学习DDD领域模型架构的一个很好案例&#xff0c;本篇继续分析该项目各层的职…

SOS_dp算法

Codeforces博客 简介&#xff1a; 前置知识&#xff1a;状压dp Sum over Subsets dynamic programming&#xff0c;简称Sos dp,状压dp的一种 用一个列题引出SOS dp&#xff1a; 给你一个由2N2^N2N个整数组成的确定数组A&#xff0c;我们需要计算对于任意的x&#xff0c;F(x)所…

微软开源Bing搜索背后的关键算法

微软今天宣布开源了一项 Bing 搜索背后的关键算法 —— SPTAG&#xff0c;它使 Bing 能够快速将搜索结果返回给用户。仅在几年前&#xff0c;网络搜索很简单&#xff0c;用户输入几个关键词然后浏览结果页面。现如今&#xff0c;这些用户可能会在手机上拍照并将其放入搜索框中&…

Stern-Brocot Tree

Stern-Brocot Tree 0.简介 Stern-Brocot Tree&#xff0c;俗称SB树&#xff08;滑稽&#xff09;。它能够表示出所有的最简分数&#xff0c;如下图。 1.一些规律 显然&#xff0c;对于两个相邻的最简分数 可以得到另一个最简分数 这样就可以在Stern-Brocot Tree上表示出所有…

FWT(快速沃尔什变换)

文章目录引入&#xff1a;or卷积and卷积xor卷积IFWT模板&#xff1a;例题&#xff1a;引入&#xff1a; FFT/NTT是用来解决∑ijkA[i]B[j]\sum_{ijk}A[i]B[j]∑ijk​A[i]B[j]的式子 而FWT是用来解决Ci∑j⊕kiAjBkC_i\sum_{j⊕ki}A_jB_kCi​∑j⊕ki​Aj​Bk​ ​ FWT是一种用于处…

教你自制.NET Core Global Tools

点击上方蓝字关注“汪宇杰博客”命令行是程序员装逼利器&#xff0c;.NET Core也可以写命令行程序&#xff0c;但是如何分发给其他程序员使用&#xff0c;一直是个问题。现在&#xff0c;有了.NET Core Global Tools&#xff0c;可以很方便的解决分发问题&#xff0c;我们来看看…

三点间LCA

三点间LCA 1.直接上题——jzoj5883. 【NOIP2018模拟A组9.25】到不了 Dscription wy 和 wjk 是好朋友。 今天他们在一起聊天&#xff0c;突然聊到了以前一起唱过的《到不了》。 “说到到不了&#xff0c;我给你讲一个故事吧。” “嗯&#xff1f;” “从前&#xff0c;神和凡人…

CF1208F Bits And Pieces(未解决)

CF1208F Bits And Piecesa 题意&#xff1a; 给定 n 个数的数组d,找到i<j<ki\lt j\lt ki<j<k 的 i,j,k&#xff0c;使得 di∣(dj&dk)d_i|(d_j \& d_k)di​∣(dj​&dk​)最大 题解&#xff1a; 一开始以为是01字典树&#xff0c;看了题解说是SOSdp&…

微软拥抱开源,Win10为啥要引入真Linux4.X内核?

来源 | 异步 | 文末赠书2019 年微软 Build 开发者大会在雷德蒙德召开。继将 Bash shell、原生 OpenSSH、WSL 引入 Windows&#xff0c;以及在微软商店提供 Ubuntu、SUSE Linux 和 Fedora 等发行版&#xff0c;微软又宣布了一个重大的决定 —— 将完整的 Linux 内核引入 Windows…

文件快速输入输出

某考试中出题人给出的毒瘤文件快速输入输出。 namespace io {const int SIZE (1 << 21) 1;char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS obuf, *oT oS SIZE - 1, c, qu[55]; int f, qr;// getchar#define gc() (iS iT ? (iT (iS ibuf) fread (ibuf, 1, SIZE, …

F.孤独(牛客小白月赛39)

F.孤独&#xff08;牛客小白月赛39&#xff09; 题意&#xff1a; 给定一棵树&#xff0c;寻找一个路径&#xff0c;将断掉所有与这个路径上的点相连的边&#xff0c;使得剩下的最大连通块的大小最小 题解&#xff1a; 这题有点印象&#xff0c;感觉做过&#xff0c;至少这…