基于ECI的弹性推理

模型训练完成后,通常会被部署成推理服务。推理服务的调用量会随着业务需求动态变化,这就需要服务器能弹性扩缩容来节省成本。在大规模高并发的节点需求情况下,常规的部署方案无法满足此类需求。阿里云提供了基于弹性容器实例ECI(Elastic Container Instance)的运行工作负载能力,满足推理服务的弹性伸缩的需求。本文介绍如何基于ECI运行弹性推理服务。

前提条件

  • 已准备好部署模型。本文使用TensorFlow 1.15训练的Bert模型。

  • 已安装ack-virtual-node、ack-alibaba-cloud-metrics-adapter、arena组件。关于组件的相关操作,请参见管理组件;关于ack-virtual-node的相关信息,请参见对接ECI概述

操作步骤

  1. 将训练模型上传到OSS上。具体操作,请参见控制台上传文件

  2. 创建PV和PVC。

    1. 使用以下模板创建pvc.yaml文件。

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: model-csi-pv
      spec:
        capacity:
          storage: 5Gi
        accessModes:
          - ReadWriteMany
        persistentVolumeReclaimPolicy: Retain
        csi:
          driver: ossplugin.csi.alibabacloud.com
          volumeHandle: model-csi-pv # 需要和pv名称一致。
          volumeAttributes:
            bucket: "Your Bucket"
            url: "Your oss url"
            akId: "Your Access Key Id"
            akSecret: "Your Access Key Secret"
            otherOpts: "-o max_stat_cache_size=0 -o allow_other"
      ---
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: model-pvc
      spec:
        accessModes:
        - ReadWriteMany
        resources:
          requests:
            storage: 5Gi

      参数

      说明

      bucket

      OSS的Bucket名称,在OSS范围内全局唯一。更多信息,请参见存储空间命名

      url

      OSS文件的访问URL。更多信息,请参见如何获取单个或多个文件的URL

      akId

      访问OSS的AccessKey ID和AccessKey Secret。建议使用RAM用户访问,更多信息,请参见创建AccessKey

      akSecret

      otherOpts

      挂载OSS时支持定制化参数输入。

      • -o max_stat_cache_size=0代表禁用属性缓存,每次访问文件都会从 OSS 中获取最新的属性信息。

      • -o allow_other代表允许其他用户访问挂载的文件系统。

      参数设置的更多信息,请参见ossfs支持的设置参数选项

    2. 执行以下命令,创建PV和PVC。

      kubectl apply -f pvc.yaml
  3. 部署推理服务。

    1. 执行以下命令,部署推理服务。

      部署推理服务时,您可以通过Annotation指定申请的资源类型,关键参数说明如下:

      参数

      说明

      alibabacloud.com/burst-resource

      取值如下:

      • 默认不配置:只使用集群现有的ECS资源。

      • eci:当前集群ECS资源不足时,使用ECI弹性资源。

      • eci_only:只使用ECI弹性资源,不使用集群的ECS资源。

      k8s.aliyun.com/eci-use-specs

      如果需要使用ECI GPU资源,需要通过该Annotation指定GPU实例规格。

      arena serve tensorflow \
         --namespace=default \
         --name=bert-tfserving \
         --model-name=chnsenticorp  \
         --gpus=1  \
         --image=tensorflow/serving:1.15.0-gpu \
         --data=model-pvc:/data \
         --model-path=/data/models/tensorflow/chnsenticorp \
         --version-policy=specific:1623831335 \
         --annotation=alibabacloud.com/burst-resource=eci_only \
         --annotation=k8s.aliyun.com/eci-use-specs=ecs.gn6i-c4g1.xlarge
    2. 执行以下命令,查看服务状态。

      arena serve list

      预期输出:

      NAME            TYPE        VERSION       DESIRED  AVAILABLE  ADDRESS        PORTS                   GPU
      bert-tfserving  Tensorflow  202207181536  1        1          172.16.52.170  GRPC:8500,RESTFUL:8501  1
    3. 执行以下命令,查看Pod状态。

      kubectl get pods -o wide

      预期输出:

      NAME                                                              READY   STATUS    RESTARTS   AGE    IP              NODE                           NOMINATED NODE   READINESS GATES
      bert-tfserving-202207181536-tensorflow-serving-547797c546-djh58   1/1     Running   0          114s   192.168.0.246   virtual-kubelet-cn-beijing-h   <none>           <none>

      由预期输出得到,Node类型为virtual-kubelet-cn-beijing-h,表示Pod被部署在ECI上。

  4. 创建HPA(Horizontal Pod Autoscaler)。HPA可以根据不同负载情况,自动调整Kubernetes中的Pod副本数量。

    1. 执行以下命令,查看推理服务对应的Deployment。

      kubectl get deployment

      预期输出:

      NAME                                             READY   UP-TO-DATE   AVAILABLE   AGE
      bert-tfserving-202207181536-tensorflow-serving   1/1     1            1           2m18s
    2. 执行以下命令,查看推理服务对应的Service。

      kubectl get service

      预期输出:

      NAME                                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
      bert-tfserving-202207181536-tensorflow-serving   ClusterIP   172.16.52.170   <none>        8500/TCP,8501/TCP   2m45s
    3. 使用以下模板创建bert-tfserving-eci-hpa.yaml文件。

      apiVersion: autoscaling/v2beta2
      kind: HorizontalPodAutoscaler
      metadata:
        name: bert-tfserving-eci-hpa
        namespace: default
      spec:
        scaleTargetRef:
          apiVersion: apps/v1
          kind: Deployment
          name: bert-tfserving-202207181536-tensorflow-serving
        minReplicas: 1
        maxReplicas: 10
        metrics:
        - type: External
          external:
            metric:
              name: sls_ingress_qps
              selector:
                matchLabels:
                  sls.project: "k8s-log-{cluster id}"
                  sls.logstore: "nginx-ingress"
                  sls.ingress.route: "default-bert-tfserving-202207181536-tensorflow-serving-8501"
            target:
              type: AverageValue
              averageValue: 10
                                      

      关键参数说明如下:

      参数

      说明

      scaleTargetRef

      设置当前HPA绑定的对象,本文配置为步骤a中,推理服务对应的Deployment名称。

      minReplicas

      最小副本数。

      maxReplicas

      最大副本数。

      sls.project

      集群的日志项目名称,配置规则为k8s-log-{cluster id}

      sls.logstore

      日志库的名称,默认值为nginx-ingress

      sls.ingress.route

      Ingress路由,配置规则为{namespace}-{service name}-{service port}

      metricname

      指标名称,本文配置为sls_ingress_qps

      targetaverageValue

      触发弹性扩容的QPS值。本文配置为10,表示当QPS大于10时,触发弹性扩容。

    4. 执行以下命令,查看HPA状态。

      kubectl get hpa

      预期输出:

      NAME                     REFERENCE                                                   TARGETS      MINPODS   MAXPODS   REPLICAS   AGE
      bert-tfserving-eci-hpa   Deployment/bert-tfserving-202207181536-tensorflow-serving   0/10 (avg)   1         10        1          116s
  5. 配置公网Ingress。

    通过arena serve tensorflow命令部署的推理服务默认提供的是ClusterIP,不能直接通过公网访问。因此需要为推理服务创建一个公网Ingress,方便进行访问。

    1. 登录容器服务管理控制台,在左侧导航栏选择集群

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择网络 > 路由

    3. 路由页面上方,选择推理服务所在的命名空间,然后单击创建Ingress,配置如下参数。关于参数的更多信息,请参见创建Nginx Ingress

      • 名称:本文配置为bert-tfserving

      • 规则

        • 域名:自定义域名,例如:test.example.com

        • 路径映射

          • 路径:不做配置,保留根路径/

          • 匹配规则:默认(ImplementationSpecific)。

          • 服务名称:本文配置为步骤b中获取的服务名称bert-tfserving-202207181536-tensorflow-serving

          • 端口:本文配置为8501

    4. 路由页面的规则列下,查看目标Ingress的地址。

  6. 使用步骤5获取的地址,对推理服务进行压测。当QPS大于HPA中配置的averageValue时,触发扩容,Pod数量不超过maxReplicas;当QPS小于averageValue时,触发缩容。