跳转到主要内容

热门内容

今日:


总体:


最近浏览:


Chinese, Simplified

category

NVIDIA Triton推理服务器是一款开源的人工智能模型服务软件,可简化大规模生产中训练有素的人工智能模块的部署。客户端可以远程向服务器管理的任何模型提供的HTTP或gRPC端点发送推理请求。

NVIDIA Triton可以管理任意数量和混合型号(受系统磁盘和内存资源限制)。它还支持多种深度学习框架,如TensorFlow、PyTorch、NVIDIA TensorRT等。这为开发人员和数据科学家提供了灵活性,他们不再需要使用特定的模型框架。NVIDIA Triton旨在与Kubernetes轻松集成,在数据中心进行大规模部署。

多实例GPU(MIG)可以最大限度地提高A100 GPU和新发布的A30 GPU的GPU利用率。它还可以让多个用户共享一个GPU,方法是并行运行多个工作负载,就好像有多个更小的GPU一样。MIG功能可以将单个GPU划分为多个GPU分区,称为GPU实例。每个实例都有专用的内存和计算资源,因此硬件级别的隔离确保了同时执行工作负载,并保证了服务质量和故障隔离。

在这篇文章中,我们分享以下最佳实践:

  • 在A100上使用MIG并行部署多个Triton推断服务器
  • 使用Kubernetes和Prometheus监控堆栈,根据推理请求的数量自动调整Triton推理服务器的数量。
  • 使用NGINX Plus负载均衡器在不同的Triton推理服务器之间均匀分配推理负载。


这一想法可以应用于单个节点或多个节点上的多个A100或A30 GPU,用于在生产中自动缩放NVIDIA Triton部署。例如,DGX A100允许在Kubernetes Pods上运行多达56台Triton推理服务器(每个A100最多有7台使用MIG的服务器)。


硬件和软件先决条件


要使用MIG,必须启用MIG模式并在A100或A30 GPU上创建MIG设备。您可以使用nvidia-smi手动创建GPU实例和计算实例。或者,使用NVIDIA新的MIG Parted工具NVIDIA MIG Parted,该工具允许管理员声明性地定义一组可能的MIG配置,以应用于节点上的所有GPU。

在运行时,点nvidia-mig-parted位于其中一个配置,nvidia-米格-parted负责应用它。这样,同一个配置文件可以分布在集群中的所有节点上,并且可以使用运行时标志来决定将这些配置中的哪一个应用于节点。因为如果重新启动机器,MIG配置将消失,nvidia MIG parted也使重新启动后更容易创建MIG实例。

在Kubernetes环境中,必须安装NVIDIA设备插件和GPU功能发现插件才能使用MIG。您可以单独安装每个插件,也可以使用云原生NVIDIA GPU Operator,这是一个单独的包,包括在Kubernetes中启用GPU的所有功能。您还可以使用负责安装和插件的NVIDIA部署工具DeepOps,以及普罗米修斯监控堆栈,包括kube Prometheus、Prometheus和普罗米修斯适配器,您应该使用它们来自动缩放Triton推理服务器。

您可以在Kubernetes中使用单一策略或混合策略进行MIG。在这篇文章中,我们建议使用混合策略,因为一个A100 GPU有七个MIG设备,而另一个A100MIG被禁用。

使用Flower演示,该演示使用ResNet50对花朵的图像进行分类。NVIDIA Triton推断服务器容器映像可以从NGC中提取。为Flower演示准备服务器的模型文件(*.plan,config.pbtxt)和客户端。有关更多信息,请参阅使用NVIDIA多实例GPU最小化深度学习推断延迟。

Kubernetes的Flower演示


在设置了flower演示之后,您希望将其扩展到Kubernetes环境中的部署。这样做可以根据推理请求自动调整Triton推理服务器的数量,并在所有服务器之间分配推理负载。因为A100上最多允许七个MIG设备,所以您最多可以有七个Kubernetes Pod,每个Pod都有一个在MIG设备上运行的Triton推理服务器。以下是部署具有自动缩放和负载平衡功能的Triton推断服务器的主要步骤:

  1. 为Triton推理服务器创建Kubernetes部署。
  2. 创建一个Kubernetes服务,将Triton推理服务器作为网络服务公开。
  3. 使用kube Prometheus和PodMonitor向Prometheus展示NVIDIA Triton指标。
  4. 创建ConfigMap以定义自定义度量。
  5. 部署Prometheus Adapter并将自定义度量公开为已注册的Kubernetes APIService。
  6. 创建HPA(Horizontal Pod Autoscaler)以使用自定义度量。
  7. 使用NGINX Plus负载均衡器在所有Triton推理服务器之间分配推理请求。


