Nutanix Enterprise AI no NKPParte 3: do catálogo ao primeiro token

Publicado
Leitura
19 min

Testado emNKP 2.19Nutanix Enterprise AI 2.8.1Kubernetes 1.36.2vLLM 0.26.0 (CPU)Lab em Em outra versão, confira a matriz de compatibilidade e as release notes antes de aplicar.

Read in English

Capa da série Nutanix Enterprise AI no NKP, com a parte 3, instalação, em destaque

Resumo: nesta parte o Nutanix Enterprise AI (NAI) sai do papel. Crio um cluster NKP dedicado, habilito as sete dependências do catálogo, instalo o NAI 2.8.1 com certificado da CA interna e aplico a licença no mesmo dia, porque o trial dura só 2 dias. Depois importo dois modelos do Hugging Face, um validado pela Nutanix e um custom, e coloco o primeiro endpoint para responder em CPU, com API key e API compatível com a OpenAI. Reuni aqui os quatro pré-requisitos e detalhes de configuração que fazem a instalação sair limpa, com a causa e o ajuste de cada um. No fim: 0,5 s até o primeiro token e 4,5 tokens/s num Xeon de 2019, e o que explica esse número no hardware do lab. Esta é a parte 3 de 4.

Onde estamos

A série acompanha a habilitação do Nutanix Enterprise AI num lab com NKP 2.19 e um cluster HCI Nutanix sem GPU.

ParteTema
1NAI: arquitetura, licenciamento e dimensionamento
2Nutanix Files para o Kubernetes: o RWX que o NAI exige
3Do catálogo ao primeiro token (este post)
4CPU, GPU e MCP: o NAI numa arquitetura híbrida

Na Parte 1 ficou decidido o desenho (cluster dedicado, como nos Nutanix Validated Designs) e na Parte 2 ficou pronta a storage class RWX nai-nfs. Agora é a instalação de verdade, numa sessão só, de ponta a ponta.


O roteiro em uma tabela

EtapaO que aconteceTempo no lab
1. Cluster dedicadoWorkspace próprio + cluster NKP com imagem Ubuntu~4 min até os nós Ready
2. Ajustes do cluster novoDNS interno no CoreDNS + ConfigMap do OpenCost~10 min (se você já souber)
3. Dependências7 apps do catálogo~7 min
4. Pré-requisitos do NAICA interna no cert-manager + credencial do registry do NAI~15 min
5. Enable do NAIApp do catálogo + override de configuração~8 min até Deployed
6. Primeiro login e licençaEULA, Pulse, senha, chave do portal~15 min
7. Node pool de inferênciaUm worker só para endpoints1 min 40 s
8. ModelosToken do Hugging Face, um validado e um custom~1,5 min por import
9. EndpointvLLM em CPU, API key, teste~8,5 min até Active

1. Um cluster só para o NAI

Os dois NVDs da Nutanix para o NAI colocam a plataforma num cluster dedicado, com workspace próprio. Segui o mesmo caminho: workspace ws-nai e um cluster com 1 control plane de 4 vCPU / 16 GiB e 3 workers de 12 vCPU / 40 GiB, todos com a imagem Ubuntu 24.04 do NKP 2.19, que é a do guia.

Assistente Create Cluster do NKP: configuração básica do cluster dedicado ao NAI

Node pool dos workers: 3 nós de 12 vCPU e 40 GiB com a imagem Ubuntu 24.04 do NKP

Do Create aos nós Ready foram 3 min 33 s. O cluster subiu com Kubernetes 1.36.2.

Cluster ativo na NKP v2.19.0

Dois ajustes que todo cluster novo precisou

Os dois já tinham aparecido no primeiro cluster de workload do lab, e voltaram aqui:

SintomaCausaAjuste
Apps do workspace aguardando, Flux sem conseguir clonar o repositórioO CoreDNS do cluster novo encaminha para um DNS público, que não resolve o domínio interno do managementBloco lab.exemplo.local no ConfigMap do CoreDNS com os nomes do Kommander e do Prism + rollout restart (o reload só atualizou 1 dos 2 pods)
Prometheus em CreateContainerConfigError e OpenCost sem iniciarFalta o ConfigMap cluster-info-configmap no namespace do workspaceCriar com CLUSTER_ID = UID do namespace kube-system do cluster

