Implantação de aplicativos em clusters d Red Hat OpenShift

Com os clusters do Red Hat® OpenShift® on IBM Cloud®, é possível implementar apps de um arquivo remoto ou de um repositório como GitHub com um único comando. Além disso, seus clusters são fornecidos com vários serviços integrados que podem ser usados para ajudar a operar seu cluster.

Movendo seus apps para o Red Hat OpenShift

Para criar um app em seu cluster Red Hat OpenShift on IBM Cloud, é possível usar o console ou a CLI do Red Hat OpenShift.

Vendo erros ao implementar seu app? O Red Hat OpenShift possui diferentes configurações padrão do Kubernetes da comunidade, como restrições de contexto de segurança mais rígidas. Revise os cenários comuns nos quais pode ser necessário modificar seus apps para que seja possível implementá-los em clusters Red Hat OpenShift.

Implementando apps por meio do console

É possível criar apps por meio de vários métodos no console do Red Hat OpenShift usando a perspectiva do Desenvolvedor. Para obter mais informações, consulte a documentação do site Red Hat OpenShift.

  1. No console, selecione seu cluster.
  2. Clique no console da web do Red Hat OpenShift.
  3. No alternador de perspectiva, selecione Desenvolvedor. O console da web do Red Hat OpenShift alterna para a perspectiva do desenvolvedor e o menu agora oferece itens como +Incluir, Topologia e Construções.
  4. Clique em +Incluir.
  5. Na barra de menus da área de janela Incluir, selecione o Projeto no qual você deseja criar seu app na lista suspensa.
  6. Clique no método que você deseja usar para incluir seu app e siga as instruções. Por exemplo, clique em Por meio do Git.

Implementando apps por meio da CLI

Para criar um aplicativo em seu cluster Red Hat OpenShift on IBM Cloud, use o comando oc new-app. Por exemplo, é possível que você se refira a um repositório de GitHub público, a um repositório de GitLab público com uma URL que termina em .git ou a outro repositório local ou remoto. Para obter mais informações, experimente o tutorial e consulte a documentação do site Red Hat OpenShift.

oc new-app --name <app_name> https://github.com/<path_to_app_repo> [--context-dir=<subdirectory>]
O que o comando new-app faz?
O comando new-app cria uma configuração de construção e uma imagem de app por meio do código-fonte, uma configuração de implementação para implementar o contêiner em pods em seu cluster e um serviço para expor o app dentro do cluster. Para obter mais informações sobre o processo de compilação e outros códigos-fonte além do Git, consulte a documentação do Red Hat OpenShift.

Implementando apps em nós do trabalhador específicos usando rótulos

Ao implementar um app, os pods de app são implementados indiscriminadamente em vários nós do trabalhador em seu cluster. Às vezes você pode querer restringir os nós do trabalhador nos quais os pods de app são implementados. Por exemplo, é possível que você queira que os pods de app sejam implementados somente em nós do trabalhador em um determinado conjunto de trabalhadores porque esses nós do trabalhador estão em máquinas bare metal. Para designar os nós do trabalhador nos quais os pods de app devem ser implementados, inclua uma regra de afinidade em sua implementação de app.

Antes de Iniciar