以下各节提供了实现这些目标的分步指南。

为Triton推理服务器创建Kubernetes部署


第一步是为Triton推理服务器创建Kubernetes部署。部署为Pods和ReplicaSet提供声明性更新。Kubernetes中的ReplicaSet同时启动同一Pod的多个实例。

下面的flower-replicas3.yml文件创建了三个复制的Pod,由.spec.creplicas字段表示,该字段可以是1到7之间的任何数字。.spec.selector字段定义部署如何查找要管理的Pod。每个Pod运行一个名为flower的容器,该容器运行20.12-py3版本的Triton推理服务器映像。与NVIDIA Triton端口号相同,容器端口8000、8001和8002分别为HTTP、gRPC和NVIDIA Triton指标保留。

.resources.limits字段为使用混合策略的每个Pod指定一个具有5 GB内存的MIG设备。nvidia.com/mig-1g.5gb表示法是特定于混合策略的,必须针对您的Kubernetes集群进行相应调整。在本例中,NVIDIA Triton的模型存储在使用NFS协议的共享文件系统中。如果您没有共享文件系统,则必须确保将模型加载到所有工作节点,以便Kubernetes启动的Pods可以访问。

apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: flower
   labels:
     app: flower
 spec:
   replicas: 3
   selector:
     matchLabels:
       app: flower
   template:
     metadata:
       labels:
         app: flower
     spec:
       volumes:
       - name: models
         nfs:
           server: <IP address of the server>
           path: <path/to/flowerdemo/model/files>
           readOnly: false
       containers:
         - name: flower
           ports:
           - containerPort: 8000
             name: http-triton
           - containerPort: 8001
             name: grpc-triton
           - containerPort: 8002
             name: metrics-triton
           image: "nvcr.io/nvidia/tritonserver:20.12-py3"
           volumeMounts:
           - mountPath: /models
             name: models
           command: ["/bin/sh", "-c"]
           args: ["cd /models /opt/tritonserver/bin/tritonserver --model-repository=/models --allow-gpu-metrics=false --strict-model-config=false"]
           resources:
             limits:
               nvidia.com/mig-1g.5gb: 1   

使用命令kubectl apply创建Kubernetes部署:

 $ kubectl apply -f flower-replicas3.yml
 deployment.apps/flower created 

确认已创建三个Pod:

$ kubectl get pods
 NAME                               READY  STATUS  RESTARTS   AGE
 flower-5cf8b78894-2qqz8   1/1     Running            0          5s
 flower-5cf8b78894-g679c   1/1     Running            0          5s
 flower-5cf8b78894-xswwj   1/1     Running            0          5s 

因为在此步骤中部署了ReplicaSet,所以可以使用命令kubectl scale手动放大或缩小Pod编号:

$ kubectl scale deployment flower --replicas=7
 deployment.apps/flower scaled
 $ kubectl get pods
 NAME                              READY   STATUS     RESTARTS   AGE
 flower-5cf8b78894-2qqz8   1/1     Running             0          69s
 flower-5cf8b78894-5znzt   1/1       Running            0          5s
 flower-5cf8b78894-g679c   1/1     Running            0          69s
 flower-5cf8b78894-gwgm6   1/1     Running            0          5s
 flower-5cf8b78894-shm2s   1/1     Running            0          5s
 flower-5cf8b78894-wrn9p   1/1     Running            0          5s
 flower-5cf8b78894-xswwj   1/1     Running            0          69s 

为Triton推理服务器创建Kubernetes服务


第二步是创建一个Kubernetes服务,将Triton推理服务器作为网络服务公开,以便客户端可以向服务器发送推理请求。创建服务时,选择自动创建外部负载平衡器的选项,如.type字段所示。这提供了一个外部可访问的IP地址,用于将流量发送到节点上的正确端口。以下代码示例是flower-service.yml文件:

