本文說明如何搭配 Azure Red Hat OpenShift 使用 NVIDIA GPU 工作負載。
先決條件
- OpenShift CLI
- jq、moreutils 和 gettext 套件
- Azure Red Hat OpenShift 4.10
如果您需要安裝叢集,請參閱 教學課程:建立 Azure Red Hat OpenShift 4 叢集。 叢集必須是 4.10.x 版或更新版本。
備註
從 4.10 開始,不再需要設定權利即可使用 NVIDIA Operator。 這已大幅簡化 GPU 工作負載的叢集設定。
Linux:
sudo dnf install jq moreutils gettext
macOS
brew install jq moreutils gettext
要求 GPU 配額
依預設,Azure 中的所有 GPU 配額都是 0。 您必須登入 Azure 入口網站並要求 GPU 配額。 由於 GPU 工作者的競爭,您可能必須在實際可以保留 GPU 的區域中佈建叢集。
支援下列 GPU 工作者:
- NC4作為 T4 v3
- NC6s v3
- NC8as T4 v3
- NC12s v3
- NC16作為 T4 v3
- NC24s v3
- NC24rs v3
- NC64 T4 v3 型號
其他 MachineSet 也支援下列執行個體:
- Standard_ND96asr_v4
- NC24ads_A100_v4
- NC48ads_A100_v4
- NC96ads_A100_v4
- ND96amsr_A100_v4
備註
要求配額時,請記住 Azure 是每個核心。 若要要求單一 NC4as T4 v3 節點,您將必須一一組 4 個的形式要求配額。 如果您想要要求 NC16as T4 v3,您將必須要求配額 16 個。
登入 Azure 入口網站。
在搜尋方塊中輸入配額,然後選取 [計算]。
在搜尋方塊中,輸入 NCAsv3_T4,勾選叢集所在的區域方塊,然後選取 [申請加大配額]。
設定配額。
登入叢集
使用具有叢集管理員權限的使用者帳戶登入 OpenShift。 下列範例使用名為 kubadmin 的帳戶:
oc login <apiserver> -u kubeadmin -p <kubeadminpass>
提取祕密 (條件式)
更新您的提取祕密,以確定您可以安裝操作員並連線到 cloud.redhat.com。
備註
如果您已經重新建立已啟用 cloud.redhat.com 的完整提取祕密,請略過此步驟。
登入 cloud.redhat.com。
瀏覽至 https://cloud.redhat.com/openshift/install/azure/aro-provisioned。
選取 [下載提取祕密],並將提取祕密儲存為
pull-secret.txt。這很重要
本節中的其餘步驟必須在與
pull-secret.txt相同的工作目錄中執行。匯出現有的提取祕密。
oc get secret pull-secret -n openshift-config -o json | jq -r '.data.".dockerconfigjson"' | base64 --decode > export-pull.json將下載的提取祕密與系統提取祕密合併,以新增
cloud.redhat.com。jq -s '.[0] * .[1]' export-pull.json pull-secret.txt | tr -d "\n\r" > new-pull-secret.json上傳新祕密檔案。
oc set data secret/pull-secret -n openshift-config --from-file=.dockerconfigjson=new-pull-secret.json您可能需要等候大約 1 小時,所有項目才能與 cloud.redhat.com 同步。
刪除祕密。
rm pull-secret.txt export-pull.json new-pull-secret.json
GPU 機器集
使用 Kubernetes MachineSet 來建立機器集。 下列程序說明如何匯出叢集中的第一部機器,並使用該機器作為範本來建置單一 GPU 機器。
檢視現有的機器集。
為方便設定起見,此範例會使用第一個機器集做為複製品來建立新的 GPU 機器集。
MACHINESET=$(oc get machineset -n openshift-machine-api -o=jsonpath='{.items[0]}' | jq -r '[.metadata.name] | @tsv')儲存範例機器集的複本。
oc get machineset -n openshift-machine-api $MACHINESET -o json > gpu_machineset.json將
.metadata.name欄位變更為新的唯一名稱。jq '.metadata.name = "nvidia-worker-<region><az>"' gpu_machineset.json| sponge gpu_machineset.json確保
spec.replicas符合機器集所需的複本計數。jq '.spec.replicas = 1' gpu_machineset.json| sponge gpu_machineset.json將
.spec.selector.matchLabels.machine.openshift.io/cluster-api-machineset欄位變更以符合.metadata.name欄位。jq '.spec.selector.matchLabels."machine.openshift.io/cluster-api-machineset" = "nvidia-worker-<region><az>"' gpu_machineset.json| sponge gpu_machineset.json將
.spec.template.metadata.labels.machine.openshift.io/cluster-api-machineset變更以符合.metadata.name欄位。jq '.spec.template.metadata.labels."machine.openshift.io/cluster-api-machineset" = "nvidia-worker-<region><az>"' gpu_machineset.json| sponge gpu_machineset.json將
spec.template.spec.providerSpec.value.vmSize變更以符合來自 Azure 所需的 GPU 執行個體類型。此範例中使用的機器為 Standard_NC4as_T4_v3。
jq '.spec.template.spec.providerSpec.value.vmSize = "Standard_NC4as_T4_v3"' gpu_machineset.json | sponge gpu_machineset.json將
spec.template.spec.providerSpec.value.zone變更以符合來自 Azure 所需的區域。jq '.spec.template.spec.providerSpec.value.zone = "1"' gpu_machineset.json | sponge gpu_machineset.json刪除 yaml 檔案的
.status區段。jq 'del(.status)' gpu_machineset.json | sponge gpu_machineset.json驗證 yaml 檔案中的其他資料。
確定已設定正確的 SKU
根據機器集所使用的映像,必須據以設定 和 image.sku 的值image.version。 這是為了確保 Hyper-V 的層代 1 或 2 虛擬機是否使用。 如需詳細資訊,請參閱 此處 。
範例:
如果使用 Standard_NC4as_T4_v3,則支援這兩個版本。 如功能支援中所述。 在此情況下,不需要變更。
Standard_NC24ads_A100_v4如果使用 ,則僅支援第 2 代 VM。
在此情況下,image.sku值必須遵循對應至叢集原始 v2的對等image.sku映像版本。 在這裡範例中,值會是 v410-v2。
您可以使用下列命令找到此項目:
az vm image list --architecture x64 -o table --all --offer aro4 --publisher azureopenshift
Filtered output:
SKU VERSION
------- ---------------
v410-v2 410.84.20220125
aro_410 410.84.20220125
如果叢集是以基底 SKU 映射 aro_410建立,而且機器集中會保留相同的值,則會失敗並出現下列錯誤:
failure sending request for machine myworkernode: cannot create vm: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest" Message="The selected VM size 'Standard_NC24ads_A100_v4' cannot boot Hypervisor Generation '1'.
建立 GPU 機器集
使用下列步驟來建立新的 GPU 機器。 佈建新的 GPU 機器可能需要 10-15 分鐘的時間。 如果此步驟失敗,請登入 Azure 入口網站,並確保沒有可用性問題。 若要這樣做,請移至虛擬機器,並搜尋您先前建立的背景工作角色名稱,以查看 VM 的狀態。
建立 GPU 機器集。
oc create -f gpu_machineset.json此命令將需要數分鐘才能完成。
驗證 GPU 機器集。
機器應該為部署中。 您可以使用下列命令來檢視機器集的狀態:
oc get machineset -n openshift-machine-api oc get machine -n openshift-machine-api一旦機器佈建 (可能需要 5-15 分鐘的時間),機器就會顯示為節點清單中的節點:
oc get nodes您應該會看到具有先前建立名稱
nvidia-worker-southcentralus1的節點。
安裝 NVIDIA GPU作員
本節說明如何建立 nvidia-gpu-operator 命名空間、設定作員群組,以及安裝 NVIDIA GPU 運算符。
建立 NVIDIA 命名空間。
cat <<EOF | oc apply -f - apiVersion: v1 kind: Namespace metadata: name: nvidia-gpu-operator EOF建立操作員群組。
cat <<EOF | oc apply -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: nvidia-gpu-operator-group namespace: nvidia-gpu-operator spec: targetNamespaces: - nvidia-gpu-operator EOF使用下列命令取得最新的 NVIDIA 通道:
CHANNEL=$(oc get packagemanifest gpu-operator-certified -n openshift-marketplace -o jsonpath='{.status.defaultChannel}')
備註
如果您的叢集在建立時未提供提取秘密,叢集將不會包含來自 Red Hat 或來自認證合作夥伴的範例或操作員。 這會導致下列錯誤訊息:
伺服器錯誤 (NotFound):找不到 packagemanifests.packages.operators.coreos.com "gpu-operator-certified"。
若要在 Azure Red Hat OpenShift 叢集上新增您的 Red Hat 提取秘密,請遵循此指南。
使用下列命令取得最新的 NVIDIA 套件:
PACKAGE=$(oc get packagemanifests/gpu-operator-certified -n openshift-marketplace -ojson | jq -r '.status.channels[] | select(.name == "'$CHANNEL'") | .currentCSV')建立訂用帳戶。
envsubst <<EOF | oc apply -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: gpu-operator-certified namespace: nvidia-gpu-operator spec: channel: "$CHANNEL" installPlanApproval: Automatic name: gpu-operator-certified source: certified-operators sourceNamespace: openshift-marketplace startingCSV: "$PACKAGE" EOF等候操作員完成安裝。
驗證操作員已完成安裝之前,請勿繼續進行。 此外,確保您的 GPU 背景工作角色在線上。
安裝節點功能探索操作員
節點功能探索操作員將探索節點上的 GPU,並適當地為節點加上標籤,讓您可以針對工作負載將其設為目標。
此範例會將 NFD 操作員安裝到 openshift-ndf 命名空間,並建立 "subscription",其為 NFD 的設定。
安裝節點功能探索操作員的官方文件。
設定
Namespace。cat <<EOF | oc apply -f - apiVersion: v1 kind: Namespace metadata: name: openshift-nfd EOF建立
OperatorGroup。cat <<EOF | oc apply -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: generateName: openshift-nfd- name: openshift-nfd namespace: openshift-nfd EOF建立
Subscription。cat <<EOF | oc apply -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: nfd namespace: openshift-nfd spec: channel: "stable" installPlanApproval: Automatic name: nfd source: redhat-operators sourceNamespace: openshift-marketplace EOF等候節點功能探索完成安裝。
您可以登入 OpenShift 主控台來檢視操作員,或只是等候幾分鐘。 無法等候操作員安裝會導致下一個步驟中發生錯誤。
建立 NFD 執行個體。
cat <<EOF | oc apply -f - kind: NodeFeatureDiscovery apiVersion: nfd.openshift.io/v1 metadata: name: nfd-instance namespace: openshift-nfd spec: customConfig: configData: | # - name: "more.kernel.features" # matchOn: # - loadedKMod: ["example_kmod3"] # - name: "more.features.by.nodename" # value: customValue # matchOn: # - nodename: ["special-.*-node-.*"] operand: image: >- registry.redhat.io/openshift4/ose-node-feature-discovery@sha256:07658ef3df4b264b02396e67af813a52ba416b47ab6e1d2d08025a350ccd2b7b servicePort: 12000 workerConfig: configData: | core: # labelWhiteList: # noPublish: false sleepInterval: 60s # sources: [all] # klog: # addDirHeader: false # alsologtostderr: false # logBacktraceAt: # logtostderr: true # skipHeaders: false # stderrthreshold: 2 # v: 0 # vmodule: ## NOTE: the following options are not dynamically run-time ## configurable and require a nfd-worker restart to take effect ## after being changed # logDir: # logFile: # logFileMaxSize: 1800 # skipLogHeaders: false sources: # cpu: # cpuid: ## NOTE: attributeWhitelist has priority over attributeBlacklist # attributeBlacklist: # - "BMI1" # - "BMI2" # - "CLMUL" # - "CMOV" # - "CX16" # - "ERMS" # - "F16C" # - "HTT" # - "LZCNT" # - "MMX" # - "MMXEXT" # - "NX" # - "POPCNT" # - "RDRAND" # - "RDSEED" # - "RDTSCP" # - "SGX" # - "SSE" # - "SSE2" # - "SSE3" # - "SSE4.1" # - "SSE4.2" # - "SSSE3" # attributeWhitelist: # kernel: # kconfigFile: "/path/to/kconfig" # configOpts: # - "NO_HZ" # - "X86" # - "DMI" pci: deviceClassWhitelist: - "0200" - "03" - "12" deviceLabelFields: # - "class" - "vendor" # - "device" # - "subsystem_vendor" # - "subsystem_device" # usb: # deviceClassWhitelist: # - "0e" # - "ef" # - "fe" # - "ff" # deviceLabelFields: # - "class" # - "vendor" # - "device" # custom: # - name: "my.kernel.feature" # matchOn: # - loadedKMod: ["example_kmod1", "example_kmod2"] # - name: "my.pci.feature" # matchOn: # - pciId: # class: ["0200"] # vendor: ["15b3"] # device: ["1014", "1017"] # - pciId : # vendor: ["8086"] # device: ["1000", "1100"] # - name: "my.usb.feature" # matchOn: # - usbId: # class: ["ff"] # vendor: ["03e7"] # device: ["2485"] # - usbId: # class: ["fe"] # vendor: ["1a6e"] # device: ["089a"] # - name: "my.combined.feature" # matchOn: # - pciId: # vendor: ["15b3"] # device: ["1014", "1017"] # loadedKMod : ["vendor_kmod1", "vendor_kmod2"] EOF驗證 NFD 已就緒。
此操作員的狀態應該會顯示為 [可用]。
套用 NVIDIA 叢集設定
本節說明如何套用 NVIDIA 叢集設定。 如果您有自己的私人存放庫或特定設定,請閱讀 NVIDIA 檔 ,以自定義此檔案。 此過程可能需要幾分鐘才能完成。
套用叢集設定。
cat <<EOF | oc apply -f - apiVersion: nvidia.com/v1 kind: ClusterPolicy metadata: name: gpu-cluster-policy spec: migManager: enabled: true operator: defaultRuntime: crio initContainer: {} runtimeClass: nvidia deployGFD: true dcgm: enabled: true gfd: {} dcgmExporter: config: name: '' driver: licensingConfig: nlsEnabled: false configMapName: '' certConfig: name: '' kernelModuleConfig: name: '' repoConfig: configMapName: '' virtualTopology: config: '' enabled: true use_ocp_driver_toolkit: true devicePlugin: {} mig: strategy: single validator: plugin: env: - name: WITH_WORKLOAD value: 'true' nodeStatusExporter: enabled: true daemonsets: {} toolkit: enabled: true EOF驗證叢集原則。
登入 OpenShift 主控台並瀏覽至操作員。 確保您位於
nvidia-gpu-operator命名空間中。 系統應顯示:State: Ready once everything is complete。
驗證 GPU
NVIDIA作員和 NFD 可能需要一些時間才能完全安裝和自我識別機器。 執行下列命令來驗證所有項目如預期般執行:
驗證 NFD 可以看到 GPU。
oc describe node | egrep 'Roles|pci-10de' | grep -v master輸出應該如下所示:
Roles: worker feature.node.kubernetes.io/pci-10de.present=true驗證節點標籤。
您可以登入 OpenShift 主控台 -> Compute -> Nodes -> nvidia-worker-southcentralus1- 來查看節點標籤。 您應該會看到多個 NVIDIA GPU 標籤和上述 pci-10de 裝置。
NVIDIA SMI 工具驗證。
oc project nvidia-gpu-operator for i in $(oc get pod -lopenshift.driver-toolkit=true --no-headers |awk '{print $1}'); do echo $i; oc exec -it $i -- nvidia-smi ; echo -e '\n' ; done您應該會看到輸出,其顯示主機上可用的 GPU,例如此範例螢幕擷取畫面。 (視 GPU 背景工作角色類型而有所不同)
建立 Pod 以執行 GPU 工作負載
oc project nvidia-gpu-operator cat <<EOF | oc apply -f - apiVersion: v1 kind: Pod metadata: name: cuda-vector-add spec: restartPolicy: OnFailure containers: - name: cuda-vector-add image: "quay.io/giantswarm/nvidia-gpu-demo:latest" resources: limits: nvidia.com/gpu: 1 nodeSelector: nvidia.com/gpu.present: true EOF檢視記錄。
oc logs cuda-vector-add --tail=-1
備註
如果您收到錯誤 Error from server (BadRequest): container "cuda-vector-add" in pod "cuda-vector-add" is waiting to start: ContainerCreating,請嘗試執行 oc delete pod cuda-vector-add,然後重新執行上述 create 陳述式。
輸出應該類似以下 (視 GPU 而定):
[Vector addition of 5000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done
如果成功,則可以刪除 Pod:
oc delete pod cuda-vector-add