Faça antes: o DNS do cluster novo

Se o seu lab não tem DNS interno entregue pelo IPAM, aplique o bloco do CoreDNS logo que o cluster ficar ativo. No primeiro dia eu deixei para depois, e os apps ficaram 80 minutos aguardando o Flux.


2. As sete dependências

O app do NAI no catálogo traz a lista de dependências na anotação required-dependencies, e a tela de Enable também mostra. Na NKP 2.19, ficaram assim:

DependênciaVersão no catálogoObservação
Prometheus Monitoring (kube-prometheus-stack)já habilitado no workspace—
CloudNativePG0.29.0Banco do NAI
OpenTelemetry Operator0.114.1Coleta de métricas e auditoria
LeaderWorkerSet0.8.0Endpoints multi-nó
KServe0.19.0Modo RawDeployment
NAI – Envoy Gateway1.8.2Gateway próprio do NAI, com AI Gateway
NVIDIA GPU Operator26.3.3Obrigatório mesmo sem GPU; sobe só o operador e o driver DRA

Detalhe do CloudNativePG no catálogo do workspace

Enable do KServe 0.19.0 no workspace

Enable do NAI Envoy Gateway 1.8.2

As sete ficaram prontas em cerca de 7 minutos. A compatibilidade com a NKP 2.19 está na própria anotação do app: nkp-version-support: >=2.18 <2.20.


3. Antes do Enable: o que eu li no chart (e o que deixei passar)

Antes de clicar em Enable, baixei o artefato do catálogo (nutanix-ai:2.8.1) e o chart nai-core para ver o que o app faz. Valeu a pena:

AchadoConsequência
O catálogo injeta gateway.certManager.selfSigned: trueSem configurar nada, o NAI sobe com certificado autoassinado
global.storage.storageClassNameRWX padrão = nai-nfs-storageSe a sua storage class tem outro nome, os volumes dos modelos ficam Pending
dnsNames padrão = nai.nutanixdev.localCertificado com um nome genérico: ajuste para o seu domínio
Requests do nai-core: ~20,7 vCPU / 33 GiBOs 3 workers de 12 vCPU ficam com pouca folga para inferência (volto a isso no passo 7)
Imagens em docker.io/nutanix/nai-*Repositórios privados (este eu deixei passar; veja o pré-requisito do token na seção 4)

Certificado da CA interna

Para o navegador confiar no NAI sem aviso, emiti o certificado pela CA interna do lab. O chart aceita um ClusterIssuer do cert-manager. Criei o secret com o certificado e a chave da CA e o issuer:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: lab-ca
spec:
ca:
secretName: lab-ca # secret tls no namespace cert-manager

Um certificado de teste para nai.lab.exemplo.local saiu assinado pela CA e passou no openssl verify.

Proteja a CA: use uma intermediária

A chave da CA do lab estava protegida por senha, e o cert-manager espera a chave sem senha. Tirei a senha na própria máquina de administração, de forma interativa, e apaguei a cópia logo depois de criar o secret. Em cliente, use uma CA intermediária só para o cluster, nunca a raiz.


4. O Enable

No workspace, Applications → Nutanix Enterprise AI → Enable. O formulário tem dois campos de configuração: um para o workspace inteiro e um por cluster.

Formulário de Enable do NAI: versão 2.8.1, as sete dependências e o cluster selecionado

Usei só o campo do cluster. Hostname e certificado são deste cluster; se ficassem no campo do workspace, valeriam para qualquer cluster novo do workspace, e o NKP habilita o app sozinho nos clusters que entram depois.

O override final (com o imagePullSecrets do pré-requisito abaixo):