apiVersion: v1
 kind: Service
 metadata:
   name: flower
   labels:
     app: flower
 spec:
   selector:
     app: flower
   ports:
     - protocol: TCP
       port: 8000
       name: http
       targetPort: 8000
     - protocol: TCP
       port: 8001
       name: grpc
       targetPort: 8001
     - protocol: TCP
       port: 8002
       name: metrics
       targetPort: 8002
   type: LoadBalancer 

同样,使用以下命令创建Kubernetes服务:

$ kubectl apply -f flower-service.yml
 service/flower created 
 

确认服务已创建:

$ kubectl get svc
 NAME    TYPE               CLUSTER-IP EXTERNAL-IP   PORT(S)       AGE
 flower   LoadBalancer   10.233.24.169   <pending>     8000:31268/TCP,8001:32231/TCP,8002:30499/TCP                            69s 

创建服务的另一种方法是使用命令kubectl expose。服务文件可以通过kubectl edit svc metrics命令进行编辑:

$ kubectl expose deployment flower --type=LoadBalancer --name=metrics
 service/metrics exposed 

现在,Triton推理服务器已准备好接收来自远程客户端的推理请求(图1)。如果客户端发送推理请求,则客户端可以查看花朵图像的分类结果,以及每个推理请求的吞吐量和端到端延迟。

Figure 1. (left) Clients sending inference requests to Triton Inference Servers running on MIG devices in Kubernetes. (right) The client getting classification results and performance numbers.

到目前为止,您有多个Triton推理服务器在Kubernetes环境中的MIG设备上运行,对客户端发送的花朵图像进行推理,您可以手动更改服务器的数量。在接下来的部分中,您将对其进行改进,以便可以根据客户端请求自动缩放服务器的数量。

使用Prometheus刮取NVIDIA Triton指标


要自动更改运行在Kubernetes Pods上的Triton推理服务器的数量,请首先收集可用于定义自定义指标的NVIDIA Triton指标。由于多个Kubernetes Pod中有多组NVIDIA Triton指标,因此您应该部署一个PodMonitor,告诉Prometheus从所有Pod中抓取指标。

Prometheus是一个开源的系统监控和警报工具包,提供由度量名称和键/值对标识的时间序列数据。PromQL是一种灵活的查询语言,用于查询普罗米修斯的度量。

为Prometheus创建PodMonitor


PodMonitor定义了对一组Pod的监控,用于普罗米修斯发现目标。在flower-pod-monitor.yml文件中,定义一个PodMonitor来监视服务器的pod,如.spec.selector字段所示。您还需要kube prometheus,它包括prometheus的部署,并抓取将Prometheu斯链接到各种度量端点的目标配置,如.spec.podMetricsEndpoints字段所示。Prometheus每隔10秒从这些端点抓取NVIDIA Triton指标,这些指标由.interval字段定义。

 apiVersion: monitoring.coreos.com/v1
 kind: PodMonitor
 metadata:
   name: kube-prometheus-stack-tritonmetrics
   namespace: monitoring
   labels:
       release: kube-prometheus-stack
 spec:
    selector:
       matchLabels:
          app: flower
    namespaceSelector:
       matchNames:
          - default
    podMetricsEndpoints:
    - port: metrics-triton
       interval: 10s
       path: /metrics 

Prometheus识别PodMonitor的一个常见问题与不正确的标记有关,该标记与普罗米修斯自定义资源定义范围不匹配。要匹配NVIDIA Triton Deployment的标签,请确保.spec.selector.matchLabels字段为app:flower,.spec.namespaceSelector.matchNames字段为-default。两者应与NVIDIA Triton Deployment位于同一命名空间下。这可以通过检查flower-replicas3.yml文件中的相关标签来确认。要匹配kube prometheus的标签,还请确保.metadata.labels字段是release:kube promotheus堆栈。使用以下命令检查标签:

$ kubectl get Prometheus -n monitoring
    NAME                                                 VERSION   REPLICAS   AGE
    kube-prometheus-stack-prometheus   v2.21.0               1          56d
    $ kubectl describe Prometheus kube-prometheus-stack-prometheus -n monitoring
    Name:         kube-prometheus-stack-prometheus
    Namespace:    monitoring
    Labels:       app=kube-prometheus-stack-prometheus
               chart=kube-prometheus-stack-10.0.2
               heritage=Helm
               release=kube-prometheus-stack
    Annotations:  <none>
    API Version:  monitoring.coreos.com/v1
    Kind:         Prometheus  
    Metadata: 
    ……
  
       Pod Monitor Namespace Selector:
       Pod Monitor Selector:
          Match Labels:
             Release:   kube-prometheus-stack 

