documentation.suse.com / Documentação do SUSE Edge / Integração de terceiros / GPUs NVIDIA no SUSE Linux Micro

33 GPUs NVIDIA no SUSE Linux Micro

33.1 Introdução

Este guia demonstra como implementar o suporte à GPU NVIDIA no nível do host usando os drivers de código-fonte aberto predefinidos no SUSE Linux Micro 6.1. Esses drivers são integrados ao sistema operacional, e não dinamicamente carregados pelo NVIDIA GPU Operator. Essa configuração é altamente aconselhável para clientes que desejam fazer bake prévio de todos os artefatos necessários para implantação na imagem, e quando não é um requisito a seleção dinâmica da versão do driver, ou seja, o usuário ter que selecionar a versão do driver pelo Kubernetes. Inicialmente, este guia explica como implantar componentes adicionais em um sistema que já tenha sido pré-implantado, mas prossegue com uma seção que descreve como incorporar essa configuração à implantação inicial por meio do Edge Image Builder. Se você não quer passar pelas etapas básicas e configurar tudo manualmente, avance direto para essa seção.

É importante destacar que o suporte a esses drivers é oferecido pela SUSE e NVIDIA em estreita colaboração, sendo que os drivers são criados e distribuídos pela SUSE como parte dos repositórios de pacotes. No entanto, se você tiver qualquer problema ou dúvida sobre a combinação dos drivers usada, contate os gerentes de conta da SUSE ou NVIDIA para receber mais ajuda. Se você pretende usar o NVIDIA AI Enterprise (NVAIE), certifique-se de que tenha uma GPU certificada para NVAIE, o que pode exigir o uso de drivers proprietários da NVIDIA. Se estiver em dúvida, fale com seu representante NVIDIA.

Este guia não aborda mais informações sobre a integração do NVIDIA GPU Operator. A integração do NVIDIA GPU Operator para Kubernetes não é explicada aqui, mas você ainda pode seguir a maioria das etapas neste guia para configurar o sistema operacional subjacente e simplesmente permitir que o GPU Operator use os drivers pré-instalados por meio do sinalizador driver.enabled=false no gráfico Helm do NVIDIA GPU Operator, que apenas vai selecionar os drivers instalados no host. A NVIDIA apresenta instruções mais detalhadas aqui.

33.2 Pré-requisitos

Se você está seguindo este guia, já deve ter os seguintes itens disponíveis:

  • No mínimo, um host com o SUSE Linux Micro 6.1 instalado, que pode ser físico ou virtual.

  • Seus hosts são anexados a uma assinatura porque isso é exigido para acesso ao pacote. Há uma avaliação disponível aqui.

  • Uma GPU NVIDIA compatível instalada (ou completamente transferida para a máquina virtual na qual o SUSE Linux Micro está em execução).

  • Acesso ao usuário root. Nestas instruções, consideramos você como usuário root, sem escalar seus privilégios por meio do sudo.

33.3 Instalação manual

Nesta seção, você vai instalar os drivers da NVIDIA diretamente no sistema operacional SUSE Linux Micro, já que o driver de código aberto da NVIDIA agora faz parte dos repositórios de pacotes principais do SUSE Linux Micro, o que o torna tão fácil de instalar quanto os pacotes RPM obrigatórios. Não há necessidade de compilação nem download de pacotes executáveis. Veja a seguir como implantar a geração "G06" do driver, que oferece suporte às GPUs mais recentes (consulte aqui para obter mais informações). Sendo assim, selecione a geração do driver apropriada à GPU NVIDIA do seu sistema. Para GPUs modernas, o driver "G06" é a opção mais comum.