global:
storage:
storageClassName: nutanix-volume # RWO
storageClassNameRWX: nai-nfs # o padrão é nai-nfs-storage
imagePullSecrets:
- name: nai-dockerhub # repositórios privados nutanix/nai-*
gateway:
tlsSecretName: ingress-certificate
certManager:
selfSigned: false
issuerRef:
name: lab-ca
kind: ClusterIssuer
group: cert-manager.io
dnsNames:
- nai.lab.exemplo.local

Override no campo cluster-nai Configuration

Pré-requisito: o token do Docker Hub do NAI

Na minha primeira tentativa eu não tinha criado essa credencial, e um minuto depois do Enable os pods do nai-system estavam em ImagePullBackOff: pull access denied … insufficient_scope. Se você vir essa mensagem, há dois pontos a conferir:

  1. A ordem da injeção da credencial do NKP. O NKP injeta a credencial do registry com uma mutação do Gatekeeper, que só age quando o pod é criado num namespace com o label inject-registry-creds. O namespace nai-system nasceu às 21:51:22, os pods às 21:51:25, e o label e o secret só chegaram às 21:52:21. Os primeiros pods foram criados antes da credencial.
  2. O NAI tem credencial própria. Mesmo recriando os pods, o pull continuou negado: o usuário de registry do NKP baixa as imagens do NKP, e os repositórios nutanix/nai-* são privados do NAI. O NAI usa o access token do Docker Hub do NAI, gerado no portal em Downloads → Nutanix Enterprise AI → Generate Access Token (usuário de registry próprio do NAI).

O ajuste: criar um secret docker-registry com o token do NAI em dois namespaces, nai-system e envoy-gateway-system (o Envoy do NAI usa uma imagem privada), e apontar o global.imagePullSecrets no override.

Override com o imagePullSecrets no lugar errado, dentro de gateway.certManager

Confira o recuo do override antes de salvar

Na primeira tentativa, eu coloquei o imagePullSecrets dentro de gateway.certManager. O Kommander aceita o YAML, o Helm ignora a chave fora do lugar e nada muda. Confira o recuo antes de salvar.

Pré-requisito: faça isso antes do Enable

Crie o namespace nai-system e o secret com o token do NAI antes do Enable, e já coloque o imagePullSecrets no override. Assim o primeiro Enable já sobe com a credencial certa.

Quando o primeiro Enable não conclui: Disable + Enable

Com a configuração ajustada, o NAI não reinstalou sozinho. Como a primeira instalação dos operadores não tinha concluído (por causa do ImagePull), o Flux entrou em desinstalação para tentar de novo. O chart tem um hook de pré-desinstalação que espera o HelmRelease nutanix-ai sair, e esse depende dos operadores. O hook espera até 30 minutos; o uninstall expira em 15.

O caminho mais rápido foi Disable → limpeza → Enable. Depois do Disable, sobraram um PVC do Valkey, um ConfigMap criado fora do Helm e um secret de webhook, todos sem dados. Apaguei os três e mantive o namespace, os secrets do registry e o issuer.

Se o primeiro Enable não concluir: Disable + Enable

Quando a primeira instalação não conclui, o hook de pré-desinstalação e a dependência entre HelmReleases esperam um pelo outro. Em vez de esperar o Flux: Disable, limpe os restos e habilite de novo. O segundo Enable, com o namespace e as credenciais já no lugar, foi limpo e levou 8 minutos.

O segundo Enable: 8 minutos

HorárioEvento
21:18:09Enable confirmado
21:20nutanix-ai-operators instalado (Valkey, banco, ClickHouse operator, AI Gateway)
21:23nutanix-ai instalando; erros transitórios de bootstrap (certificados do IAM, nai-api esperando o banco)
21:26nutanix-ai instalado: 27 pods (23 Running, 4 Completed), Deployed no Kommander

Nutanix Enterprise AI com status Deployed no cluster

O Envoy do NAI pegou o próximo IP livre do pool do MetalLB (198.51.100.131) e o certificado ficou pronto, emitido pela CA do lab. Pela bastion, um curl --resolve com a CA do lab validou a cadeia e recebeu o redirecionamento para o login.


5. Primeiro login: EULA, Pulse e senha

Com o nome no DNS (no lab, por enquanto, no /etc/hosts), a tela de login abre em https://nai.lab.exemplo.local com o certificado válido.