使用命令kubectl apply-f flower-pod-monitor.yml部署PodMonitor并确认:

$ kubectl get PodMonitor -n monitoring
     NAME                                                  AGE
     kube-prometheus-stack-tritonmetrics   20s 

使用Prometheus查询NVIDIA Triton指标


默认情况下,普罗米修斯提供了一个用户界面,可以在普罗米修斯服务器的9090端口上访问。在web浏览器中打开“普罗米修斯”,然后选择“状态”、“目标”。您可以看到,kube prometheus正确地检测到了来自三台服务器的指标,并将其添加到prometheus中进行报废。

您可以单独查询任何NVIDIA Triton度量,如nv_inference_queue_duration_us或nv_inference _request_success,也可以使用PromQL查询以下自定义度量,并获得Prometheus计算的三个值(图2)。将avg相加,得到三个Pod的平均值:

avg(delta(nv_inference_queue_duration_us[30s])/(1+delta(nv_inference_request_success[30s]))).

当您选择“图形”时,普罗米修斯还会以图形的形式提供时间序列数据。我们将在下一节中提供有关此指标的更多信息。


自动缩放Triton推断服务器

Figure 3. The Prometheus adapter communicates with Kubernetes and Prometheus

现在您已经让Prometheus监视服务器,您应该部署Prometheus适配器,它知道如何与Kubernetes和Prometheu斯通信(图3)。适配器可以帮助您使用Prometheus收集的指标来做出缩放决策。适配器定期从Prometheus收集可用度量的名称,然后只公开遵循特定形式的度量。这些指标由API服务公开,HPA可以很容易地使用这些指标。

可选:启用允许绑定
 

在Kubernetes集群中,基于角色的访问控制(RBAC)是规范对不同对象访问的常用方法。对于本例,必须允许在不同名称空间中运行的HPA访问度量API提供的度量。RBAC的配置与Kubernetes集群的配置有很大不同。有关如何使用基于角色的访问控制的更多信息,请参阅使用RBAC授权。

在演示中,您可以创建一个具有许可绑定的ClusterRoleBinding对象,以允许kubelet用户通过发出以下命令访问所有Pod。这有效地禁用了Kubernetes集群中的任何类型的安全性,并且不能用于生产环境。

$kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --user=admin --user=kubelet --group=system:serviceaccounts 

 

创建ConfigMap以定义自定义度量


首先,告诉普罗米修斯适配器如何收集特定的度量。您使用两个NVIDIA Triton度量来定义HPA执行自动缩放的ConfigMap中的自定义度量avg_time_queue_us。ConfigMap有一个键,该值看起来像配置格式的片段。在ConfigMap文件customimetrics-server-config.yml中,使用以下值:

  • nv_inference_request_success[30]是过去30秒内成功的推理请求数。
  • nv_inference_queue_duration_us是以微秒为单位的累计推理排队持续时间。
     

自定义度量是指过去30秒内每个推理请求的平均队列时间,HPA根据该时间决定是否更改副本编号。

在配置Prometheus适配器时,重要的是度量要有一个命名的端点,例如要寻址的Pod。以后无法从度量API查询未寻址的度量。添加.deverrides字段以强制稍后在API中公开pod和命名空间。

apiVersion: v1
 kind: ConfigMap
 metadata:
   name: adapter-config
   namespace: monitoring
 data:
   triton-adapter-config.yml: |
     rules:
     - seriesQuery: 'nv_inference_queue_duration_us{namespace="default",pod!=""}'
       resources:
         overrides:
           namespace:
             resource: "namespace"
           pod:
             resource: "pod"
       name:
         matches: "nv_inference_queue_duration_us"
         as: "avg_time_queue_us"
      metricsQuery: 'avg(delta(nv_inference_queue_duration_us{<<.LabelMatchers>>}[30s])/
 (1+delta(nv_inference_request_success{<<.LabelMatchers>>}[30s]))) by (<<.GroupBy>>)'
  
      Create the ConfigMap and confirm it:
 $ kubectl apply -f custom-metrics-server-config.yml
 configmap/adapter-config created
 $ kubectl get configmap -n monitoring
 NAME                                                      DATA   AGE
 adapter-config                                            1        22s 

