NVIDIA Triton 推理服務器是一款開源人工智能模型服務軟件,可簡化在生產中大規(guī)模部署經過培訓的人工智能模型。對于服務器管理的任何模型,客戶端可以遠程向提供的 HTTP 或 gRPC 端點發(fā)送推斷請求。
NVIDIA Triton 可以管理任意數(shù)量和混合型號(受系統(tǒng)磁盤和內存資源的限制)。它還支持多種深度學習框架,如 TensorFlow 、 PyTorch 、 NVIDIA TensorRT 等。這為開發(fā)者和數(shù)據(jù)科學家提供了靈活性,他們不再需要使用特定的模型框架。 NVIDIA Triton 旨在輕松與 Kubernetes 集成,以便在數(shù)據(jù)中心進行大規(guī)模部署。
多實例并行運行多個工作負載( MIG )可以最大化 A100 GPU 和新發(fā)布的 A30 GPU 的 GPU 利用率。它還可以讓多個用戶通過 GPU 共享一個 GPU ,就像有多個更小的 GPU 一樣。 MIG 功能可以將單個 GPU 劃分為多個 GPU 分區(qū),稱為 GPU 實例。每個實例都有專用的內存和計算資源,因此硬件級別的隔離可以確保同時執(zhí)行工作負載,同時保證服務質量和故障隔離。
在本文中,我們分享以下最佳實踐:
在 A100 上使用 MIG 并行部署多個 Triton 推理服務器
使用 Kubernetes 和 Prometheus 監(jiān)控堆棧根據(jù)推理請求的數(shù)量自動調整 Triton 推理服務器的數(shù)量。
使用 NGINX Plus 負載平衡器在不同的 Triton 推理服務器之間均勻分配推理負載。
這一思想可以應用于單個節(jié)點或多個節(jié)點上的多個 A100 或 A30 GPU ,以便在生產中自動縮放 NVIDIA Triton 部署。例如, DGX A100 允許在 Kubernetes 吊艙上運行多達 56 個 Triton 推理服務器(每個 A100 最多有七個使用 MIG 的服務器)。
硬件和軟件先決條件
要使用 MIG ,必須啟用 MIG 模式并在A100或A30 GPU 上創(chuàng)建 MIG 設備。您可以使用nvidia-smi創(chuàng)建 GPU 實例并手動計算實例?;蛘?,使用 NVIDIA 新的 MIG 分離工具nvidia-mig-parted,該工具允許管理員定義一組可能的 Clara 配置,以應用于節(jié)點上的所有 GPU 。
在運行時,將nvidia-mig-parted指向其中一個配置,nvidia-mig-parted負責應用它。通過這種方式,相同的配置文件可以分布在集群中的所有節(jié)點上,并且可以使用運行時標志來決定將哪些配置應用于節(jié)點。因為如果重新啟動機器, MIG 配置將消失,nvidia-mig-parted還使重新啟動后創(chuàng)建 MIG 實例變得更容易。
在 Kubernetes 環(huán)境中,必須安裝 NVIDIA 設備插件和 GPU 功能發(fā)現(xiàn)插件才能使用 MIG 。您可以單獨安裝每個插件,或者使用云本機 NVIDIA GPU 運算符,它是一個包,包含在 Kubernetes 中啟用 GPU 的所有內容。您還可以使用 NVIDIA 部署工具DeepOps,該工具負責安裝和插件,以及普羅米修斯監(jiān)控堆棧,包括kube-prometheus、普羅米修斯和普羅米修斯適配器,您應將其用于自動校準 Triton 推理服務器。
您可以在 Kubernetes 中使用 MIG 的單一策略或混合策略中的任意一個。在本文中,我們建議采用混合策略,因為一個 A100 GPU 有七個 MIG 設備,而另一個 A100 MIG 被禁用。
使用花卉演示,它使用 ResNet50 對花卉圖像進行分類。 NVIDIA Triton 推理服務器容器映像可以從NGC中提取。為 Flower 演示準備服務器的模型文件(*.plan, config.pbtxt)和客戶端。有關更多信息,請參閱使用 NVIDIA 多實例 GPU 最小化深度學習推理延遲。
庫伯內特斯花卉演示
設置 flower 演示后,您希望將其擴展到 Kubernetes 環(huán)境中的部署。這樣可以根據(jù)推理請求自動調整 Triton 推理服務器的數(shù)量,并在所有服務器之間分配推理負載。因為 A100 上最多允許七個 MIG 設備,所以您最多可以有七個 Kubernetes 吊艙,每個吊艙都有一個 Triton 推理服務器在 MIG 設備上運行。以下是部署具有自動縮放和負載平衡的 Triton 推理服務器的主要步驟:
為 Triton 推理服務器創(chuàng)建 Kubernetes 部署。
創(chuàng)建 Kubernetes 服務以將 Triton 推理服務器公開為網絡服務。
使用 kube Prometheus 和 PodMonitor 向 Prometheus 公開 NVIDIA Triton 度量。
創(chuàng)建 ConfigMap 以定義自定義度量。
部署 Prometheus 適配器并將自定義度量公開為注冊的 Kubernetes API 服務。
創(chuàng)建 HPA (水平吊艙自動縮放)以使用自定義度量。
使用 NGINX Plus 負載平衡器在所有 Triton 推理服務器之間分配推理請求。
以下各節(jié)提供了實現(xiàn)這些目標的分步指南。
為 Triton 推理服務器創(chuàng)建 Kubernetes 部署
第一步是為 Triton 推理服務器創(chuàng)建庫伯內特斯部署。部署為Pods和ReplicaSets提供了動態(tài)更新。Kubernetes中的復制集同時啟動同一Pod的多個實例。
以下flower-replicas3.yml文件創(chuàng)建了三個復制的 POD ,由.spec.replicas字段指示,該字段可以是 1 到 7 之間的任意數(shù)字。.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特定于混合策略,必須根據(jù) Kubernetes 集群進行相應調整。在本例中, NVIDIA Triton 的模型使用 NFS 協(xié)議存儲在共享文件系統(tǒng)上。如果沒有共享文件系統(tǒng),則必須確保將模型加載到所有工作節(jié)點,以便 Kubernetes 啟動的 POD 可以訪問。
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:path: 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
創(chuàng)建 Kubernetes 部署:
$ kubectl apply -f flower-replicas3.yml deployment.apps/flower created
確認創(chuàng)建了三個吊艙:
$ 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 推理服務器創(chuàng)建 Kubernetes 服務
第二步是創(chuàng)建一個庫伯內特斯服務,將 Triton 推理服務器作為網絡服務公開,以便客戶端可以向服務器發(fā)送推理請求。創(chuàng)建服務時,選擇自動創(chuàng)建外部負載平衡器的選項,如.type
字段所示。這提供了一個外部可訪問的 IP 地址,可將流量發(fā)送到節(jié)點上的正確端口。以下代碼示例是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
類似地,使用以下命令創(chuàng)建 Kubernetes 服務:
$ kubectl apply -f flower-service.yml service/flower created
確認已創(chuàng)建服務:
$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE flower LoadBalancer 10.233.24.1698000:31268/TCP,8001:32231/TCP,8002:30499/TCP 69s
創(chuàng)建服務的另一種方法是使用命令kubectl expose
??赏ㄟ^kubectl edit svc metrics
命令編輯服務文件:
$ kubectl expose deployment flower --type=LoadBalancer --name=metrics service/metrics exposed
現(xiàn)在, Triton 推理服務器已準備好接收來自遠程客戶端的推理請求(圖 1 )。如果客戶端發(fā)送推斷請求,客戶端可以查看花卉圖像的分類結果以及每個推斷請求的吞吐量和端到端延遲。
圖 1 。(左)向 Kubernetes 中 MIG 設備上運行的 Triton 推理服務器發(fā)送推理請求的客戶端 ( 右)獲得分類結果和性能編號的客戶。
到目前為止,您在 Kubernetes 環(huán)境中的 MIG 設備上運行多個 Triton 推理服務器,對客戶端發(fā)送的花朵圖像進行推理,您可以手動更改服務器數(shù)量。在接下來的部分中,您將對其進行改進,以便可以根據(jù)客戶機請求自動調整服務器的數(shù)量。
使用普羅米修斯刮取 NVIDIA Triton 指標
要自動更改 Kubernetes 吊艙上運行的 Triton 推理服務器的數(shù)量,請首先收集可用于定義自定義度量的 NVIDIA Triton 度量。因為多個 Kubernetes 吊艙中有多組 NVIDIA Triton 度量,所以您應該部署一個PodMonitor,告訴Prometheus從所有吊艙中獲取度量。
Prometheus 是一個開源的系統(tǒng)監(jiān)控和警報工具包,提供由度量名稱和鍵/值對標識的時間序列數(shù)據(jù)。PromQL,一種靈活的查詢語言,用于從 Prometheus 查詢度量。
為普羅米修斯創(chuàng)建 PodMonitor
PodMonitor定義了一組吊艙的監(jiān)控,用于普羅米修斯發(fā)現(xiàn)目標。在flower-pod-monitor.yml文件中,您可以定義一個 PodMonitor 來監(jiān)視服務器的 pod ,如.spec.selector字段所示。您還需要kube-prometheus,它包括普羅米修斯的部署,并將普羅米修斯鏈接到各種度量端點的目標配置刮取,如.spec.podMetricsEndpoints字段所示。普羅米修斯每 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
與普羅米修斯的 PodMonitor 標識相關的一個常見問題與不符合普羅米修斯自定義資源定義范圍的錯誤標記有關。要匹配 NVIDIA Triton 部署的標簽,請確保.spec.selector.matchLabels
字段為app:flower
,而.spec.namespaceSelector.matchNames
字段為-default
。兩者都應與 NVIDIA Triton 部署位于同一命名空間下。這可以通過檢查flower-replicas3.yml
文件中的相關標簽來確認。要匹配kube-prometheus
的標簽,還要確保.metadata.labels
字段為release: kube-prometheus-stack
。使用以下命令檢查標簽:
$ 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: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
自動縮放 Triton 推理服務器
圖 3 普羅米修斯適配器與庫伯內特斯和普羅米修斯通信
既然普羅米修斯在監(jiān)視服務器,那么應該部署普羅米修斯適配器,它知道如何與庫伯內特斯和普羅米修斯通信(圖 3 )。適配器幫助您使用普羅米修斯收集的指標來做出縮放決策。適配器定期從普羅米修斯收集可用度量的名稱,然后只公開遵循特定形式的度量。這些度量由 API 服務公開, HPA 可以輕松使用。
可選:啟用許可綁定
在 Kubernetes 集群中,基于角色的訪問控制( RBAC )是調節(jié)對不同對象訪問的常用方法。對于本例,必須允許在不同命名空間中運行的 HPA 訪問 metrics API 提供的度量。 RBAC 的配置與 Kubernetes 集群的配置有很大不同。有關如何使用基于角色的訪問控制的更多信息,請參閱使用 RBAC 授權。
在演示中,您可以通過發(fā)出以下命令創(chuàng)建一個具有許可綁定的ClusterRoleBinding對象,以允許 kubelet 用戶訪問所有 POD 。這將有效地禁用 Kubernetes 集群中的任何類型的安全性,并且不得用于生產環(huán)境。
$kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --user=admin --user=kubelet --group=system:serviceaccounts
創(chuàng)建 ConfigMap 以定義自定義度量
首先,告訴普羅米修斯適配器如何收集特定指標。您使用兩個 NVIDIA Triton 度量來定義ConfigMap中的自定義度量avg_time_queue_us
,其中HPA執(zhí)行自動縮放。ConfigMap
有一個鍵,該值看起來像配置格式的片段。在ConfigMap
文件custom-metrics-server-config.yml
中,使用以下值:
-
nv_inference_request_success[30]
是過去 30 秒內成功的推理請求數(shù)。 -
nv_inference_queue_duration_us
是以微秒為單位的累計推理排隊持續(xù)時間。
自定義度量是指過去 30 秒內每個推斷請求的平均隊列時間, HPA 根據(jù)該時間決定是否更改副本號。
在配置 Prometheus 適配器時,重要的是這些指標要有一個命名端點,例如要尋址的 Pod 。以后無法從 metrics API 查詢未尋址的度量。添加.overrides
字段以強制要求pod
和namespace
稍后在 API 中公開。
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 metrics API 創(chuàng)建 Prometheus 適配器
要使 HPA 對該自定義指標作出反應,必須為 Prometheus 適配器創(chuàng)建 Kubernetes 部署、服務和APIService。下面的代碼示例是部署文件custom-metrics-server-deployment.yml
。它使用上一步中的ConfigMap
,它告訴適配器收集自定義度量。它還創(chuàng)建了一個部署,生成適配器盒,從普羅米修斯那里獲取自定義度量。.containers.config
字段必須與.mountPath
字段和上一步ConfigMap
中創(chuàng)建的文件名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=- --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 適配器創(chuàng)建 Kubernetes 服務。在以下文件custom-metrics-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
接下來,創(chuàng)建一個 APIService ,以便 Kubernetes 可以訪問 Prometheus 適配器。然后,可以通過 HPA 獲取自定義度量。以下代碼塊是 APIService 文件custom-metrics-server-apiservice.yml
。.spec.service
字段必須與服務文件的. metadata 字段匹配。要允許 autoscaler 訪問自定義度量,您應該向API 聚合器注冊度量。這里需要使用的 API 是custom.metrics.k8s.io/v1beta1。
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 適配器創(chuàng)建 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 ,因為當前沒有來自客戶端的推斷請求。在這里,您將從default
命名空間中選擇所有 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 根據(jù)觀察到的指標自動縮放復制控制器、部署、復制集或有狀態(tài)集中的 POD 數(shù)量?,F(xiàn)在,您可以創(chuàng)建使用自定義度量的 HPA 。 HPA 根據(jù)以下等式控制部署在 Kubernetes 中的副本數(shù)量。它根據(jù)所需度量值和當前度量值之間的比率進行操作,并返回所需副本的數(shù)量:
在該公式中,使用以下公式:
是 Kubernetes 擁有的副本數(shù)。
是當前的副本數(shù)。
是當前度量:在這種情況下,來自所有服務器的自定義度量值的平均值。
是所需的度量值。
When與 CR 不同, HPA 通過作用于 Kubernetes 部署( Pods )來增加或減少副本的數(shù)量?;旧?,只要當前度量值與所需度量值之間的比率大于 1 ,就可以部署新的副本。
圖 4 。 HPA 比例 NVIDIA Triton 部署
以下 HPA 文件flower-hpa.yml自動縮放 Triton 推理服務器的部署。它使用由.sepc.metrics字段指示的 Pods 度量,該字段獲取自動縮放目標控制的所有 Pods 中給定度量的平均值。.spec.metrics.targetAverageValue字段是通過考慮來自所有 POD 的自定義度量的值范圍來指定的。該字段觸發(fā) HPA 定期調整副本的數(shù)量,以使觀察到的自定義度量與目標值相匹配。
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
創(chuàng)建 HPA 并確認:
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE flower-hpa Deployment/flower 0/50 1 7 1 22s
如果客戶端開始向服務器發(fā)送推斷請求,新的 HPA 可以獲取部署的自定義指標并確定所需的 POD 數(shù)量。例如,當推理請求增加時, HPA 會將 POD 的數(shù)量從 1 增加到 2 ,然后逐漸增加到 7 ,這是 A100 GPU 上的最大 POD 數(shù)量。最后,當客戶端停止發(fā)送推斷請求時, HPA 將副本數(shù)減少到僅 1 (圖 5 )。
圖 5 使用命令 kubectl 描述 hpa 花 hpa 檢查 HPA 如何增加或減少 Pod 數(shù)量 s 。
使用 NGINX Plus 實現(xiàn)負載平衡
負載平衡用于將來自客戶端的負載以最佳方式分布在可用服務器上。在前面,您選擇了 Kubernetes 內置負載平衡器,這是一個第 4 層(傳輸層)負載平衡器,它很容易部署,但是使用gRPC的limitation可以實現(xiàn)。
在這個演示中,使用 Prometheus ,您會發(fā)現(xiàn) autoscaler 新添加的 POD 無法使用 Kubernetes 內置的負載平衡器獲得工作負載。要改進這一點,請使用NGINX Plus,它是第 7 層(應用程序層)負載平衡器。工作負載均勻地分布在所有 POD 中,包括新擴展的 POD 。
首先,您應該創(chuàng)建 NGINX Plus 映像,因為 Docker Hub 無法提供 NGINX Plus 的商業(yè)產品。在 Docker 容器中創(chuàng)建 NGINX 實例使用 Docker Hub 的 NGINX 開源映像。然后,將本地映像推送到私有 Docker 注冊表。
接下來,要部署 NGINX Plus ,請使用以下命令使用role=nginxplus 標記要在其上部署 NGINX Plus 的節(jié)點:
$ kubectl label node
修改服務,將clusterIP設置為none,,以便所有副本端點都由 NGINX Plus 公開和標識。為避免混淆,請創(chuàng)建一個新的服務文件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 創(chuàng)建一個配置文件。下面的代碼示例假定您正在使用位置/path/to/nginx/config/nginx.conf
。
resolvervalid=5s; upstream backend { zone upstream-backend 64k; server resolve; } upstream backendgrpc { zone upstream-backend 64k; server 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 創(chuàng)建一個ReplicationController。要從私有注冊表中提取映像, Kubernetes 需要credentials。配置文件中的imagePullSecrets
字段指定 Kubernetes 應從名為regcred
的機密中獲取憑據(jù)。在此配置文件中,還必須將上一步創(chuàng)建的 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:path: readOnly: false name: etc-nginx-confd
使用以下命令創(chuàng)建 ReplicationController :
kubectl create -f nginxplus-rc.yml
驗證部署。您應該發(fā)現(xiàn) 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
現(xiàn)
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
創(chuàng)建 HPA 并確認:
$ kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE flower-hpa Deployment/flower 0/50 1 7 1 22s
現(xiàn)在,當客戶端向服務器發(fā)送推斷請求時,您可以看到 NGINX Plus 儀表板(圖 6 ):
autoscaler 將豆莢的數(shù)量從 1 逐漸增加到 7 。
工作負載在所有 POD 中均勻分布,如流量所示。
您還可以通過檢查普羅米修斯中所有 POD 的度量值或自定義度量值來確認新添加的 POD 正在工作。
圖 6 NGINX Plus儀表板顯示了按 HPA 縮放的 NVIDIA Triton 服務器數(shù)量和每臺服務器的信息。
Conclusion
這篇文章展示了在 Kubernetes 環(huán)境中使用 MIG 大規(guī)模部署 Triton 推理服務器的分步說明和代碼。我們還向您展示了如何使用兩種不同類型的負載平衡器自動調整服務器數(shù)量和平衡工作負載。
關于作者
Maggie Zhang 是 NVIDIA 的深度學習工程師,致力于深度學習框架和應用程序。她在澳大利亞新南威爾士大學獲得計算機科學和工程博士學位,在那里她從事 GPU / CPU 異構計算和編譯器優(yōu)化。
Dai Yang 是 NVIDIA 的高級解決方案架構師。他負責使用 GPU 和網絡產品定制客戶優(yōu)化的解決方案,重點關注工業(yè)、汽車和 HPC 客戶。 Dai 積極參與 EMEA 地區(qū) DGX 解決方案的規(guī)劃、部署和培訓。在加入 NVIDIA 之前,戴是慕尼黑工業(yè)大學的研究助理,在那里他研究了高性能計算的各個方面,并為 MPI 標準擴展了 MPI 論壇的草案。戴是在 ISC2020 漢斯梅爾獎獲獎團隊的一部分。
Davide Onofrio 是 NVIDIA 的高級深度學習軟件技術營銷工程師。他在 NVIDIA 專注于深度學習技術開發(fā)人員關注內容的開發(fā)和演示。戴維德在生物特征識別、虛擬現(xiàn)實和汽車行業(yè)擔任計算機視覺和機器學習工程師已有多年經驗。他的教育背景包括米蘭理工學院的信號處理博士學位。
審核編輯:郭婷
-
NVIDIA
+關注
關注
14文章
4855瀏覽量
102709 -
服務器
+關注
關注
12文章
8958瀏覽量
85081 -
人工智能
+關注
關注
1789文章
46652瀏覽量
237071
發(fā)布評論請先 登錄
相關推薦
評論