Tela de login do Nutanix Enterprise AI

Usuário admin com a senha padrão do guia. No 2.8.1, a ordem das telas é: EULA (nome e empresa), depois Pulse, depois a troca de senha (o guia mostra outra ordem).

Tela do Pulse no primeiro login, com a telemetria ligada

Depois do Pulse: entre de novo

Depois de Save and Proceed no Pulse, a minha sessão mostrou 403 Access Denied. Nos logs, as gravações de EULA e Pulse voltaram 200 e o Envoy não registrou nenhum 403: a sessão aberta antes da EULA só não tinha os atributos de autorização atualizados.

Tela 403 Access Denied logo depois de salvar o Pulse

O que fazer: Back to login e entrar de novo. Aí veio a troca de senha e o dashboard.

Dashboard do NAI no primeiro acesso, com o aviso Next, Add License

Pulse

Deixei a telemetria ligada no lab, como no NKP. Em cliente, principalmente no setor público, é decisão de política de dados.


6. A licença: no mesmo dia

O NAI tem trial de só 2 dias depois da instalação, e a licença de CPU ou GPU só pode ser adicionada na primeira instalação. Então ela vem logo depois do primeiro login.

Settings, Licensing antes: Unlicensed, 0 vCPU

O caminho:

  1. No NAI, Settings → Licensing → Add License mostra o Kubernetes Cluster ID. É o UID do namespace kube-system do cluster (conferi pela bastion).
  2. No portal da Nutanix, Licenses → Manage Licenses → Manage NAI/NKP License → NAI: informar o nome e o UUID do cluster, escolher NAI Pro (VCPU) e a quantidade.
  3. Gerar a chave e voltar ao NAI.

Janela Add License com o Kubernetes Cluster ID

Portal: 36 vCPU para o cluster, de um saldo de 600

Escolhi 36 vCPU, os 3 workers × 12, o teto que um endpoint consegue usar nesse cluster.

Revisão no portal: NAI Pro, 36 vCPU, validade

Para chave de vCPU, selecione CPU License

A janela Add License do NAI abre com GPU GB License selecionado. Para chave de vCPU, troque para CPU License antes de colar.

Licensing depois: Pro, NAI CPU, 36 vCPUs

E o Agent Gateway?

A tela de licença tem um terceiro tipo, Agentic Gateway License: “Required for accessing Unified Endpoints and MCP Connectors”. É um direito separado, medido em access keys. Uma chave de vCPU colada nesse campo dá “Meter type mismatch”.

Chave de vCPU colada como Agentic Gateway: Meter type mismatch

LicençaLiberaMétrica
CPUEndpoints em CPUvCPU
GPUEndpoints em GPUGB de memória de GPU
Agent GatewayUnified Endpoints, Providers, MCPaccess keys

O lab ainda não tem o direito de Agent Gateway. Ele fica para a Parte 4.


7. Um node pool só para inferência

Depois do Enable, os requests de CPU dos três workers ficaram em 77%, 96% e 83%, com uso real de ~5%. Sobravam ~2,7 vCPU agendáveis no melhor nó. O guia confirma o motivo: os 3 workers de 10 vCPU da tabela de requisitos são só para o plano de controle do NAI, e os recursos de inferência são à parte.

A solução foi um node pool nai-cpu: 1 worker de 12 vCPU / 48 GiB, sem taint (no NAI 2.8.1, os endpoints em CPU usam o agendamento padrão, sem toleration nem nodeSelector).

Add Worker Node Pool: nai-cpu, 1 nó, 12 vCPU, 48 GiB

Três node pools no cluster: control plane, workers e nai-cpu

Do Add ao nó Ready: 1 min 40 s, com ~11,6 vCPU livres.

Label de node pool que chega ao nó

O label personalizado que coloquei no formulário (lab.exemplo.local/pool=nai-cpu) ficou no objeto Machine: o Cluster API copia para o nó só os labels com prefixo node.cluster.x-k8s.io/. Se precisar selecionar o nó por label, use esse prefixo.