Antes de começar, é importante reconhecer que, além do driver de código aberto da NVIDIA que a SUSE distribui como parte do SUSE Linux Micro, você precisa de componentes NVIDIA adicionais para sua configuração. Eles podem ser bibliotecas OpenGL, kits de ferramentas CUDA, utilitários de linha de comando, como nvidia-smi, e componentes de integração de contêiner, como nvidia-container-toolkit. Muitos desses componentes não são distribuídos pela SUSE porque são softwares proprietários da NVIDIA, ou porque não faz sentido distribuí-los no lugar da NVIDIA. Portanto, como parte das instruções, vamos configurar repositórios adicionais para termos acesso a esses componentes e percorrer alguns exemplos de como usar essas ferramentas para obter um sistema totalmente funcional. É importante diferenciar entre os repositórios SUSE e NVIDIA, já que pode haver incompatibilidade entre as versões dos pacotes que a NVIDIA disponibiliza e as que a SUSE compilou. Geralmente, isso acontece quando a SUSE cria uma nova versão do driver de código aberto disponível e leva alguns dias até que os pacotes equivalentes sejam disponibilizados nos repositórios NVIDIA para compatibilidade.

A recomendação é garantir que você selecione uma versão do driver compatível com a GPU e que atenda aos possíveis requisitos de CUDA verificando o seguinte:

Dica
Dica

Para encontrar as versões de driver de código aberto da NVIDIA, execute zypper se -s nvidia-open-driver na máquina de destino ou pesquise no SUSE Customer Center por "nvidia-open-driver" no SUSE Linux Micro 6.1 para AMD64/Intel 64.

SUSE Customer Center

Depois que você confirmar a disponibilidade de uma versão equivalente nos repositórios NVIDIA, estará pronto para instalar os pacotes no sistema operacional host. Para isso, precisamos abrir uma sessão transactional-update, que cria um novo instantâneo de leitura/gravação do sistema operacional subjacente para que possamos fazer alterações na plataforma imutável (para obter mais instruções sobre transactional-update, consulte aqui):

transactional-update shell

Quando estiver no shell transactional-update, adicione outro repositório de pacotes da NVIDIA para que possamos obter os utilitários adicionais, por exemplo, nvidia-smi:

zypper ar https://download.nvidia.com/suse/sle15sp6/ nvidia-suse-main
zypper --gpg-auto-import-keys refresh

Depois disso, você poderá instalar o driver e nvidia-compute-utils para os utilitários adicionais. Se os utilitários não forem necessários, você poderá omiti-los. No entanto, é importante instalá-los neste estágio para fins de teste:

zypper install -y --auto-agree-with-licenses nvidia-open-driver-G06-signed-kmp nvidia-compute-utils-G06
Nota
Nota

Se houver falha na instalação, poderá ser indicativo de uma incompatibilidade de dependência entre a versão do driver selecionada e a que a NVIDIA distribui em seus repositórios. Consulte a seção anterior para verificar se as suas versões são compatíveis. Tente instalar outra versão do driver. Por exemplo, se os repositórios NVIDIA tiverem uma versão mais antiga, tente especificar nvidia-open-driver-G06-signed-kmp=550.54.14 em seu comando de instalação para especificar uma versão equivalente.

Em seguida, se você não usa uma GPU compatível (lembrando que a lista está disponível aqui), pode conferir se o driver funciona habilitando o suporte no nível do módulo, mas a sua milhagem poderá variar. Pule esta etapa se você usa uma GPU compatível:

sed -i '/NVreg_OpenRmEnableUnsupportedGpus/s/^#//g' /etc/modprobe.d/50-nvidia-default.conf

Agora que você instalou os pacotes, saia da sessão transactional-update:

exit
Nota
Nota

Antes de prosseguir, garanta que já tenha saído da sessão transactional-update.

Agora que você instalou os drivers, faça a reinicialização. Como o SUSE Linux Micro é um sistema operacional imutável, ele precisa ser reinicializado no novo instantâneo criado na etapa anterior. Os drivers são instalados apenas nesse novo instantâneo, já que não é possível carregá-los sem a reinicialização nele, o que é feito automaticamente. Execute o comando de reinicialização quando estiver pronto:

reboot

Após a reinicialização bem-sucedida do sistema, faça login novamente e use a ferramenta nvidia-smi para verificar se o driver foi carregado com sucesso e pode acessar e enumerar as GPUs:

nvidia-smi

A saída desse comando deve ser similar à mostrada abaixo, levando em consideração que temos duas GPUs no exemplo a seguir:

+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.29.06              Driver Version: 545.29.06    CUDA Version: 12.3     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA A100-PCIE-40GB          Off | 00000000:17:00.0 Off |                    0 |
| N/A   29C    P0              35W / 250W |      4MiB / 40960MiB |      0%      Default |
|                                         |                      |             Disabled |
+-----------------------------------------+----------------------+----------------------+
|   1  NVIDIA A100-PCIE-40GB          Off | 00000000:CA:00.0 Off |                    0 |
| N/A   30C    P0              33W / 250W |      4MiB / 40960MiB |      0%      Default |
|                                         |                      |             Disabled |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|  No running processes found                                                           |
+---------------------------------------------------------------------------------------+

E assim concluímos o processo de instalação e verificação dos drivers da NVIDIA no sistema SUSE Linux Micro.

33.4 Validação adicional da instalação manual

Neste estágio, a única coisa que podemos verificar é que, no nível do host, é possível acessar o dispositivo NVIDIA e os drivers são carregados com sucesso. No entanto, para garantir que tudo esteja funcionando, há um teste simples para comprovar que a GPU pode receber as instruções de um aplicativo no espaço do usuário, de preferência por meio de um contêiner, e pela biblioteca CUDA, que é o mais comum para uma carga de trabalho real. Para isso, é possível fazer outra modificação no sistema operacional host instalando o nvidia-container-toolkit (NVIDIA Container Toolkit). Em primeiro lugar, abra outro shell transactional-update, lembrando que talvez isso já tenha sido feito em uma transação única na etapa anterior, e veja como fazer isso de maneira totalmente automatizada em uma seção posterior:

transactional-update shell

Em seguida, instale o pacote nvidia-container-toolkit do repositório NVIDIA Container Toolkit:

  • O nvidia-container-toolkit.repo a seguir contém um repositório estável (nvidia-container-toolkit) e outro experimental (nvidia-container-toolkit-experimental). O repositório estável é recomendado para uso em produção. O repositório experimental está desabilitado por padrão.

zypper ar https://nvidia.github.io/libnvidia-container/stable/rpm/nvidia-container-toolkit.repo
zypper --gpg-auto-import-keys install -y nvidia-container-toolkit

Quando estiver pronto, saia do shell transactional-update:

exit

…​e reinicie a máquina em um novo instantâneo:

reboot
Nota
Nota

Como antes, você precisa garantir que saiu do transactional-shell e reinicializou a máquina para que as alterações tenham efeito.

Depois que a máquina for reinicializada, verifique se o sistema pode enumerar corretamente os dispositivos usando o NVIDIA Container Toolkit. A saída deve ser detalhada, com mensagens INFO e WARN, mas sem mensagens ERROR:

nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml

Esse procedimento garante que os contêineres iniciados na máquina possam usar os dispositivos de GPU NVIDIA que foram descobertos. Quando estiver pronto, você poderá executar um contêiner baseado em podman. Usar o podman é uma boa forma de validar o acesso ao dispositivo NVIDIA de dentro de um contêiner, o que traz segurança para fazer o mesmo com o Kubernetes no futuro. Conceda ao podman acesso para os dispositivos NVIDIA identificados que foram processados pelo comando anterior, com base na SLE BCI, e simplesmente execute o comando Bash:

podman run --rm --device nvidia.com/gpu=all --security-opt=label=disable -it registry.suse.com/bci/bci-base:latest bash