为Kubernetes度量API创建Prometheus适配器


HPA必须为Prometheus适配器创建Kubernetes部署、服务和APIService,才能对此自定义度量做出反应。以下代码示例是部署文件custommetrics-server-deployml.yml。它使用上一步中的ConfigMap,这告诉适配器收集自定义度量。它还创建了Deployment,该Deployment派生适配器Pod以从Prometheus中提取自定义度量。containers.config字段必须与.mountPath字段和上一步骤中在ConfigMap中创建的文件名triton-adapter-configl.yml匹配。

 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: triton-custom-metrics-apiserver
   namespace: monitoring
   labels:
     app: triton-custom-metris-apiserver
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: triton-custom-metrics-apiserver
   template:
     metadata:
       labels:
         app: triton-custom-metrics-apiserver
     spec:
       containers:
       - name: custom-metrics-server
         image: quay.io/coreos/k8s-prometheus-adapter-amd64:v0.4.1
         args:
         - --cert-dir=/tmp
         - --prometheus-url=<IP address:9090>
         - --metrics-relist-interval=30s
         - --v=10
         - --config=/etc/config/triton-adapter-config.yml
         - --secure-port=6443
         ports:
         - name: main-port
           containerPort: 6443
         volumeMounts:
         - name: config-volume
           mountPath: /etc/config
           readOnly: false
       volumes:
       - name: config-volume
         configMap:
           name: adapter-config

为Prometheus适配器创建一个Kubernetes服务。在以下文件中,custommetrics-server-service.yml,.spec.selector。字段必须与部署中的标签app:triton custom-metris-apiserver匹配,以指定提供服务的Pod。

apiVersion: v1
 kind: Service
 metadata:
   name: triton-custom-metrics-api
   namespace: monitoring
 spec:
   selector:
     app: triton-custom-metrics-apiserver
   ports:
   - port: 443
     targetPort: 6443 

接下来,创建一个APIService,以便Kubernetes可以访问Prometheus适配器。然后,HPA可以获取自定义度量。以下代码块是APIService文件customimetrics-server-APIService.yml。.spec.service字段必须与服务文件的.metadata字段匹配。为了允许自动缩放器访问自定义度量,您应该向API聚合器注册该度量。此处需要使用的API是custom.metrics.k8s.io/v1 beta1。

 apiVersion: apiregistration.k8s.io/v1beta1
 kind: APIService
 metadata:
   name: v1beta1.custom.metrics.k8s.io
 spec:
   insecureSkipTLSVerify: true
   group: custom.metrics.k8s.io
   groupPriorityMinimum: 100
   versionPriority: 5
   service:
     name: triton-custom-metrics-api
     namespace: monitoring
   version: v1beta1 

在部署Prometheus适配器之前,您可以看到API点上没有可用的指标:

$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq
 Error from server (NotFound): the server could not find the requested resource 

使用命令kubectl apply来应用前面提到的三个.yml文件中的配置。为Prometheus适配器创建APIService后,您可以看到自定义度量可用:

$ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq .
 {
   "kind": "APIResourceList",
   "apiVersion": "v1",
   "groupVersion": "custom.metrics.k8s.io/v1beta1",
   "resources": [
     {
       "name": "namespaces/avg_time_queue_us",
       "singularName": "",
       "namespaced": false,
       "kind": "MetricValueList",
      "verbs": [
      "get"
      ]
      },
      {
       "name": "pods/avg_time_queue_us",
       "singularName": "",
       "namespaced": true,
       "kind": "MetricValueList",
      "verbs": [
      "get"
      ]
      }
   ]
 }  
 $ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq .
 {
   "kind": "APIResourceList",
   "apiVersion": "v1",
   "groupVersion": "custom.metrics.k8s.io/v1beta1",
   "resources": [
     {
       "name": "namespaces/avg_time_queue_us",
       "singularName": "",
       "namespaced": false,
       "kind": "MetricValueList",
      "verbs": [
      "get"
      ]
      },
      {
       "name": "pods/avg_time_queue_us",
       "singularName": "",
       "namespaced": true,
       "kind": "MetricValueList",
      "verbs": [
      "get"
      ]
      }
   ]
 } 

您还可以检查此自定义度量的当前值,该值为0,因为当前没有来自客户端的推理请求。在这里,您从默认名称空间中选择所有Pod,其中部署了flower演示:

$ kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/avg_time_queue_us | jq .
 {
   "kind": "MetricValueList",
   "apiVersion": "custom.metrics.k8s.io/v1beta1",
   "metadata": {
     "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/avg_time_queue_us"
   },
   "items": [
      {
       "describedObject": {
      "kind": "Pod",
      "namespace": "default",
      "name": "flower-5cf8b78894-jng2g",
         "apiVersion": "/v1"
      },
       "metricName": "avg_time_queue_us",
      "timestamp": "2021-03-25T15:49:10Z",
      "value": "0"
      }
   ]
 } 

部署HPA


HPA根据观察到的指标自动缩放复制控制器、部署、复制集或有状态集中的Pod数量。现在,您可以创建一个使用自定义度量的HPA。HPA根据以下等式控制在Kubernetes中部署的复制副本的数量。它根据所需度量值和当前度量值之间的比率进行操作,并返回所需副本的数量:


R=ceil \left(CR\cdot\frac{CV}{DV}\right)
在这个公式中,使用了以下内容:

  • R是Kubernetes拥有的复制副本的数量。
  • CR是当前复制副本的数量。
  • CV是当前度量:在这种情况下,是来自所有服务器的自定义度量值的平均值。
  • DV是所需的度量值。


当R与CR不同时,HPA通过作用于Kubernetes部署(Pods)来增加或减少副本的数量。基本上,只要当前度量值和所需度量值之间的比率大于1,就可以部署新的副本。

以下HPA文件flower-HPA.yml自动缩放Triton推断服务器的部署。它使用由.sepc.metrics字段指示的Pods度量,该字段取自动缩放目标控制的所有Pod中给定度量的平均值。.spec.metrics.targetAverageValue字段是通过考虑来自所有Pod的自定义度量的值范围来指定的。该字段触发HPA定期调整副本的数量,以使观察到的自定义度量与目标值相匹配。

 apiVersion: autoscaling/v2beta1
 kind: HorizontalPodAutoscaler
 metadata:
     name: flower-hpa
 spec:
     scaleTargetRef:
       apiVersion: apps/v1beta1
       kind: Deployment
       name: flower
     minReplicas: 1
     maxReplicas: 7
     metrics:
     - type: Pods
       pods:
         metricName: avg_time_queue_ms
         targetAverageValue: 50 

使用命令kubectl apply-f flower-HPA.yml创建HPA并确认:

 $ kubectl get hpa
 NAME         REFERENCE      TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
 flower-hpa   Deployment/flower   0/50              1                 7                    1              22s 

如果客户端开始向服务器发送推理请求,新的HPA可以获取部署的自定义度量,并建立所需的Pod数量。例如,当推理请求不断增加时,HPA将Pod的数量从1增加到2,并逐渐增加到7,这是A100 GPU上的最大Pod数量。最后,当客户端停止发送推理请求时,HPA将Replica数量减少到只有1(图5)。

Figure 5. Using the command kubectl describe hpa flower-hpa to check how HPA increase or decrease the number of Pods.

NGINX Plus的负载平衡


负载平衡是为了在可用服务器之间以最佳方式分配来自客户端的负载。早些时候,您选择了Kubernetes内置的负载均衡器,即第4层(传输层)负载均衡器,它易于部署,但有使用gRPC的限制。

在这个演示中,使用Prometheus,您发现autoscaler新添加的Pods无法使用Kubernetes内置的负载均衡器来获得工作负载。要改进这一点,请使用NGINX Plus,它是一个第7层(应用层)负载均衡器。工作量平均分布在所有Pod中,包括新扩大的Pod。

  • 首先,您应该创建一个NGINX Plus映像,因为Docker Hub无法提供NGINX Plus的商业产品。使用DockerHub中的NGINX开源映像在Docker容器中创建一个NGINX实例。然后,将本地映像推送到专用Docker注册表中。
  • 接下来,要部署NGINX Plus,请使用以下命令将要部署NGINX Plus的节点标记为role=nginxplus:

$ kubectl label node <IP address or node name> role=nginxplus

  • 修改服务以将clusterIP设置为none,以便所有副本端点都由NGINX Plus公开和标识。为了避免混淆,请创建一个新的服务文件flower-Service-nginx.yml,并应用它:
 apiVersion: v1
 kind: Service
 metadata:
   name: flower-nginx
   labels:
     app: flower
 Spec:
   clusterIP: None 
   selector:
     app: flower
   ports:
     - protocol: TCP
       port: 8000
       name: http
       targetPort: 8000
     - protocol: TCP
       port: 8001
       name: grpc
       targetPort: 8001 
  • 接下来,为NGINX创建一个配置文件。下面的代码示例假设您使用的是位置/path/to/nginx/config/nginx.conf。
resolver <K8s DNS server IP> valid=5s;
 upstream backend {
    zone upstream-backend 64k;
    server <clusterIP FQDN: 8000> resolve;
 }
  
 upstream backendgrpc {
    zone upstream-backend 64k;
    server <clusterIP FQDN:8001> resolve;
 }
  
 server {
    listen 80;
    status_zone backend-servers;
  
    location / {
      proxy_pass http://backend;
      health_check uri=/v2/health/ready;
    }
 }
  
 server {
         listen 89 http2;
  
         location / {
             grpc_pass grpc://backendgrpc;
         }
 }
  
 server {
     listen 8080;
     root /usr/share/nginx/html;
     location = /dashboard.html { }
     location = / {
        return 302 /dashboard.html;
     }
     location /api {
       api write=on;
     }
 } 
  • 最后,您应该在以下nginxplus-rc.yml文件中为NGINX Plus创建一个ReplicationController。要从私有注册表中提取映像,Kubernetes需要凭据。配置文件中的imagePullSecrets字段指定Kubernetes应该从名为regcred的Secret中获取凭据。在这个配置文件中,您还必须将上一步创建的NGINX配置文件装载到/etc/NGINX/conf.d位置。
  apiVersion: v1
 kind: ReplicationController
 metadata:
   name: nginxplus-rc
 spec:
   replicas: 1
   selector:
     app: nginxplus
   template:
     metadata:
       labels:
         app: nginxplus
     spec:
       nodeSelector:
         role: nginxplus
       imagePullSecrets:
       - name: regcred
       containers:
       - name: nginxplus
         command: [ "/bin/bash", "-c", "--" ]
         args: [ "nginx; while true; do sleep 30; done;" ]
         imagePullPolicy: IfNotPresent
         image: nvcr.io/nvidian/swdl/nginxplus:v1
         ports:
           - name: http
             containerPort: 80
             hostPort: 8085
           - name: grpc
             containerPort: 89
             hostPort: 8087
           - name: http-alt
             containerPort: 8080
             hostPort: 8086
           - name: flower-svc
             containerPort: 8000
             hostPort: 32309
         volumeMounts:
           - mountPath: "/etc/nginx/conf.d"
             name: etc-nginx-confd
       volumes:
         - nfs:
            server: <NFS server IP>
            path: </path/to/nginx/config>
            readOnly: false
           name: etc-nginx-confd 
  • 使用以下命令创建ReplicationController:
kubectl create -f nginxplus-rc.yml  
  • 验证Deployment。您应该会发现NGINX Plus正在运行:
 $kubectl get pods
 NAME                      READY   STATUS    RESTARTS   AGE
 flower-5cf8b78894-jng2g   1/1     Running   0          8h
 nginxplus-rc-nvj7b        1/1     Running   0          10s 
  • 现在,当客户端向服务器发送推理请求时,您可以看到NGINX Plus Dashboard(图6):
    • 自动缩放器将播客的数量从一个逐渐增加到七个。
    • 工作负载在所有Pod之间均匀分布,如Traffic中所示。
       

您还可以通过检查Prometheus中所有Pod的度量值或自定义度量值来确认新添加的Pod正忙于工作。

Figure 6. NGINX Plus dashboard showing the number of NVIDIA Triton servers scaled by HPA and each server’s information.
 

结论


这篇文章展示了在Kubernetes环境中使用MIG大规模部署Triton推理服务器的分步说明和代码。我们还向您展示了如何使用两种不同类型的负载均衡器自动缩放服务器数量和平衡工作负载。我们记录了所有步骤和结果,您还可以观看使用多实例GPU(MIG)和Kubernetes GTC'21会话的Triton大规模部署。

有关使用MIG在单个A100 GPU上并行运行多个深度学习工作负载的更多信息,请参阅使用MIG充分利用NVIDIA A100 GPU。

相关资源

本文地址
最后修改
星期日, 九月 8, 2024 - 19:41
Article