8. Modelos: Hugging Face, validado e custom

Uma conta de serviço no Hugging Face

Criei uma conta do lab no Hugging Face, em vez de usar a pessoal: o token não depende de uma pessoa e a separação fica limpa. Dois modelos para comparar:

PapelModeloGate
Validadogoogle/gemma-3-270m-itSim: licença do Google (o aceite passa pelo Kaggle)
CustomQwen/Qwen3-0.6BNão (Apache-2.0)

Gemma no Hugging Face: é preciso aceitar a licença

Qwen3-0.6B: abre direto, sem gate

O token é do tipo Read. Em cliente, prefira um token fine-grained com leitura só dos repositórios usados.

Criação do token Read no Hugging Face

No NAI, Settings → Third Party Credentials → Add Credential, plataforma Hugging Face. A tela avisa que só cabe um token do Hugging Face por NAI.

Add Credential: plataforma Hugging Face, uma credencial por plataforma

O modelo validado

Models → Import Models → From Hugging Face Model Hub lista 52 modelos validados.

Catálogo do Hugging Face Model Hub no NAI: 52 modelos validados

Import do gemma-3-270m-it com nome de instância próprio

O status passa por Pending → Waiting for storage. Por trás, o NAI cria um objeto Model e um PVC RWX na nai-nfs, o Files cria o share e um job baixa o modelo. Tempo total: ~1,5 min.

EtapaDesde o clique
PVC de 10 GiB RWX Bound (share no Files)28 s
Job de download iniciado no nó nai-cpu56 s
Modelo Active88 s

Gemma em Pending, Waiting for storage

Governança: o NAI começa fechado (deny by default)

Com o Gemma pronto, o NAI mostrou o aviso “The usage of this model has been restricted by the administrator”. É a governança funcionando: numa instalação nova, o Model Access Control começa sem modelos liberados (0 de 52 do Hugging Face e 0 de 32 do NGC), com import por URL e upload manual desligados, e o administrador libera o que for usar.

Model Access Control na instalação: 0 de 32 e 0 de 52, URL e upload manual desligados

No lab, liberei os catálogos e os dois toggles. Um detalhe: no NGC, Allow all validated libera 27 de 32. Os outros 5 estão no catálogo sem o selo de validado, e só entram com Allow specific models.

NGC: cinco modelos do catálogo sem o selo de validado

Governança de verdade

Deny by default para modelos é um bom argumento para cliente. Em produção, libere por lista e mantenha URL e upload manual desligados, a menos que haja necessidade.

O custom model, pela URL

Na mesma tela do Hub, o link Import using Model URL aceita qualquer repositório do Hugging Face. O NAI pede uma confirmação explícita:

Import pela URL: Qwen/Qwen3-0.6B

Confirm to Proceed: modelo não validado, digitar confirm

Import em 59 s (o share ficou pronto em 3 s e a imagem do processador já estava em cache).

Os dois modelos Ready

No objeto Model, apareceu uma diferença que vale conhecer:

Gemma (validado, Hub)Qwen3 (custom, URL)
Revisão do repositóriofixada num commitvazia: baixa o que estiver no main
Tamanho do volume10 GiB (catálogo)12 GiB (estimado)
Confirmação de riscoNãoSim
CPU e memória do endpointSugeridos pelo NAIVocê define

9. O primeiro endpoint

Escolha um modelo com perfil de CPU

Local Endpoints → Create Endpoint com o Gemma, e a tela mostrou: “No supported accelerator types available”.

Endpoint com o Gemma validado: nenhum tipo de acelerador disponível

O cluster estava pronto: o NFD detectou AVX-512 em todos os nós e o inventário do NAI via 11,6 vCPU livres no nai-cpu. O que define a opção é o perfil do modelo: no catálogo 2.8.1, o Gemma 3 270M é validado para GPU. Com o Qwen3 custom, a opção CPU aparece (e a de Intel AMX fica cinza, porque o Xeon do lab é de 2ª geração).

Endpoint com o Qwen3 custom: aceleração CPU disponível

A configuração