Agora você executará os comandos de um contêiner podman temporário. Ele não tem acesso ao seu sistema subjacente e é efêmero, portanto, o que quer que se faça nele não vai persistir, e você não poderá danificar nada no host subjacente. Como estamos em um contêiner, podemos instalar as bibliotecas CUDA necessárias; mais uma vez, verificando a versão correta do CUDA para seu driver aqui, embora a saída anterior de nvidia-smi deva mostrar a versão necessária do CUDA. No exemplo a seguir, vamos instalar o CUDA 12.3 e extrair muitos exemplos, demonstrações e kits de desenvolvimento para você validar o GPU na íntegra:

zypper ar https://developer.download.nvidia.com/compute/cuda/repos/sles15/x86_64/ cuda-suse
zypper in -y cuda-libraries-devel-12-3 cuda-minimal-build-12-3 cuda-demo-suite-12-3

Após a devida instalação, não saia do contêiner. Executaremos o exemplo deviceQuery de CUDA, que valida de maneira completa o acesso da GPU por CUDA, e de dentro do próprio contêiner:

/usr/local/cuda-12/extras/demo_suite/deviceQuery

Se tudo correr bem, você verá uma saída como esta mostrada a seguir, com destaque para a mensagem Result = PASS no fim do comando e para a identificação correta das duas GPUs feita pelo sistema, considerando que seu ambiente pode ter apenas uma:

/usr/local/cuda-12/extras/demo_suite/deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 2 CUDA Capable device(s)

Device 0: "NVIDIA A100-PCIE-40GB"
  CUDA Driver Version / Runtime Version          12.2 / 12.1
  CUDA Capability Major/Minor version number:    8.0
  Total amount of global memory:                 40339 MBytes (42298834944 bytes)
  (108) Multiprocessors, ( 64) CUDA Cores/MP:     6912 CUDA Cores
  GPU Max Clock rate:                            1410 MHz (1.41 GHz)
  Memory Clock rate:                             1215 Mhz
  Memory Bus Width:                              5120-bit
  L2 Cache Size:                                 41943040 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 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 3 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 Compute Preemption:            Yes
  Supports Cooperative Kernel Launch:            Yes
  Supports MultiDevice Co-op Kernel Launch:      Yes
  Device PCI Domain ID / Bus ID / location ID:   0 / 23 / 0
  Compute Mode:
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

Device 1: <snip to reduce output for multiple devices>
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >
> Peer access from NVIDIA A100-PCIE-40GB (GPU0) -> NVIDIA A100-PCIE-40GB (GPU1) : Yes
> Peer access from NVIDIA A100-PCIE-40GB (GPU1) -> NVIDIA A100-PCIE-40GB (GPU0) : Yes

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 12.3, CUDA Runtime Version = 12.3, NumDevs = 2, Device0 = NVIDIA A100-PCIE-40GB, Device1 = NVIDIA A100-PCIE-40GB
Result = PASS

A partir deste ponto, você pode continuar executando qualquer outra carga de trabalho CUDA. Use os compiladores e qualquer outro elemento do ecossistema CUDA para realizar mais testes. Ao concluir, saia do contêiner, lembrando que tudo o que você instalou nele é efêmero (será perdido!) e não afeta o sistema operacional subjacente:

exit

33.5 Implementação com o Kubernetes

Agora que comprovamos a instalação e o uso do driver de código aberto da NVIDIA no SUSE Linux Micro, vamos explorar a configuração do Kubernetes na mesma máquina. Este guia não orienta na implantação do Kubernetes, mas ele considera que você já tenha o K3s ou o RKE2 instalado e que o kubeconfig esteja devidamente configurado, de modo que os comandos kubectl padrão possam ser executados como superusuário. Supomos que o seu nó forme um cluster de nó único, embora as etapas principais sejam similares nos clusters de vários nós. Primeiramente, garanta que o acesso ao kubectl esteja funcionando:

kubectl get nodes

