Kubernetes: introdução
Esta aula apresenta o Kubernetes, uma plataforma de orquestração de contêineres, explicando sua arquitetura, principais conceitos e quando utilizá-lo. Inclui exemplos práticos, exercícios com respostas e referências para aprofundamento.
O Kubernetes, frequentemente abreviado como K8s, é uma plataforma de orquestração de contêineres de código aberto que automatiza a implantação, o dimensionamento e a operação de aplicações em contêineres. Ele foi originalmente desenvolvido pelo Google e agora é mantido pela Cloud Native Computing Foundation (CNCF). Nesta aula, vamos explorar o que é o Kubernetes, sua arquitetura, os conceitos centrais e quando faz sentido adotá-lo.
Se você já trabalha com contêineres (como Docker), sabe que gerenciar vários contêineres manualmente pode se tornar complexo. O Kubernetes resolve isso fornecendo uma camada de abstração que gerencia clusters de máquinas, distribuindo aplicações de forma resiliente e escalável. Vamos mergulhar nos detalhes.
O que é
Kubernetes é um sistema de orquestração de contêineres que permite gerenciar aplicações em contêineres em um cluster de máquinas. Ele cuida de tarefas como escalonamento automático, balanceamento de carga, auto-recuperação (reiniciando contêineres que falham), e atualizações contínuas sem tempo de inatividade. Em resumo, ele abstrai a infraestrutura subjacente e oferece uma API declarativa para descrever o estado desejado do sistema.
O nome Kubernetes vem do grego e significa 'timoneiro' ou 'piloto', refletindo seu papel de guiar as aplicações. Ele é frequentemente chamado de 'k8s' (substituindo as oito letras entre 'k' e 's').
Exemplo de comando básico para verificar a versão do cliente:
kubectl version --clientArquitetura (control plane, nodes)
Um cluster Kubernetes é composto por dois tipos de componentes: o plano de controle (control plane) e os nós (nodes) de trabalho. O control plane é o 'cérebro' do cluster, responsável por tomar decisões globais (como agendar novos pods) e responder a eventos do cluster. Ele inclui componentes como o kube-apiserver (a porta de entrada para todas as chamadas de API), o etcd (um banco de dados chave-valor que armazena todo o estado do cluster), o kube-scheduler (que decide em qual nó um pod deve ser executado) e o kube-controller-manager (que executa controladores que garantem o estado desejado).
Os nós de trabalho são as máquinas (físicas ou virtuais) onde as aplicações realmente rodam. Cada nó contém o kubelet (agente que se comunica com o control plane), o kube-proxy (responsável pelo balanceamento de rede) e o runtime de contêineres (como Docker ou containerd).
Quando você executa um comando kubectl, ele envia uma requisição ao kube-apiserver, que autentica e valida, depois persiste o estado no etcd e agenda os pods nos nós apropriados. Os kubelets nos nós garantem que os contêineres estejam rodando conforme o esperado.
Exemplo de comando para listar os nós do cluster:
kubectl get nodesQuando (não) usar
O Kubernetes é extremamente poderoso, mas não é uma bala de prata. Ele é ideal quando você tem aplicações em contêineres que precisam de alta disponibilidade, escalabilidade automática e deploy contínuo. É particularmente útil em arquiteturas de microsserviços, onde muitos serviços precisam ser gerenciados de forma coordenada. Empresas como Google, Netflix e Spotify usam Kubernetes em produção.
Por outro lado, não use Kubernetes se você tem apenas um ou poucos contêineres e não prevê crescimento significativo. A complexidade de operar um cluster (mesmo em serviços gerenciados como EKS, AKS ou GKE) pode ser maior que o benefício. Para projetos simples, ferramentas como Docker Compose são suficientes. Além disso, se sua equipe não tem experiência em infraestrutura ou operações, a curva de aprendizado pode ser íngreme.
Avalie também o custo: clusters gerenciados têm custos fixos além do uso de máquinas. Para cargas de trabalho muito estáveis e previsíveis, talvez uma VM tradicional seja mais simples e barata.
Conceitos centrais
Para trabalhar com Kubernetes, é essencial entender alguns conceitos-chave. Vamos listar os principais:
- Pod: a menor unidade implantável no Kubernetes. Um pod pode conter um ou mais contêineres que compartilham rede e armazenamento.
- Deployment: controla a criação e atualização de pods. Ele garante que o número desejado de réplicas esteja rodando e oferece atualizações contínuas (rolling updates).
- Service: uma abstração que expõe um conjunto de pods como um único endpoint de rede, fornecendo balanceamento de carga e descoberta de serviço.
- ConfigMap e Secret: usados para separar configuração e dados sensíveis do código da aplicação.
- Namespace: permite dividir o cluster em ambientes virtuais, útil para separar equipes ou projetos.
- Ingress: gerencia o acesso externo aos serviços, geralmente via HTTP/HTTPS.
- PersistentVolume (PV) e PersistentVolumeClaim (PVC): abstraem o armazenamento persistente para pods.
Exemplo de um arquivo YAML para criar um Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:latest
ports:
- containerPort: 80Boas práticas
Ao trabalhar com Kubernetes, adote boas práticas desde o início: use namespaces para organizar ambientes, defina limites de recursos (requests e limits) para cada contêiner, utilize liveness e readiness probes para garantir a saúde das aplicações, e versionie seus manifests em Git. Além disso, prefira usar serviços gerenciados (como EKS, AKS ou GKE) para reduzir a complexidade operacional, a menos que tenha requisitos específicos.
Exercícios
- Explique a diferença entre um pod e um deployment no Kubernetes.
- Qual é o papel do kube-apiserver e por que ele é central no cluster?
- Cite três situações em que você NÃO deveria usar Kubernetes.
- Crie um arquivo YAML para um Deployment simples de um contêiner Nginx com 2 réplicas.
- O que é um Service e por que ele é necessário para expor pods?
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80