

 **Ajudar a melhorar esta página** 

Para contribuir com este guia de usuário, escolha o link **Editar esta página no GitHub**, disponível no painel direito de cada página.

# Gerenciar a computação para workloads de IA/ML com o Modo Automático do EKS e o Karpenter
<a name="ml-node-pools"></a>

**dica**  
 [Registre-se](https://events.eksworkshop.com/workshops/genai/) para os próximos workshops do Amazon EKS AI/ML.

Esta seção aborda como gerenciar a computação acelerada (AWS Trainium, GPUs da NVIDIA) para workloads de treinamento e inferência de IA usando o Modo Automático do Amazon EKS ou o Karpenter autogerenciado.

O Modo Automático do EKS e o Karpenter são compatíveis com dois modos de provisionamento: provisionamento dinâmico e provisionamento estático. Com o provisionamento dinâmico, o Modo Automático do EKS e o Karpenter provisionam e escalam instâncias com computação acelerada conforme as workloads são agendadas no cluster. Com o provisionamento estático, o Modo Automático do EKS e o Karpenter provisionam e mantêm um número fixo de nós. O provisionamento dinâmico e estático pode ser usado no mesmo cluster para manter um grupo de capacidade de linha de base constante e, ao mesmo tempo, escalar de acordo com as demandas das workloads.

O Modo Automático do EKS e o Karpenter são compatíveis com todas as quatro opções de compra de capacidade (sob demanda, spot, Blocos de Capacidade e ODCRs) e sempre provisionam primeiro a capacidade reservada, seguida pela spot ou sob demanda.

## Modo Automático do EKS vs Karpenter
<a name="eks-aiml-auto-mode-vs-karpenter"></a>

Ambas as abordagens compartilham a API do NodePool, mas diferem em propriedade operacional, APIs de recursos, suporte ao sistema operacional, tratamento de interrupções spot e flexibilidade de configuração.


| Recurso | Modo Automático do EKS | Karpenter autogerenciado | 
| --- | --- | --- | 
| Melhor para | Equipes que preferem uma infraestrutura gerenciada com despesas operacionais mínimas | Equipes que preferem controle total sobre o ciclo de vida dos nós, AMIs, ajuste do sistema operacional e aplicação de patches. | 
| Modelo operacional |  A AWS provisiona e gerencia o controlador do Karpenter, os drivers de GPU/Trainium, os plug-ins de dispositivo, a aplicação de patches do sistema operacional e o tratamento de interrupções spot. | Você instala e opera o controlador do Karpenter em seu cluster e é responsável pelos drivers de GPU/Trainium, plug-ins de dispositivos, ciclo de vida das AMIs, aplicação de patches e tratamento de interrupções spot. | 
| Opções de computação | Sob demanda, Spot, ODCRs, Blocos de Capacidade para ML | Sob demanda, Spot, ODCRs, Blocos de Capacidade para ML | 
| APIs de recursos |  `NodePool` (`karpenter.sh/v1`), `NodeClass` (`eks.amazonaws.com/v1`). |  `NodePool` (`karpenter.sh/v1`), `EC2NodeClass` (`karpenter.k8s.aws/v1`). | 
| Sistema operacional dos nós | Somente Bottlerocket. Dependências da GPU da NVIDIA, do AWS Trainium e do EFA incluídas. | AL2023, Bottlerocket, Windows ou sua própria AMI. | 
| Vida útil dos nós | Vida útil máxima dos nós de 21 dias para aplicação de patches de segurança. As workloads devem tolerar a rotação de nós. | Você define o ciclo de vida dos nós por meio do NodePool `expireAfter` e dos orçamentos de interrupção. | 
| Tratamento de interrupções spot | Nativo. Nenhuma fila SQS ou Node Termination Handler é necessário. | Sua responsabilidade de configurar e habilitar. | 
| Pulls rápidos de contêineres | SOCI parallel pull incluído em todas as instâncias das famílias G, P e Trn | Sua responsabilidade de configurar e habilitar. | 
| Grupos de posicionamento do EC2 | Cluster, partição, distribuição | Cluster, partição, distribuição | 
| Configuração da interface de rede | Por configuração de interface para tipo `interface` ou `EFA-only`  | Por configuração de interface para tipo `interface` ou `EFA-only`  | 
| Reparo de nós | Habilitado por padrão, o agente de monitoramento de nós do EKS está incluído | Habilitado opcionalmente, o agente de monitoramento de nós do EKS é autogerenciado | 
| Preços |  [Taxa de gerenciamento do Modo Automático do EKS](https://aws.amazon.com/eks/pricing/), além do custo subjacente da instância do EC2. | Código aberto. Você paga pelas instâncias subjacentes do EC2. | 

## Rótulos comuns conhecidos de IA/ML
<a name="eks-aiml-labels"></a>

O Modo Automático do EKS e o Karpenter expõem rótulos de instância que você pode usar em `requirements` do NodePool e no `nodeSelector` ou `nodeAffinity` do pod para direcionar workloads sem codificar tipos de instância. O prefixo do rótulo difere entre os dois: o Modo Automático do EKS usa `eks.amazonaws.com/` enquanto o Karpenter autogerenciado usa `karpenter.k8s.aws/`.

As tabelas abaixo mostram rótulos relevantes que podem ser usados nos NodePools. O Modo Automático do EKS e o Karpenter também aplicam os rótulos listados na [documentação do Karpenter](https://karpenter.sh/docs/concepts/scheduling/#labels) aos nós como parte do processo de provisionamento que pode ser usado posteriormente para o direcionamento da workload.

------
#### [ EKS Auto Mode ]

Para ver a lista completa, consulte [Rótulos compatíveis com o Modo Automático do EKS](https://docs.aws.amazon.com/eks/latest/userguide/create-node-pool.html#auto-supported-labels).


| Rótulo | Valor de exemplo | Descrição | 
| --- | --- | --- | 
|  `eks.amazonaws.com/instance-family`  |  `p5`  | Tipos de instância de propriedades semelhantes, mas com quantidades de recursos diferentes. | 
|  `eks.amazonaws.com/instance-category`  |  `p`  | Categoria da instância, geralmente a letra antes do número de geração. | 
|  `eks.amazonaws.com/instance-generation`  |  `5`  | Número de geração do tipo de instância em uma categoria. | 
|  `eks.amazonaws.com/instance-gpu-name`  |  `h100`  | Nome da GPU na instância. | 
|  `eks.amazonaws.com/instance-gpu-manufacturer`  |  `nvidia`  | Nome do fabricante da GPU. | 
|  `eks.amazonaws.com/instance-gpu-count`  |  `8`  | Número de GPUs na instância. | 
|  `eks.amazonaws.com/instance-gpu-memory`  |  `81920`  | Mebibytes de memória por GPU. | 
|  `karpenter.sh/capacity-type`  |  `reserved`  | Tipo de capacidade: `spot`, `on-demand` ou `reserved`. | 
|  `topology.kubernetes.io/zone`  |  `us-east-1a`  | Zona de disponibilidade. | 

------
#### [ Self-managed Karpenter ]

Para ver a lista completa, consulte [Rótulos conhecidos do Karpenter](https://karpenter.sh/docs/concepts/scheduling/#well-known-labels).


| Rótulo | Valor de exemplo | Descrição | 
| --- | --- | --- | 
|  `karpenter.k8s.aws/instance-family`  |  `p5`  | Tipos de instância de propriedades semelhantes, mas com quantidades de recursos diferentes. | 
|  `karpenter.k8s.aws/instance-category`  |  `p`  | Categoria da instância, geralmente a letra antes do número de geração. | 
|  `karpenter.k8s.aws/instance-generation`  |  `5`  | Número de geração do tipo de instância em uma categoria. | 
|  `karpenter.k8s.aws/instance-gpu-name`  |  `h100`  | Nome da GPU na instância. | 
|  `karpenter.k8s.aws/instance-gpu-manufacturer`  |  `nvidia`  | Nome do fabricante da GPU. | 
|  `karpenter.k8s.aws/instance-gpu-count`  |  `8`  | Número de GPUs na instância. | 
|  `karpenter.sh/capacity-type`  |  `reserved`  | Tipo de capacidade: `spot`, `on-demand` ou `reserved`. | 
|  `topology.kubernetes.io/zone`  |  `us-east-1a`  | Zona de disponibilidade. | 
|  `kubernetes.io/arch`  |  `amd64`  | Arquitetura da CPU. | 

------

## Rótulos de agendamento para capacidade reservada
<a name="eks-aiml-scheduling-labels"></a>

Quando o Modo Automático do EKS ou o Karpenter inicia um nó em uma reserva, ele adiciona os rótulos a seguir. Use-os em `nodeSelector`, afinidade de nós ou requisitos do NodePool para rotear workloads.
+  `karpenter.sh/capacity-type`: `reserved`, `on-demand`, ou `spot`. Indica a capacidade que dá suporte ao nó.
+  `karpenter.k8s.aws/capacity-reservation-id`: o ID de reserva específico em que o nó foi inicializado.
+  `karpenter.k8s.aws/capacity-reservation-type`: `default` para ODCRs, `capacity-block` para Blocos de Capacidade.

Os exemplos a seguir mostram padrões de agendamento comuns:

 **Fixe um pod em uma reserva específica (sem fallback):** 

```
spec:
  nodeSelector:
    karpenter.sh/capacity-type: reserved
    karpenter.k8s.aws/capacity-reservation-id: "cr-0123456789abcdef0"
```

 **Somente nós ODCR de destino (qualquer ODCR, não Blocos de Capacidade):** 

```
spec:
  nodeSelector:
    karpenter.sh/capacity-type: reserved
    karpenter.k8s.aws/capacity-reservation-type: default
```

 **Direcione para qualquer capacidade reservada (ODCR ou Bloco de Capacidade):** 

```
spec:
  nodeSelector:
    karpenter.sh/capacity-type: reserved
```

 **Prefira instâncias reservadas, mas use spot ou sob demanda como fallback se não estiverem disponíveis:** 

```
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 100
          preference:
            matchExpressions:
              - key: karpenter.sh/capacity-type
                operator: In
                values: ["reserved"]
```

## Comportamento na expiração da reserva
<a name="eks-aiml-node-pools-expiration"></a>

Os ODCRs e os Blocos de Capacidade se comportam de forma diferente quando a reserva termina. Certifique-se de que sua estratégia de agendamento e ponto de verificação seja compatível com o tipo de reserva que dá suporte à sua workload.

 **ODCRs** 

Uma instância inicializada em um ODCR não permanece nesse ODCR indefinidamente. O ODCR pode expirar, ser cancelado ou a instância pode ser removida manualmente do ODCR. Se alguma dessas situações ocorrer e o Modo Automático do EKS ou o Karpenter detectar que a instância não pertence mais a um ODCR, ele atualizará o rótulo `karpenter.sh/capacity-type` do nó de `reserved` para `on-demand`. A instância continua em execução como capacidade sob demanda padrão, e os pods existentes continuam em execução sem interrupções.

**nota**  
Qualquer pod programado com um `nodeSelector: karpenter.sh/capacity-type: reserved` estrito não será programado no nó se ele tiver sido renomeado. Para que as workloads sobrevivam à expiração ou ao cancelamento do ODCR, use o padrão `preferredDuringSchedulingIgnoredDuringExecution` mostrado acima em vez de um `nodeSelector`.

 **Blocos de capacidade** 

Ao contrário dos ODCRs, os Blocos de Capacidade sempre têm um horário de término, e o EC2 encerra as instâncias do Bloco de Capacidade 30 minutos antes do horário final (60 minutos para os tipos de instância UltraServer). Planeje trabalhos de treinamento e inferência para concluir ou salvar o estado antes que a janela de reserva seja encerrada. Pods que usam um `nodeSelector` estrito em um `capacity-reservation-id` específico ficam `Pending` quando o bloco expira e não serão reagendados em outro lugar. Combine o ponto de verificação com o padrão de afinidade flexível acima se precisar que as workloads sejam transferidas para outra capacidade durante a expiração do Bloco de Capacidade.
+ É possível usar instâncias reservadas até 30 minutos antes do horário de término do Bloco de Capacidade para a maioria dos tipos de instância, ou 60 minutos antes do horário de término para tipos de instância UltraServer.
+ O Modo Automático do EKS e o Karpenter começam preventivamente a drenar os nós em um Bloco de Capacidade dez minutos antes do início do encerramento do EC2, para que as workloads tenham tempo para o ponto de verificação e desligar normalmente.

## NodePools de capacidade estática
<a name="eks-aiml-static-capacity-nodepools"></a>

O Modo Automático do EKS e o Karpenter são compatíveis com NodePools de *capacidade estática*, que mantêm um número fixo de nós independentemente da demanda das workloads. Os grupos estáticos eliminam atrasos de inicialização a frio para inferências sensíveis à latência e permitem que você reserve uma capacidade mínima da infraestrutura para o seu cluster.

A capacidade estática é configurada definindo o campo `replicas` no NodePool.

 **Considerações** 
+ Depois que `replicas` for configurado em um NodePool, ele não poderá ser removido. Um único NodePool não pode alternar entre o provisionamento de capacidade estática e dinâmica.
+ NodePools de capacidade estática não são considerados para consolidação. Defina `limits.nodes` acima de `replicas` para permitir a escalabilidade temporária durante o desvio ou a expiração da AMI.
+ Para uma distribuição previsível das zonas de disponibilidade (AZ), crie um NodePool de capacidade estática por AZ em vez de abranger várias zonas em um único grupo.

------
#### [ EKS Auto Mode ]

O exemplo abaixo mostra um NodePool de capacidade estática que usa o NodeClass padrão do Modo Automático do EKS e cria um NodePool estático com quatro nós (`replicas`) que pode ter no máximo seis nós (`limits.nodes`).

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-static-inference
spec:
  replicas: 4
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "eks.amazonaws.com/instance-family"
          operator: In
          values: ["g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    nodes: 6   # Allow temporary headroom during node replacement
```

------
#### [ Self-managed Karpenter ]

Com o Karpenter autogerenciado, a capacidade estática é controlada pelo recurso alfa `StaticCapacity` (lançado na versão v1.8 do Karpenter), que deve ser habilitado nos valores do Helm:

```
settings:
  featureGates:
    staticCapacity: true
```

O NodePool faz referência a um `EC2NodeClass` personalizado denominado `my-nodeclass` e cria um NodePool estático com quatro nós (`replicas`) que podem ter no máximo seis nós (`limits.nodes`).

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-static-inference
spec:
  replicas: 4
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: my-nodeclass
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    nodes: 6   # Allow temporary headroom during node replacement
```

------

## Blocos de capacidade para ML
<a name="eks-aiml-capacity-blocks"></a>

 Os [Blocos de Capacidade para ML](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-blocks.html) permitem que você reserve instâncias da família P e Trainium para uma janela futura definida. Elas são pré-pagas, então o Modo Automático do EKS e o Karpenter as modelam como gratuitas e as priorizam em relação às sob demanda e spot. Os Blocos de Capacidade para ML podem ter uma duração de reserva de 1 a 14 dias ou um múltiplo de 7 dias, até 182 dias (6 meses).

Para usar os Blocos de Capacidade para ML com o Modo Automático do EKS ou o Karpenter, configure `capacityReservationSelectorTerms` com seu ID de reserva de capacidade em seu NodeClass. Você não pode usar a correspondência de reservas abertas com Blocos de Capacidade para ML. Um termo pode especificar um ID, um conjunto de tags ou critérios de correspondência de instância a serem selecionados. Ao especificar as tags, ele selecionará todas as reservas de capacidade acessíveis na conta com as tags correspondentes. Isso pode ser ainda mais restrito especificando o ID da conta do proprietário.

Para obter mais exemplos, consulte a [documentação do Karpenter](https://karpenter.sh/docs/concepts/nodeclasses/#speccapacityreservationselectorterms).

------
#### [ EKS Auto Mode ]

Crie um `NodeClass` que faça referência à sua reserva de Bloco de Capacidade e, em seguida, crie um NodePool que o use.

Com o `consolidateAfter: Never` definido, o Karpenter não tentará substituir, mesclar ou encerrar nós para reduzir custos ou empacotar workloads com mais eficiência. Isso é recomendado para Blocos de Capacidade porque a capacidade já está pré-paga.

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: capacity-block-gpu
spec:
  capacityReservationSelectorTerms:
    - id: "cr-0123456789abcdef0"   # Your Capacity Block reservation ID
    # Alternative: select by tags
    # - tags:
    #     role: "production-inference"
    #   owner: "012345678901"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-capacity-block
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: capacity-block-gpu
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved"]
        - key: "eks.amazonaws.com/instance-family"
          operator: In
          values: ["p5", "p5e", "p5en", "p4d"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------
#### [ Self-managed Karpenter ]

Crie um `EC2NodeClass` que inclua seletores de AMIs, sub-redes e grupos de segurança, além de `capacityReservationSelectorTerms`, e crie um NodePool que o use.

Com o `consolidateAfter: Never` definido, o Karpenter não tentará substituir, mesclar ou encerrar nós para reduzir custos ou empacotar workloads com mais eficiência. Isso é recomendado para Blocos de Capacidade porque a capacidade já está pré-paga.

```
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: capacity-block-gpu
spec:
  amiSelectorTerms:
    - alias: al2023@latest
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  capacityReservationSelectorTerms:
    - id: "cr-0123456789abcdef0" # Your Capacity Block reservation ID
    # Alternative: select by tags
    # - tags:
    #     role: "production-inference"
    #   owner: "012345678901"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-capacity-block
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: capacity-block-gpu
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["p5", "p5e", "p5en", "p4d"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------

## Reservas de capacidade sob demanda (ODCRs)
<a name="eks-aiml-odcrs"></a>

Os ODCRs garantem capacidade em uma zona de disponibilidade (AZ) específica sem um compromisso de longo prazo. Você recebe o faturamento de acordo com as taxas padrão sob demanda, independentemente de a capacidade ser usada ou não. Os ODCRs são compatíveis com todas as famílias de GPUs da NVIDIA, incluindo instâncias da família G que não são compatíveis com os Blocos de Capacidade para ML. Os ODCRs são pré-pagos, então o Modo Automático do EKS e o Karpenter os modelam como gratuitos e os priorizam em relação aos sob demanda e aos spot.

Os ODCRs se comportam de forma diferente dos Blocos de Capacidade para ML ao término da reserva. Quando um ODCR expira ou é cancelado, a instância continua em execução como sob demanda padrão. Para mais detalhes, consulte [Comportamento na expiração da reserva](#eks-aiml-node-pools-expiration).

Para usar ODCRs com o Modo Automático do EKS ou o Karpenter, configure `capacityReservationSelectorTerms` com seus termos de reserva de capacidade em seu NodeClass. Um termo pode especificar um ID, um conjunto de tags ou critérios de correspondência de instância a serem selecionados. Ao especificar as tags, ele selecionará todas as reservas de capacidade acessíveis na conta com as tags correspondentes. Ao especificar os critérios de correspondência de instâncias, ele seleciona as reservas pelo comportamento correspondente: aberto (corresponde a todas as instâncias compatíveis) ou direcionado (corresponde apenas a instâncias explicitamente direcionadas). Isso pode ser ainda mais restrito especificando o ID da conta do proprietário.

Para obter mais exemplos, consulte a [documentação do Karpenter](https://karpenter.sh/docs/concepts/nodeclasses/#speccapacityreservationselectorterms).

------
#### [ EKS Auto Mode ]

Crie um `NodeClass` com `capacityReservationSelectorTerms` e um NodePool que priorize `reserved` com fallback `on-demand`. Fixe `topology.kubernetes.io/zone` na AZ do ODCR:

```
apiVersion: eks.amazonaws.com/v1
kind: NodeClass
metadata:
  name: odcr-gpu-production
spec:
  capacityReservationSelectorTerms:
    - id: "cr-0987654321fedcba0"
    # Alternative: select by tags
    # - tags:
    #     Purpose: "production-inference"
    #   owner: "012345678901"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-reserved-production
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: odcr-gpu-production
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved", "on-demand"]
        - key: "eks.amazonaws.com/instance-family"
          operator: In
          values: ["p5", "g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------
#### [ Self-managed Karpenter ]

Crie um `EC2NodeClass` com seletores de AMIs, sub-redes e grupos de segurança, além de `capacityReservationSelectorTerms`, e em seguida crie o NodePool:

```
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
  name: odcr-gpu-production
spec:
  amiSelectorTerms:
    - alias: al2023@latest
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: ml-cluster
  capacityReservationSelectorTerms:
    - id: "cr-0987654321fedcba0"
---
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-reserved-production
spec:
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: Never
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: odcr-gpu-production
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["reserved", "on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["p5", "g6e"]
        - key: "topology.kubernetes.io/zone"
          operator: In
          values: ["us-east-1a"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------

## Sob demanda
<a name="eks-aiml-on-demand"></a>

Sob demanda é o tipo de capacidade padrão e pode ser usado com provisionamento estático ou dinâmico no Modo Automático do EKS e no Karpenter. Você pode requisitar explicitamente instâncias sob demanda configurando `karpenter.sh/capacity-type: on-demand` no seu NodePool. O Modo Automático do EKS e o Karpenter selecionam a instância de menor preço que satisfaz as requisições de recursos do pod. Use instâncias sob demanda para desenvolvimento, prototipagem, escalabilidade de inferência imprevisível e qualquer workload que precise de disponibilidade imediata sem risco de interrupção.

------
#### [ EKS Auto Mode ]

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-ondemand
spec:
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "eks.amazonaws.com/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "eks.amazonaws.com/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------
#### [ Self-managed Karpenter ]

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-ondemand
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["on-demand"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "karpenter.k8s.aws/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
```

------

## Spot
<a name="eks-aiml-spot"></a>

As instâncias spot oferecem até 90% de economia em relação às sob demanda usando a capacidade extra do EC2. A AWS pode recuperar instâncias spot com um aviso de interrupção de dois minutos. Maximize a disponibilidade listando várias famílias de instâncias no NodePool. Combine workloads spot com um `PodDisruptionBudget` e ponto de verificação para armazenamento durável (Amazon S3 ou Amazon EFS) em intervalos regulares para que os pods possam salvar o estado durante a janela de drenagem.

As instâncias spot são uma boa opção para workloads de treinamento e inferência tolerantes a falhas e reiniciáveis, em que interrupções ocasionais são aceitáveis em troca de uma economia significativa de custos.

Candidatos comuns incluem:
+  **Ajuste e varredura de hiperparâmetros**: vários testes curtos e paralelos que podem ser reiniciados se interrompidos.
+  **Treinamento distribuído com ponto de verificação**: tarefas de longa duração que periodicamente salvam o estado no S3 ou FSx e podem ser retomadas a partir do último ponto de verificação após a perda do nó.
+  **Inferência em lote e offline**: tarefas de pontuação em grande escala em relação a conjuntos de dados em que a latência de ponta a ponta é medida em horas, não em segundos.
+  **Pipelines de pré-processamento de dados e engenharia de atributos**: transformações paralelas em grandes conjuntos de dados.
+  **Benchmarking e avaliação de modelos**: tarefas reexecutáveis que produzem resultados idempotentes.
+  **Desenvolvimento, prototipagem e cadernos**: experimentação interativa em que os usuários podem tolerar reinicializações ocasionais.

Evite instâncias spot para inferência em tempo real sensível à latência, endpoints de produção sujeitos a SLA e workloads que não salvam pontos de verificação ou não toleram reinicializações.

Você pode requisitar explicitamente instâncias spot configurando `karpenter.sh/capacity-type: spot` em seu NodePool.

------
#### [ EKS Auto Mode ]

O Modo Automático do EKS lida com as interrupções de instâncias spot de forma nativa. Nenhuma fila SQS ou Node Termination Handler é necessário.

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-spot
spec:
  disruption:
    budgets:
      - nodes: 10%
    consolidationPolicy: WhenEmpty
    consolidateAfter: 1h
  template:
    spec:
      nodeClassRef:
        group: eks.amazonaws.com
        kind: NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["spot"]
        - key: "eks.amazonaws.com/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "eks.amazonaws.com/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    resources:
      nvidia.com/gpu: "64"
```

------
#### [ Self-managed Karpenter ]

O Karpenter autogerenciado exige que você habilite o tratamento nativo de interrupções no controlador do Karpenter (não no NodePool) configurando uma fila de interrupção: uma fila SQS que recebe eventos de interrupção de instâncias spot do EC2 e [Recomendação de rebalanceamento](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/rebalance-recommendations.html). Você configura isso uma vez no momento da instalação.

Se você instalar o Karpenter diretamente com o Helm, defina `settings.interruptionQueue` no seu `values.yaml`:

```
# karpenter values.yaml (Helm)
settings:
  clusterName: my-cluster
  interruptionQueue: my-queue   # Name of the SQS queue receiving Spot events
```

Se você inicializar o Karpenter com `eksctl`, defina `withSpotInterruptionQueue: true` no seu arquivo de configuração do cluster. O `eksctl` cria a fila SQS e as regras do EventBridge e configura o controlador do Karpenter para usá-las.

```
# eksctl ClusterConfig
karpenter:
  version: "${KARPENTER_VERSION}"
  withSpotInterruptionQueue: true
```

Depois que o controlador estiver configurado para usar sua fila, nenhuma configuração extra será necessária em recursos individuais do NodePool. O tratamento de interrupções se aplica a todo o cluster.

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-spot
spec:
  disruption:
    budgets:
      - nodes: 10%
    consolidationPolicy: WhenEmpty
    consolidateAfter: 1h
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: "karpenter.sh/capacity-type"
          operator: In
          values: ["spot"]
        - key: "karpenter.k8s.aws/instance-family"
          operator: In
          values: ["g6", "g6e", "g7e"]
        - key: "karpenter.k8s.aws/instance-gpu-manufacturer"
          operator: In
          values: ["nvidia"]
      taints:
        - key: nvidia.com/gpu
          value: "true"
          effect: NoSchedule
  limits:
    resources:
      nvidia.com/gpu: "64"
```

------