Esse comando deve retornar algo semelhante ao seguinte:

NAME       STATUS   ROLES                       AGE   VERSION
node0001   Ready    control-plane,etcd,master   13d   v1.32.4+rke2r1

Você deve descobrir que a instalação do k3s/rke2 detectou o NVIDIA Container Toolkit no host e configurou automaticamente a integração do runtime NVIDIA ao containerd (a interface de tempo de execução do contêiner que o k3s/rke2 usa). Para confirmar isso, verifique o arquivo config.toml de containerd:

tail -n8 /var/lib/rancher/rke2/agent/etc/containerd/config.toml

Isso deve retornar algo semelhante ao que está mostrado a seguir. O local equivalente do K3s é /var/lib/rancher/k3s/agent/etc/containerd/config.toml:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."nvidia"]
  runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes."nvidia".options]
  BinaryName = "/usr/bin/nvidia-container-runtime"
Nota
Nota

Se estas entradas não estiverem presentes, talvez a detecção tenha falhado. O motivo pode ser a máquina ou os serviços do Kubernetes que não foram reiniciados. Se necessário, adicione-os manualmente conforme explicado acima.

Depois disso, precisamos configurar o RuntimeClass NVIDIA como runtime do Kubernetes adicional ao padrão, garantindo que as solicitações dos usuários para pods que precisam de acesso à GPU possam usar o NVIDIA Container Toolkit para fazer isso, por meio do comando nvidia-container-runtime, conforme definido na configuração de containerd:

kubectl apply -f - <<EOF
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia
EOF

A próxima etapa é configurar o plug-in de dispositivo NVIDIA, que configura o Kubernetes para aproveitar as GPUs NVIDIA como recursos no cluster que pode ser usado, trabalhando em conjunto com o NVIDIA Container Toolkit. Inicialmente, essa ferramenta detecta todos os recursos no host subjacente, incluindo GPUs, drivers e outros (como GL), e permite solicitar recursos para a GPU e consumi-los como parte dos seus aplicativos.

Primeiro, você precisa adicionar e atualizar o repositório Helm para o plug-in de dispositivo NVIDIA:

helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
helm repo update

Agora você pode instalar o plug-in de dispositivo NVIDIA:

helm upgrade -i nvdp nvdp/nvidia-device-plugin --namespace nvidia-device-plugin --create-namespace --version 0.14.5 --set runtimeClassName=nvidia

Após alguns minutos, você verá um novo pod em execução que concluirá a detecção em seus nós disponíveis e os marcará com o número de GPUs que foram detectadas:

kubectl get pods -n nvidia-device-plugin
NAME                              READY   STATUS    RESTARTS      AGE
nvdp-nvidia-device-plugin-jp697   1/1     Running   2 (12h ago)   6d3h

kubectl get node node0001 -o json | jq .status.capacity
{
  "cpu": "128",
  "ephemeral-storage": "466889732Ki",
  "hugepages-1Gi": "0",
  "hugepages-2Mi": "0",
  "memory": "32545636Ki",
  "nvidia.com/gpu": "1",                      <----
  "pods": "110"
}

Agora você está pronto para criar um pod NVIDIA que tenta usar essa GPU. Vamos tentar com o contêiner de benchmark CUDA:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: nbody-gpu-benchmark
  namespace: default
spec:
  restartPolicy: OnFailure
  runtimeClassName: nvidia
  containers:
  - name: cuda-container
    image: nvcr.io/nvidia/k8s/cuda-sample:nbody
    args: ["nbody", "-gpu", "-benchmark"]
    resources:
      limits:
        nvidia.com/gpu: 1
    env:
    - name: NVIDIA_VISIBLE_DEVICES
      value: all
    - name: NVIDIA_DRIVER_CAPABILITIES
      value: all
EOF

Se tudo correu bem, você pode consultar os registros para ver as informações de benchmark:

kubectl logs nbody-gpu-benchmark
Run "nbody -benchmark [-numbodies=<numBodies>]" to measure performance.
	-fullscreen       (run n-body simulation in fullscreen mode)
	-fp64             (use double precision floating point values for simulation)
	-hostmem          (stores simulation data in host memory)
	-benchmark        (run benchmark to measure performance)
	-numbodies=<N>    (number of bodies (>= 1) to run in simulation)
	-device=<d>       (where d=0,1,2.... for the CUDA device to use)
	-numdevices=<i>   (where i=(number of CUDA devices > 0) to use for simulation)
	-compare          (compares simulation results running once on the default GPU and once on the CPU)
	-cpu              (run n-body simulation on the CPU)
	-tipsy=<file.bin> (load a tipsy model file for simulation)

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

> Windowed mode
> Simulation data stored in video memory
> Single precision floating point simulation
> 1 Devices used for simulation
GPU Device 0: "Turing" with compute capability 7.5

> Compute 7.5 CUDA device: [Tesla T4]
40960 bodies, total time for 10 iterations: 101.677 ms
= 165.005 billion interactions per second
= 3300.103 single-precision GFLOP/s at 20 flops per interaction

Por fim, se os seus aplicativos exigem OpenGL, instale as bibliotecas OpenGL da NVIDIA necessárias no nível do host; e o plug-in de dispositivo NVIDIA e o NVIDIA Container Toolkit podem torná-las disponíveis aos contêineres. Para isso, instale o pacote da seguinte maneira:

transactional-update pkg install nvidia-gl-G06
Nota
Nota

Você precisa reinicializar para disponibilizar esse pacote aos seus aplicativos. O plug-in de dispositivo NVIDIA deve fazer essa nova detecção automaticamente por meio do NVIDIA Container Toolkit.

33.6 Reunindo tudo com o Edge Image Builder

Você demonstrou a total funcionalidade dos aplicativos e das GPUs no SUSE Linux Micro e agora quer usar o Capítulo 11, Edge Image Builder para disponibilizar tudo em uma imagem de disco ISO ou RAW implantável/consumível. Este guia não explica como usar o Edge Image Builder, mas aborda as configurações necessárias para criar essa imagem. Veja a seguir um exemplo de definição de imagem, junto com os arquivos de configuração necessários do Kubernetes, para garantir que todos os componentes obrigatórios sejam implantados imediatamente. Esta é a estrutura de diretórios do Edge Image Builder para o exemplo apresentado abaixo:

.
├── base-images
│   └── SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
├── eib-config-iso.yaml
├── kubernetes
│   ├── config
│   │   └── server.yaml
│   ├── helm
│   │   └── values
│   │       └── nvidia-device-plugin.yaml
│   └── manifests
│       └── nvidia-runtime-class.yaml
└── rpms
    └── gpg-keys
        └── nvidia-container-toolkit.key

Vamos explorar esses arquivos. Primeiro, esta é uma definição da imagem de amostra para um cluster de nó único com o K3s e que também implanta os utilitários e os pacotes OpenGL (eib-config-iso.yaml):

apiVersion: 1.2
image:
  arch: x86_64
  imageType: iso
  baseImage: SL-Micro.x86_64-6.1-Base-SelfInstall-GM.install.iso
  outputImageName: deployimage.iso
operatingSystem:
  time:
    timezone: Europe/London
    ntp:
      pools:
        - 2.suse.pool.ntp.org
  isoConfiguration:
    installDevice: /dev/sda
  users:
    - username: root
      encryptedPassword: $6$XcQN1xkuQKjWEtQG$WbhV80rbveDLJDz1c93K5Ga9JDjt3mF.ZUnhYtsS7uE52FR8mmT8Cnii/JPeFk9jzQO6eapESYZesZHO9EslD1
  packages:
    packageList:
      - nvidia-open-driver-G06-signed-kmp-default
      - nvidia-compute-utils-G06
      - nvidia-gl-G06
      - nvidia-container-toolkit
    additionalRepos:
      - url: https://download.nvidia.com/suse/sle15sp6/
      - url: https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64
    sccRegistrationCode: [snip]