Para implementar apps em nós do trabalhador específicos,

  1. Obtenha o ID do conjunto de trabalhadores para o qual você deseja implementar os pods de app.

    ibmcloud oc worker-pool ls --cluster CLUSTER_NAME_OR_ID
    
  2. Liste os nós do trabalhador que estão no conjunto de trabalhadores e anote um dos endereços IP privado.

    ibmcloud oc worker ls --cluster CLUSTER_NAME_OR_ID --worker-pool WORKER_POOL_NAME_OR_ID
    
  3. Descreva o nó do trabalhador. Na saída Rótulos, anote o rótulo do ID do conjunto de trabalhadores, ibm-cloud.kubernetes.io/worker-pool-id.

    As etapas neste tópico usam um ID do conjunto de trabalhadores para implementar pods de app apenas para nós do trabalhador dentro desse conjunto de trabalhadores. Para implementar os pods de app em nós do trabalhador específicos usando um rótulo diferente, anote esse rótulo. Por exemplo, para implementar os pods de app apenas para os nós do trabalhador em uma VLAN privada específica, use a etiqueta privateVLAN=.

    oc describe node <worker_node_private_IP>
    

    Saída de exemplo

    NAME:               10.xxx.xx.xxx
    Roles:              <none>
    Labels:             arch=amd64
                        beta.kubernetes.io/arch=amd64
                        beta.kubernetes.io/instance-type=b3c.4x16.encrypted
                        beta.kubernetes.io/os=linux
                        failure-domain.beta.kubernetes.io/region=us-south
                        failure-domain.beta.kubernetes.io/zone=dal10
                        ibm-cloud.kubernetes.io/encrypted-docker-data=true
                        ibm-cloud.kubernetes.io/ha-worker=true
                        ibm-cloud.kubernetes.io/iaas-provider=softlayer
                        ibm-cloud.kubernetes.io/machine-type=b3c.4x16.encrypted
                        ibm-cloud.kubernetes.io/sgx-enabled=false
                        ibm-cloud.kubernetes.io/worker-pool-id=00a11aa1a11aa11a1111a1111aaa11aa-11a11a
                        ibm-cloud.kubernetes.io/worker-version=1.35_1534
                        kubernetes.io/hostname=10.xxx.xx.xxx
                        privateVLAN=1234567
                        publicVLAN=7654321
    Annotations:        node.alpha.kubernetes.io/ttl=0
    ...
    
  4. Inclua uma regra de afinidade para o rótulo do ID do conjunto de trabalhadores para a implementação do app.

    Exemplo de YAML

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: with-node-affinity
    spec:
      template:
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: ibm-cloud.kubernetes.io/worker-pool-id
                    operator: In
                    values:
                    - <worker_pool_ID>
    ...
    

    Na seção afinidade do exemplo YAML, ibm-cloud.kubernetes.io/worker-pool-id é o key e <worker_pool_ID> é o value.

  5. Aplique o arquivo de configuração de implementação atualizado.

    oc apply -f with-node-affinity.yaml
    
  6. Verifique se os pods de app foram implementados nos nós do trabalhador corretos.

    1. Liste os pods em seu cluster.
        oc get pods -o wide
        ```
        Saída de exemplo
        ```sh {: screen}
        NAME                   READY     STATUS              RESTARTS   AGE       IP               NODE
        cf-py-d7b7d94db-vp8pq  1/1       Running             0          15d       172.30.xxx.xxx   10.176.48.78
        ```
    2. Na saída, identifique um pod para seu app. Anote o endereço IP privado do **NODE** dodo trabalhador no qual o pod está.
    
        Na saída de exemplo anterior, o pod de app `cf-py-d7b7d94db-vp8pq` está em um nó do trabalhador com o endereço IP `10.xxx.xx.xxx`.
    
    3. Liste os nós do trabalhador no conjunto de trabalhadores que você designou em sua implementação de app.
    
    ```sh {: pre}
        ibmcloud oc worker ls --cluster CLUSTER_NAME_OR_ID --worker-pool WORKER_POOL_NAME_OR_ID
        ```
        Saída de exemplo
    
        ```sh {: screen}
        ID                                                 Public IP       Private IP     Machine Type      State    Status  Zone    Version
        kube-dal10-crb20b637238bb471f8b4b8b881bbb4962-w7   169.xx.xxx.xxx  10.176.48.78   b3c.4x16          normal   Ready   dal10   1.8.6_1504
        kube-dal10-crb20b637238bb471f8b4b8b881bbb4962-w8   169.xx.xxx.xxx  10.176.48.83   b3c.4x16          normal   Ready   dal10   1.8.6_1504
        kube-dal12-crb20b637238bb471f8b4b8b881bbb4962-w9   169.xx.xxx.xxx  10.176.48.69   b3c.4x16          normal   Ready   dal12   1.8.6_1504
        ```
        Se você criou uma regra de afinidade de app baseada em outro fator, obtenha esse valor no lugar. Por exemplo, para verificar se o pod do app está implementado em um nó do trabalhador em uma VLAN específica, visualize a VLAN na qual o nó do trabalhador se encontra executando `ibmcloud oc worker get --cluster CLUSTER_NAME_OR_ID --worker WORKER_ID`.
        {: tip}
    
    4. Na saída, verifique se o nó do trabalhador com o endereço IP privado que você identificou na etapa anterior está implementado nesse conjunto de trabalhadores.
    
    

Implantação de um aplicativo em uma máquina com GPU do NVIDIA

Se você tiver um tipo de máquina GPU, será possível acelerar o tempo de processamento necessário para cargas de trabalho intensivas de cálculo, como IA, aprendizado de máquina, inferência e mais.

Nas etapas a seguir, você aprenderá como implementar cargas de trabalho que requerem a GPU. No entanto, também é possível implantar aplicativos que não precisam processar suas cargas de trabalho tanto na GPU quanto na CPU.

Você também pode experimentar cargas de trabalho matematicamente intensas, como a TensorFlow estrutura de aprendizado de máquina com esta demonstração em Kubernetes.

Pré-requisitos

Antes de Iniciar

  • Crie um cluster ou um conjunto de trabalhadores que use um tipo de GPU Tenha em mente que a configuração de uma máquina bare metal pode levar mais de um dia útil para ser concluída. Para obter uma lista de tipos disponíveis, consulte os links a seguir:

  • Certifique-se de que você esteja designado a uma função de acesso ao serviço que concede a função apropriada de RBAC do Kubernetes para poder trabalhar com recursos do Kubernetes no cluster.

Limitações de cluster somente privadas: se você não tiver conectividade de rede pública, deverá permitir a conectividade de rede pública ou espelhar imagens de registros externos e fluxos de imagem para o icr.io. No exemplo a seguir, o app GPU usa o mercado OLM com fluxos de imagem. Esse exemplo não funcionará se o seu cluster não puder acessar o registro NVIDIA ( nvcr.io ).

Deve-se usar o operador NVIDIA GPU versão 1.3.1 ou mais recente. Ao instalar o operador Node Feature Discovery, selecione o canal de atualização que corresponde à sua versão do cluster Red Hat OpenShift. Não instale os operadores por meio de outro método, como um gráfico do tipo “ Helm ”.

Nós de trabalho do RHEL 9: Se você estiver instalando drivers de GPU NVIDIA em nós de trabalho RHEL 9, deverá aplicar uma solução alternativa para ativar todos os repositórios necessários do Extended Update Support (EUS). O NVIDIA GPU Operator não habilita todos os repositórios EUS necessários por padrão, o que causa falha na instalação do driver. Para obter mais informações, consulte Por que a instalação do driver da GPU NVIDIA falha nos nós de trabalho do RHEL 9?

Caso você tenha dificuldades para instalar o Operador de Descoberta de Recursos do Node ou o Operador de GPU do NVIDIA, entre em contato com o suporte do NVIDIA para obter ajuda ou abra um ticket no repositório do Operador de GPU doNVIDIA

Implementando uma carga de trabalho

  1. Crie um arquivo YAML. Neste exemplo, um arquivo YAML do tipo “ Job ” gerencia cargas de trabalho semelhantes a processamento em lote, criando um pod de curta duração que é executado até que o comando seja concluído e seja encerrado com sucesso.

    Para cargas de trabalho de GPU, é necessário especificar o campo resources: limits: nvidia.com/gpu no arquivo YAML da tarefa.

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: nvidia-devicequery
      labels:
        name: nvidia-devicequery
    spec:
      template:
        metadata:
          labels:
            name: nvidia-devicequery
        spec:
          containers:
          - name: nvidia-devicequery
            image: nvcr.io/nvidia/k8s/cuda-sample:devicequery-cuda11.7.1-ubuntu20.04
            imagePullPolicy: IfNotPresent
            resources:
              limits:
                nvidia.com/gpu: 2
          restartPolicy: Never
    
    Compreensão de seus componentes YAML
    Componente Descrição
    Metadados e nomes de rótulo Insira um nome e um rótulo para a tarefa e use o mesmo nome nos metadados do arquivo e nos metadados do spec template. Por exemplo, nvidia-devicequery.
    containers.image Forneça a imagem da qual o contêiner é uma instância em execução. Neste exemplo, o valor é configurado para usar a imagem de consulta do dispositivo CUDA DockerHub:nvcr.io/nvidia/k8s/cuda-sample:devicequery-cuda11.7.1-ubuntu20.04.
    containers.imagePullPolicy Para puxar uma nova imagem somente se a imagem não estiver atualmente no nó do trabalhador, especifique IfNotPresent.
    resources.limits

    Para máquinas de GPU, deve-se especificar o limite de recurso. O Plug-in do dispositivo do Kubernetes configura a solicitação de recursos padrão para corresponder ao limite.

    • Deve-se especificar a chave como nvidia.com/gpu.
    • Insira o número inteiro de GPUs solicitado, como 2. Observe que os pods de contêiner não compartilham GPUs e as GPUs não podem ser supercomprometidas. Por exemplo, se você tem somente 1 máquina mg1c.16x128, então tem apenas 2 GPUs nessa máquina e pode especificar um máximo de 2.
  2. Aplique o arquivo YAML. Por exemplo:

    oc apply -f nvidia-devicequery.yaml
    
  3. Verifique o pod de tarefa filtrando seus pods pelo rótulo “ nvidia-devicequery ”. Verifique se o STATUS é Concluído.

    oc get pod -A -l 'name in (nvidia-devicequery)'
    

    Saída de exemplo

    NAME                  READY     STATUS      RESTARTS   AGE
    nvidia-devicequery-ppkd4      0/1       Completed   0          36s
    
  4. Descreva o pod para ver como o plug-in do dispositivo de GPU planejou o pod.

    • Nos campos Limits e Requests, veja se o limite de recurso que você especificou corresponde à solicitação que o plug-in do dispositivo configurou automaticamente.
    • Nos eventos, verifique se o pod está designado ao seu nó do trabalhador da GPU.
        oc describe pod nvidia-devicequery-ppkd4
        ```
        Saída de exemplo
        ```sh {: screen}
        NAME:           nvidia-devicequery-ppkd4
        Namespace:      default
        ...
        Limits:
            nvidia.com/gpu:  1
        Requests:
            nvidia.com/gpu:  1
        ...
        Events:
        Type    Reason                 Age   From                     Message
        ----    ------                 ----  ----                     -------
        Normal  Scheduled              1m    default-scheduler        Successfully assigned nvidia-devicequery-ppkd4 to 10.xxx.xx.xxx
        ...
        ```
    
  5. Para verificar se a tarefa usou a GPU para calcular sua carga de trabalho, é possível verificar os logs.

    oc logs nvidia-devicequery-ppkd4
    

    Saída de exemplo

    /cuda-samples/sample Starting...
    CUDA Device Query (Runtime API) version (CUDART static linking)
    Detected 1 CUDA Capable device(s)
    Device 0: "Tesla P100-PCIE-16GB"
    CUDA Driver Version / Runtime Version          11.4 / 11.7
    CUDA Capability Major/Minor version number:    6.0
    Total amount of global memory:                 16281 MBytes (17071734784 bytes)
    (056) Multiprocessors, (064) CUDA Cores/MP:    3584 CUDA Cores
    GPU Max Clock rate:                            1329 MHz (1.33 GHz)
    Memory Clock rate:                             715 Mhz
    Memory Bus Width:                              4096-bit
    L2 Cache Size:                                 4194304 bytes
    Maximum Texture Dimension Size (x,y,z)         1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384)
    Maximum Layered 1D Texture Size, (num) layers  1D=(32768), 2048 layers
    Maximum Layered 2D Texture Size, (num) layers  2D=(32768, 32768), 2048 layers
    Total amount of constant memory:               65536 bytes
    Total amount of shared memory per block:       49152 bytes
    Total shared memory per multiprocessor:        65536 bytes
    Total number of registers available per block: 65536
    Warp size:                                     32
    Maximum number of threads per multiprocessor:  2048
    Maximum number of threads per block:           1024
    Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
    Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)
    Maximum memory pitch:                          2147483647 bytes
    Texture alignment:                             512 bytes
    Concurrent copy and kernel execution:          Yes with 2 copy engine(s)
    Run time limit on kernels:                     No
    Integrated GPU sharing Host Memory:            No
    Support host page-locked memory mapping:       Yes
    Alignment requirement for Surfaces:            Yes
    Device has ECC support:                        Enabled
    Device supports Unified Addressing (UVA):      Yes
    Device supports Managed Memory:                Yes
    Device supports Compute Preemption:            Yes
    Supports Cooperative Kernel Launch:            Yes
    Supports MultiDevice Co-op Kernel Launch:      Yes
    Device PCI Domain ID / Bus ID / location ID:   0 / 175 / 0
    Compute Mode:
    < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
    deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 11.4, CUDA Runtime Version = 11.7, NumDevs = 1
    Result = PASS
    

    Neste exemplo, você vê que uma GPU foi usada para executar a tarefa, pois a GPU foi planejada no nó do trabalhador Se o limite for configurado para 2, apenas 2 GPUs serão mostradas.