Motor vLLM, imagem da Nutanix v0.26.0. A tela avisa que o vLLM é community-supported e mostra outras origens de imagem.

Engine Source: imagem da NAI, registry da comunidade vLLM ou outro registry

Configuração avançada: imutável depois de criar

Para custom model, você define o tamanho. Usei:

CampoValorPor quê
vCPU8O vLLM em CPU escala com núcleos; cabe no nai-cpu e usa 8 dos 36 da licença
Memória16 GiBModelo de ~1,5 GB mais cache de contexto e runtime
Contexto4096 tokensEm CPU, o cache cresce com o contexto

Configuração do endpoint: vLLM, 8 vCPU, 16 GiB, contexto 4096

De Pending a Active: 8,5 minutos

Por trás, o NAI cria um InferenceService do KServe com o pod do vLLM no nó nai-cpu, com requests iguais aos limits (8 CPU / 16 GiB).

EtapaDuração
Pull da imagem nai-vllm (primeira vez no nó)3 min 28 s
Leitura dos pesos pelo NFS (1,40 GiB)2,4 s
Aquecimento e compilação do vLLM em CPU2 min 20 s
Probe de prontidão (a cada 60 s)~1 min
Total~8,5 min

Endpoint qwen3-06b-cpu Active

A página do endpoint mostra a URL compatível com a OpenAI. No campo model, vai o nome do endpoint.

Access URL do endpoint e API key mascarada


10. O primeiro token

Pela interface

O botão Test responde com o modo de raciocínio do Qwen3 ligado (o padrão do modelo): a resposta começa com o raciocínio em inglês e depois vem em português. Pela API, dá para desligar com enable_thinking: false.

Test pela interface: raciocínio em inglês antes da resposta

Pela API

Pela bastion, com a API key num prompt sem eco:

Terminal window
curl https://nai.lab.exemplo.local/enterpriseai/v1/chat/completions \
-H "Authorization: Bearer $NAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-06b-cpu",
"messages": [
{"role": "system", "content": "Responda sempre em português do Brasil."},
{"role": "user", "content": "Explique em 3 frases o que é o Nutanix Enterprise AI."}
],
"max_tokens": 200,
"chat_template_kwargs": {"enable_thinking": false}
}'
TesteResultado
Sem API keyHTTP 401
GET /enterpriseai/v1/modelsqwen3-06b-cpu
Chat (não-streaming)HTTP 200, 78 tokens em 17 s, resposta em português
Streaming, 3 rodadas de ~200 tokensTTFT 0,48–0,60 s e 4,3–4,6 tokens/s

A resposta veio no formato pedido e genérica no conteúdo, como se espera de um modelo de 0,6B.

Por que 4,5 tokens/s

Medi em vez de supor:

FatorO que viEfeito
CPU throttlingPod limitado a 8 vCPU, mas o vLLM enxerga os 12 núcleos do nó e abre 11 threads OpenMP: 20,5% dos períodos estranguladosO processo fica parado esperando cota de CPU
Sem BF16A CPU (Cascade Lake) tem AVX-512 e VNNI, mas não AVX512_BF16 nem AMXO vLLM roda em FP32: o dobro de memória e mais lento

Dá para melhorar o primeiro com VLLM_CPU_OMP_THREADS_BIND igual aos núcleos do pod. No NAI 2.8.1, a configuração avançada do endpoint oferece Engine Arguments e KV Cache Aware Routing; uma variável de ambiente como essa vai no InferenceService do KServe. A Parte 4 mostra o passo a passo e o ganho: +40% de tokens/s. O segundo é do hardware do lab. Para comparação, o appliance com GPU do lab serve um modelo de 30B com NIM a ~66 tokens/s.

CPU serve para quê

Num cluster sem GPU, o NAI em CPU demonstra a plataforma inteira: catálogo, governança de modelos, licença, endpoints com API key, API compatível com a OpenAI, auditoria e métricas. Para desempenho, é GPU (ou CPU com AMX).


Os números

