zoukankan      html  css  js  c++  java
  • 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进行持续集成和持续部署的架构拓扑:

    image

    我们首先使用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的配置

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

    image

    在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的配置

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

    image

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

    image

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

    image

    从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: {}
    

    测试已部署的RESTful API

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

    image

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

    image

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

    总结

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

  • 相关阅读:
    20201029-1 每周例行报告
    20201022-1 每周例行报告
    2020年秋软件工程“领跑衫”获奖感言
    20201015-3 每周例行报告
    20201207-总结
    20201126-1 每周例行报告
    20201120-1 每周例行报告
    20201112-1 每周例行报告
    20201105-1 每周例行报告
    20201022-1 每周例行报告
  • 原文地址:https://www.cnblogs.com/daxnet/p/12941766.html
Copyright © 2011-2022 走看看