Agora que você implementou uma carga de trabalho de GPU de teste, talvez deseje configurar o cluster para executar uma ferramenta que conte com processamento de GPU, como IBM Maximo Visual Inspection.

Implantação de um aplicativo em uma máquina Intel AI Accelerator (Gaudi 3)

Esse recurso está disponível apenas para contas incluídas na lista de permissões. Para solicitar acesso, consulte Solicitação de acesso a recursos listados para permissão.

Conclua o exemplo a seguir para implantar a imagem do contêiner PyTorch do Intel Gaudi que recupera um dispositivo Gaudi usando o campo resource.limits. Antes de começar, certifique-se de que seu cluster atenda aos seguintes requisitos.

Para obter mais informações e exemplos, consulte os documentos da Habana e o exemplo de início rápido.

  1. Copie o exemplo de configuração de trabalho a seguir e salve-o em um arquivo chamado config.yaml
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: habanalabs-gaudi-demo
    spec:
      template:
          spec:
            hostIPC: true
            restartPolicy: OnFailure
            containers:
              - name: habana-ai-base-container
                image: vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest
                workingDir: /root
                command: ["hl-smi"]
                securityContext:
                  capabilities:
                      add: ["SYS_NICE"]
                resources:
                  limits:
                      habana.ai/gaudi: 8
                      memory: 409Gi
                      hugepages-2Mi: 9500Mi
    
  2. Aplique o trabalho no seu cluster.
    oc apply -f config.yaml
    
  3. Aguarde a inicialização dos pods e verifique se o trabalho foi concluído.
    oc get po -n default
    
    Exemplo
    NAME                          READY   STATUS      RESTARTS   AGE
    habanalabs-gaudi-demo-kmdcp   0/1     Completed   0          2m32s
    
  4. Descreva o pod de trabalho para obter mais detalhes.
    oc describe po habanalabs-gaudi-demo-kmdcp
    
    Name:             habanalabs-gaudi-demo-kmdcp
    Namespace:        default
    Priority:         0
    Service Account:  default
    Node:             test-csrq76620trmo9r8j7u0-btsstagevpc-gaudi3s-00013059/10.180.0.83
    Start Time:       Tue, 27 May 2025 14:41:50 -0400
    Labels:           batch.kubernetes.io/controller-uid=c3b33c8a-5fef-4312-9d59-c8b13c03313a
                      batch.kubernetes.io/job-name=habanalabs-gaudi-demo
                      controller-uid=c3b33c8a-5fef-4312-9d59-c8b13c03313a
                      job-name=habanalabs-gaudi-demo
    Annotations:      cni.projectcalico.org/containerID: 7c883dfa9c681ee2c4128b1a5412d4dc181842d0de2a4b7b8019eefc06df37ca
                      cni.projectcalico.org/podIP:
                      cni.projectcalico.org/podIPs:
    Status:           Succeeded
    IP:               172.17.151.97
    IPs:
      IP:           172.17.151.97
    Controlled By:  Job/habanalabs-gaudi-demo
    Containers:
      habana-ai-base-container:
        Container ID:  cri-o://d75288e9b467f3f820e05e770bbc3d9a2b11cbf8155a54a129fc083d5d507571
        Image:         vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest
        Image ID:      vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0@sha256:cd599626a8f4d1c3a7b354ccf4ef73e19196f09030d02261d4900bf3467a964c
        Port:          <none>
        Host Port:     <none>
        Command:
          hl-smi
        State:          Terminated
          Reason:       Completed
          Exit Code:    0
          Started:      Tue, 27 May 2025 14:41:53 -0400
          Finished:     Tue, 27 May 2025 14:41:54 -0400
        Ready:          False
        Restart Count:  0
        Limits:
          habana.ai/gaudi:  8
          hugepages-2Mi:    9500Mi
          memory:           409Gi
        Requests:
          habana.ai/gaudi:  8
          hugepages-2Mi:    9500Mi
          memory:           409Gi
        Environment:        <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8vn42 (ro)
    Conditions:
      Type                        Status
      PodReadyToStartContainers   False
      Initialized                 True
      Ready                       False
      ContainersReady             False
      PodScheduled                True
    Volumes:
      kube-api-access-8vn42:
        Type:                    Projected (a volume that contains injected data from multiple sources)
        TokenExpirationSeconds:  3607
        ConfigMapName:           kube-root-ca.crt
        ConfigMapOptional:       <nil>
        DownwardAPI:             true
        ConfigMapName:           openshift-service-ca.crt
        ConfigMapOptional:       <nil>
    QoS Class:                   Burstable
    Node-Selectors:              <none>
    Tolerations:                 node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                                  node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                                  node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    Events:
      Type    Reason          Age   From               Message
      ----    ------          ----  ----               -------
      Normal  Scheduled       53s   default-scheduler  Successfully assigned default/habanalabs-gaudi-demo-kmdcp to test-csrq76620trmo9r8j7u0-btsstagevpc-gaudi3s-00013059
      Normal  AddedInterface  52s   multus             Add eth0 [172.17.151.97/32] from k8s-pod-network
      Normal  Pulling         52s   kubelet            Pulling image "vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest"
      Normal  Pulled          50s   kubelet            Successfully pulled image "vault.habana.ai/gaudi-docker/1.21.0/ubuntu22.04/habanalabs/pytorch-installer-2.6.0:latest" in 2.146s (2.146s including waiting). Image size: 5188441181 bytes.
      Normal  Created         50s   kubelet            Created container: habana-ai-base-container
      Normal  Started         50s   kubelet            Started container habana-ai-base-container
    
  5. Obtenha os registros do pod para ver os detalhes do dispositivo Gaudi.
    oc logs habanalabs-gaudi-demo-kmdcp
    
    Saída de exemplo
    +-----------------------------------------------------------------------------+
    | HL-SMI Version:                              hl-1.21.0-fw-59.2.1.0          |
    | Driver Version:                                     1.20.1-366eb9c          |
    | Nic Driver Version:                                 1.20.1-213b09b          |
    |-------------------------------+----------------------+----------------------+
    | AIP  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncor-Events|
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | AIP-Util  Compute M. |
    |===============================+======================+======================|
    |   0  HL-325L             N/A  | 0000:e9:00.0     N/A |                   0  |
    | N/A   36C   P0  228W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    |   1  HL-325L             N/A  | 0000:c1:00.0     N/A |                   0  |
    | N/A   37C   P0  226W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    |   2  HL-325L             N/A  | 0000:b7:00.0     N/A |                   0  |
    | N/A   36C   P0  225W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    |   3  HL-325L             N/A  | 0000:ad:00.0     N/A |                   0  |
    | N/A   40C   P0  228W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    |   4  HL-325L             N/A  | 0000:a3:00.0     N/A |                   0  |
    | N/A   36C   P0  228W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    |   5  HL-325L             N/A  | 0000:df:00.0     N/A |                   0  |
    | N/A   39C   P0  229W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    |   6  HL-325L             N/A  | 0000:d5:00.0     N/A |                   0  |
    | N/A   36C   P0  231W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    |   7  HL-325L             N/A  | 0000:cb:00.0     N/A |                   0  |
    | N/A   38C   P0  227W /  900W  |   672MiB / 131072MiB |     0%            0% |
    |-------------------------------+----------------------+----------------------+
    | Compute Processes:                                               AIP Memory |
    |  AIP       PID   Type   Process name                             Usage      |
    |=============================================================================|
    |   0        N/A   N/A    N/A                                      N/A        |
    |   1        N/A   N/A    N/A                                      N/A        |
    |   2        N/A   N/A    N/A                                      N/A        |
    |   3        N/A   N/A    N/A                                      N/A        |
    |   4        N/A   N/A    N/A                                      N/A        |
    |   5        N/A   N/A    N/A                                      N/A        |
    |   6        N/A   N/A    N/A                                      N/A        |
    |   7        N/A   N/A    N/A                                      N/A        |
    +=============================================================================+
    