MedidaValor
Cluster dedicado: Create → nós Ready3 min 33 s
Dependências do catálogo~7 min
Enable (2º) → Deployed~8 min, 27 pods
Requests do NAI (padrão)~20,7 vCPU / 33 GiB
Node pool nai-cpu: Add → Ready1 min 40 s
Import do modelo validado (10 GiB)88 s
Import do custom (12 GiB)59 s
Endpoint em CPU: Create → Active~8,5 min
Tempo até o primeiro token0,5 s
Velocidade4,5 tokens/s (8 vCPU, FP32)
Licença aplicadaNAI Pro, 36 vCPU, no dia da instalação

O que aprendi

  1. Leia o chart antes do Enable. O padrão vem com certificado autoassinado e com storage class e hostname genéricos: ajuste para o seu ambiente.
  2. O NAI tem credencial própria de registry. Crie o namespace nai-system e o secret com o token do Docker Hub do NAI antes do Enable, inclusive em envoy-gateway-system.
  3. Se o primeiro Enable não concluir, Disable + limpeza + Enable. É o caminho mais rápido, sem esperar o Flux.
  4. Licença no mesmo dia, tipo CPU. O trial é de 2 dias, e a janela abre em GPU.
  5. Dimensione os workers para o plano de controle do NAI. Os requests padrão pedem ~21 vCPU; reserve um node pool para inferência.
  6. Governança desde o primeiro dia. O Model Access Control vem em deny by default; libere por lista.
  7. Confira o tipo de acelerador do modelo antes de escolher o modelo da demo: validado para GPU não implica perfil de CPU.
  8. No meu lab, CPU sem BF16/AMX serve para demonstração; para desempenho, GPU ou CPU com AMX. E ajuste as threads do vLLM ao limite do pod.

Checklist: NAI 2.8.1 no NKP

  • Cluster dedicado com imagem Ubuntu; CoreDNS e cluster-info-configmap ajustados
  • Storage class RWX pronta (Immediate)
  • As 7 dependências do catálogo habilitadas
  • ClusterIssuer da CA interna (ou aceitar o autoassinado)
  • Token do Docker Hub do NAI e secret em nai-system e envoy-gateway-system
  • Override no campo do cluster: storage classes, imagePullSecrets, issuer e dnsNames
  • DNS do nome do NAI apontando para o IP do Envoy
  • Primeiro login (EULA → Pulse → senha); se aparecer 403 depois do Pulse, entrar de novo
  • Licença CPU aplicada no mesmo dia
  • Node pool para inferência
  • Token do Hugging Face (Read ou fine-grained) e licenças gated aceitas
  • Model Access Control liberado por lista
  • Endpoint com API key; teste sem chave (401) e com chave (200)

O que ainda não testei

  • Endpoints em GPU no NAI. O cluster do lab não tem GPU, e a licença aplicada foi a de CPU. A GPU dentro do próprio NKP é o próximo passo do lab.
  • Inferência em CPU com BF16 ou AMX. Os hosts do lab são Cascade Lake, sem AVX512_BF16 nem AMX, e o vLLM roda em FP32.
  • O ajuste de threads do vLLM (VLLM_CPU_OMP_THREADS_BIND): ficou para a Parte 4, que mostra o passo a passo e o ganho de +40%.
  • O Agent Gateway (unified endpoints e MCP): o lab ainda não tinha esse direito nesta etapa, e ele ficou para a Parte 4.

Próxima parte

Na Parte 4, o NAI deixa de ser uma ilha: o mesmo cliente OpenAI chamando o endpoint em CPU do NAI e o modelo na GPU do lab, o Agent Gateway com MCP e a observabilidade de tokens.

Referências

Nutanix

  • Nutanix Enterprise AI Guide 2.8.1 (portal Nutanix): requisitos (p. 13–17), deploy no NKP, Docker Hub access token (p. 28), login (p. 132), licenciamento (p. 173–178), Model Access Control (p. 194), import de modelos (p. 197–202), endpoints (p. 225–246)
  • Nutanix Validated Design: Nutanix Enterprise AI (NVD-2057)

Projetos e comunidade

Comentários

Os comentários usam o GitHub Discussions; é preciso ter uma conta no GitHub.