kubernetes:
  version: v1.32.4+k3s1
  helm:
    charts:
      - name: nvidia-device-plugin
        version: v0.14.5
        installationNamespace: kube-system
        targetNamespace: nvidia-device-plugin
        createNamespace: true
        valuesFile: nvidia-device-plugin.yaml
        repositoryName: nvidia
    repositories:
      - name: nvidia
        url: https://nvidia.github.io/k8s-device-plugin
Nota
Nota

Este é apenas um exemplo. Você pode precisar personalizá-lo de acordo com os seus requisitos e expectativas. Além disso, se você usa o SUSE Linux Micro, precisa inserir seu próprio sccRegistrationCode para resolver as dependências de pacotes e obter os drivers da NVIDIA.

Além disso, precisamos adicionar outros componentes para que sejam carregados pelo Kubernetes no momento da inicialização. O diretório do EIB precisa primeiro de um diretório kubernetes, com os subdiretórios para configuração, os valores dos gráficos Helm e todos os manifestos adicionais necessários:

mkdir -p kubernetes/config kubernetes/helm/values kubernetes/manifests

Agora vamos definir a configuração (opcional) do Kubernetes escolhendo uma CNI (que assume o Cilium como padrão se nada for selecionado) e habilitando o SELinux:

cat << EOF > kubernetes/config/server.yaml
cni: cilium
selinux: true
EOF

Agora garanta que o RuntimeClass NVIDIA tenha sido criado no cluster Kubernetes:

cat << EOF > kubernetes/manifests/nvidia-runtime-class.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: nvidia
handler: nvidia
EOF

Usamos o Helm Controller incorporado para implantar o plug-in de dispositivo NVIDIA pelo próprio Kubernetes. Vamos inserir uma classe de runtime no arquivo de valores do gráfico:

cat << EOF > kubernetes/helm/values/nvidia-device-plugin.yaml
runtimeClassName: nvidia
EOF

Precisamos obter a chave pública do RPM do NVIDIA Container Toolkit antes de continuar:

mkdir -p rpms/gpg-keys
curl -o rpms/gpg-keys/nvidia-container-toolkit.key https://nvidia.github.io/libnvidia-container/gpgkey

Todos os artefatos necessários, incluindo o binário do Kubernetes, as imagens do contêiner, os gráficos Helm (e todas as imagens referenciadas), serão automaticamente isolados. Isso significa que, por padrão, o sistema não deve exigir conectividade de Internet no momento da implantação. Agora você precisa apenas obter a ISO do SUSE Linux Micro da página de downloads da SUSE (e salvá-la no diretório base-images) e chamar a ferramenta Edge Image Builder para gerar a ISO para você. Para concluir o exemplo, este é o comando que foi usado para criar a imagem:

podman run --rm --privileged -it -v /path/to/eib-files/:/eib \
registry.suse.com/edge/3.3/edge-image-builder:1.2.1 \
build --definition-file eib-config-iso.yaml

Para obter mais instruções, consulte a documentação do Edge Image Builder.

33.7 Resolvendo problemas

33.7.1 nvidia-smi não encontra a GPU

Verifique as mensagens do kernel usando o dmesg. Se isso indicar que não é possível alocar o NvKMSKapDevice, adote a solução alternativa para a GPU sem suporte:

sed -i '/NVreg_OpenRmEnableUnsupportedGpus/s/^#//g' /etc/modprobe.d/50-nvidia-default.conf

NOTA: Será necessário recarregar, ou reinicializar, o módulo do kernel se você alterar a configuração dele na etapa anterior para que as alterações entrem em vigor.

Documentation survey