Implantação de um aplicativo em uma máquina AMD MI300x

Red Hat CoreOS 4.18 e, posteriormente, VPC

Para obter mais informações e exemplos, consulte os documentos da AMD e o exemplo de início rápido.

  1. Copie o exemplo de configuração de pod a seguir e salve-o em um arquivo chamado config.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: amd-smi
    spec:
      containers:
      - image: docker.io/rocm/rocm-terminal:latest
        name: amd-smi
        command: ["/bin/bash"]
        args: ["-c","amd-smi version && amd-smi monitor -ptum"]
        resources:
          limits:
            amd.com/gpu: 8
          requests:
            amd.com/gpu: 8
      restartPolicy: Never
    
  2. Aplique o pod no seu cluster.
    oc apply -f config.yaml
    
  3. Aguarde a inicialização dos pods e verifique se o trabalho foi concluído.
    oc get po -n default
    
    Exemplo
    NAME       READY   STATUS      RESTARTS   AGE
    amd-smi    0/1     Completed   0          19m
    
  4. Descreva o pod de trabalho para obter mais detalhes.
    oc describe po amd-smi
    
    Name:         amd-smi
    Namespace:    default
    Priority:     0
    Node:         test-d18ofps20v1lr6in6ta0-btsstagevpc-gx3d208-00001687/10.240.1.4
    Start Time:   Mon, 07 Jul 2025 13:32:18 -0500
    Labels:       <none>
    Annotations:  cni.projectcalico.org/containerID: 5b5d39f8ebe5ea14250af02031084961285f8b210eea14d2c22704784d957de3
                  cni.projectcalico.org/podIP:
                  cni.projectcalico.org/podIPs:
    Status:       Succeeded
    IP:           172.17.55.73
    IPs:
      IP:  172.17.55.73
    Containers:
      amd-smi:
        Container ID:  cri-o://3260f5a2788cc189adbe53d3d49c1bdccc7001df27f0c747d6fa86a3068c9eda
        Image:         docker.io/rocm/rocm-terminal:latest
        Image ID:      docker.io/rocm/rocm-terminal@sha256:72b323c5d56c511ea75f7353d0fee04e637390dd4874d414020284627a658014
        Port:          <none>
        Host Port:     <none>
        Command:
          /bin/bash
        Args:
          -c
          amd-smi version && amd-smi monitor -ptum
        State:          Terminated
          Reason:       Completed
          Exit Code:    0
          Started:      Mon, 07 Jul 2025 13:32:20 -0500
          Finished:     Mon, 07 Jul 2025 13:32:20 -0500
        Ready:          False
        Restart Count:  0
        Limits:
          amd.com/gpu:  8
        Requests:
          amd.com/gpu:  8
        Environment:    <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-tshnq (ro)
    Conditions:
      Type                        Status
      PodReadyToStartContainers   False
      Initialized                 True
      Ready                       False
      ContainersReady             False
      PodScheduled                True
    Volumes:
      kube-api-access-tshnq:
        Type:                    Projected (a volume that contains injected data from multiple sources)
        TokenExpirationSeconds:  3607
        ConfigMapName:           kube-root-ca.crt
        ConfigMapOptional:       <nil>
        DownwardAPI:             true
        ConfigMapName:           openshift-service-ca.crt
        ConfigMapOptional:       <nil>
    QoS Class:                   BestEffort
    Node-Selectors:              <none>
    Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                                node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    Events:
      Type    Reason          Age   From               Message
      ----    ------          ----  ----               -------
      Normal  Scheduled       19m   default-scheduler  Successfully assigned default/amd-smi to test-d18ofps20v1lr6in6ta0-btsstagevpc-gx3d208-00001687
      Normal  AddedInterface  19m   multus             Add eth0 [172.17.55.73/32] from k8s-pod-network
      Normal  Pulling         19m   kubelet            Pulling image "docker.io/rocm/rocm-terminal:latest"
      Normal  Pulled          19m   kubelet            Successfully pulled image "docker.io/rocm/rocm-terminal:latest" in 782ms (782ms including waiting). Image size: 3016399213 bytes.
      Normal  Created         19m   kubelet            Created container: amd-smi
      Normal  Started         19m   kubelet            Started container amd-smi
    
  5. Obtenha os registros do pod para ver os detalhes da GPU AMD.
    oc logs amd-smi
    
    Saída de exemplo
    AMDSMI Tool: 25.3.0+ede62f2 | AMDSMI Library version: 25.3.0 | ROCm version: 6.4.0 | amdgpu version: 6.10.5 | amd_hsmp version: N/A
    WARNING: User is missing the following required groups: render. Please add user to these groups.
    GPU  POWER   GPU_T   MEM_T   GFX_CLK   GFX%   MEM%  MEM_CLOCK
      0  141 W   40 °C   36 °C   140 MHz    0 %    0 %    900 MHz
      1  144 W   42 °C   33 °C   138 MHz    0 %    0 %    900 MHz
      2  140 W   38 °C   34 °C   142 MHz    0 %    0 %    900 MHz
      3  142 W   39 °C   34 °C   140 MHz    0 %    0 %    900 MHz
      4  140 W   38 °C   35 °C   138 MHz    0 %    0 %    900 MHz
      5  142 W   36 °C   30 °C   138 MHz    0 %    0 %    900 MHz
      6  137 W   40 °C   35 °C   138 MHz    0 %    0 %    900 MHz
      7  137 W   38 °C   32 °C   142 MHz    0 %    0 %    900 MHz