Kubernetes
O Kubernetes (K8s) executa contentores num cluster, mantém em bom estado o número declarado de réplicas e agenda tarefas de treino e inferência em GPU.
Kubernetes, muitas vezes abreviado para K8s, é um sistema de código aberto que executa aplicações contentorizadas num cluster de máquinas. Os utilizadores declaram o estado pretendido de uma carga de trabalho, como a imagem de contentor a executar, quantas cópias manter e quanta capacidade de CPU, memória e GPU cada cópia necessita; o Kubernetes inicia, reinicia, move e escala continuamente os contentores para corresponder a esse estado. A Google anunciou o projeto em junho de 2014, com base no seu gestor interno de clusters Borg, e, com a versão 1.0 em julho de 2015, disponibilizou-o como projeto-semente da recém-formada Cloud Native Computing Foundation. O nome significa «timoneiro» em grego, e K8s substitui as oito letras entre K e s. Nas operações de aprendizagem automática (MLOps), o Kubernetes é a camada comum que executa tarefas de treino distribuído, inferência em lote e disponibilização de modelos em hardware partilhado.
Arquitetura e ciclo de controlo#
Um cluster tem um plano de controlo e nós de trabalho. O plano de controlo contém o servidor da API, com o qual todos os clientes comunicam, o armazenamento etcd do estado do cluster, o escalonador que atribui novos pods aos nós e controladores que monitorizam cada tipo de objeto. Cada nó de trabalho, seja um servidor local ou uma máquina virtual na nuvem, executa um agente kubelet e um ambiente de execução de contentores, como containerd ou CRI-O. A menor unidade que o Kubernetes escalona é um pod: um ou mais contentores que partilham um endereço de rede e volumes de armazenamento.
As cargas de trabalho são declaradas como objetos, normalmente escritos em YAML e aplicados com kubectl. Um Deployment mantém em execução um número definido de pods idênticos e substitui-os gradualmente quando a imagem muda; um Service atribui-lhes um endereço estável comum e distribui os pedidos entre eles; e um Job executa pods até à conclusão de uma tarefa. Os controladores comparam o estado declarado com o que está efetivamente em execução e agem perante qualquer diferença:
O mesmo ciclo torna o Kubernetes autorrecuperável. Quando um nó falha, os respetivos pods deixam de estar em execução e o controlador cria substitutos em nós saudáveis. Um pod que fica no estado Pending por falta de capacidade também serve de sinal para os escalonadores automáticos do cluster adicionarem nós.
Kubernetes para aprendizagem automática#
As GPUs chegam aos pods através de plugins de dispositivos, que as anunciam como um recurso contabilizável, como nvidia.com/gpu, e através da Dynamic Resource Allocation, estável desde o Kubernetes 1.34, que permite a um pod solicitar dispositivos segundo atributos como o modelo ou a memória da GPU. O GPU Operator da NVIDIA instala controladores e plugins nos nós com GPU e pode dividir uma GPU em segmentos Multi-Instance GPU ou partilhar a GPU por vários pods ao longo do tempo. Em 2021, a OpenAI informou que tinha dimensionado clusters individuais de Kubernetes para 7.500 nós para treinar modelos como o GPT-3 e o CLIP.
Os projetos de código aberto adicionam camadas específicas de aprendizagem automática:
- Kubeflow: Executa treino distribuído em PyTorch, pipelines de aprendizagem automática e notebooks num cluster.
- Kueue: Coloca em fila tarefas em lote e de treino, e aplica quotas de equipa para manter ocupadas as GPUs dispendiosas sem deixar que uma equipa fique com todas.
- KServe: Disponibiliza modelos através de endpoints com escalonamento automático, incluindo redução a zero para modelos inativos.
- Horizontal Pod Autoscaler: Adiciona ou remove réplicas de inferência com base na utilização da CPU ou em métricas personalizadas, como o tamanho da fila, mantendo a latência estável à medida que o tráfego muda.
Um Job é a forma mais simples de executar uma tarefa pontual de GPU, como inferência em lote. A imagem oficial do Docker da Ultralytics já contém o comando yolo e os pesos do YOLO26 nano, então esse Job só precisa definir um comando e solicitar uma GPU:
apiVersion: batch/v1
kind: Job
metadata:
name: yolo26-predict
spec:
backoffLimit: 2 # retry a failed pod at most twice
template:
spec:
restartPolicy: Never
containers:
- name: yolo
image: ultralytics/ultralytics:latest
command: ["yolo", "predict", "model=yolo26n.pt", "source=https://ultralytics.com/images/bus.jpg"]
resources:
limits:
nvidia.com/gpu: 1 # schedule only onto a node with a free GPUkubectl apply -f job.yaml submete a tarefa, o escalonador coloca o pod num nó com uma GPU livre e kubectl logs job/yolo26-predict apresenta os resultados da deteção de objetos do modo de previsão. Um Job de treino segue o mesmo padrão e adiciona um volume persistente para os pontos de controlo, além de um volume em memória em /dev/shm para os trabalhadores do carregador de dados do PyTorch.
Kubernetes vs. Docker e computação sem servidor#
- Docker: Cria imagens e executa contentores numa única máquina. O Kubernetes distribui contentores por várias máquinas e, desde a versão 1.24, executa imagens criadas com Docker através do containerd ou do CRI-O, em vez do Docker Engine.
- Computação sem servidor: Serviços como o Google Cloud Run e o AWS Lambda ocultam completamente o cluster e cobram por pedido; o Knative traz o mesmo modelo de redução a zero aos clusters Kubernetes.
- Kubernetes gerido: O Google Kubernetes Engine (GKE), o Amazon Elastic Kubernetes Service (EKS) e o Azure Kubernetes Service (AKS) executam o plano de controlo para os clientes, e o GKE Autopilot também gere os nós de trabalho.










