Construindo um Cluster Kubernetes

Avancado | 180 min leitura | 2025.12.02

O que voce vai aprender neste tutorial

  • Construir um cluster Kubernetes local com minikube
  • Conceitos basicos de Pod, Deployment e Service
  • Como escrever manifestos YAML
  • Deploy e exposicao de aplicacoes
  • Escalonamento e rolling updates
  • Uso de ConfigMap, Secret e Namespace
  • Melhores praticas para ambiente de producao

Pre-requisitos: Docker Desktop instalado. Instalacao de kubectl e minikube necessarios.


Historia e Contexto do Kubernetes

Por que o Kubernetes foi criado

Kubernetes (tambem conhecido como K8s) e uma plataforma de orquestracao de containers lancada como open source pelo Google em 2014. Sua origem remonta aos sistemas de gerenciamento de containers em larga escala “Borg” e “Omega” que o Google operou internamente por mais de 10 anos.

“Kubernetes is based on a decade and a half of experience at Google running production workloads at scale, combined with best-of-breed ideas and practices from the community.”

Documentacao Oficial do Kubernetes

Diz-se que o Google inicia bilhoes de containers toda semana, e o conhecimento obtido dessa experiencia operacional foi consolidado no Kubernetes.

Origem do nome Kubernetes

“Kubernetes” vem do grego e significa “timoneiro” ou “piloto”. O significado e pilotar o “navio” de containers, e o logo e baseado no timao de um navio. A abreviacao “K8s” vem do fato de haver 8 letras (ubernete) entre K e s.

Necessidade de Orquestracao de Containers

A tecnologia de containers (Docker) simplificou dramaticamente o empacotamento e distribuicao de aplicacoes. No entanto, novos desafios surgiram em ambientes de producao:

DesafioDescricao
EscalonamentoAjustar dinamicamente o numero de containers conforme o trafego
Recuperacao de falhasReinicio automatico quando containers falham
Balanceamento de cargaDistribuicao de trafego entre multiplos containers
Service DiscoveryGerenciamento de enderecos IP de containers que mudam dinamicamente
Rolling UpdatesAtualizacao de aplicacoes sem downtime
Gerenciamento de secretsDistribuicao segura de senhas e chaves de API

O Kubernetes resolve esses desafios com configuracao declarativa (definindo o estado desejado).

CNCF e Ecossistema Cloud Native

Em 2015, o Google doou o Kubernetes para a CNCF (Cloud Native Computing Foundation). A CNCF e uma organizacao sob a Linux Foundation que promove a adocao e padronizacao de tecnologias cloud native.

Atualmente, a CNCF inclui projetos importantes como:

  • Kubernetes - Orquestracao de containers
  • Prometheus - Monitoramento e alertas
  • Envoy - Proxy de servicos
  • Helm - Gerenciador de pacotes
  • Argo - Workflow GitOps

Referencia: CNCF Cloud Native Interactive Landscape


Visao Geral da Arquitetura Kubernetes

O cluster Kubernetes e composto por Control Plane (master) e Worker Nodes.

Componentes do Control Plane

flowchart TB
    subgraph ControlPlane["Control Plane"]
        API["API Server"]
        Sched["Scheduler"]
        CM["Controller Manager"]
        etcd["etcd<br/>(Armazenamento KV Distribuido)"]
    end
ComponenteFuncao
kube-apiserverPonto de entrada para todas as operacoes de API no cluster
etcdBanco de dados distribuido que armazena o estado do cluster
kube-schedulerDecide em qual no colocar os Pods
kube-controller-managerExecuta varios controladores (ReplicaSet, Node, etc.)

Componentes dos Worker Nodes

flowchart TB
    subgraph WorkerNode["Worker Node"]
        kubelet["kubelet"]
        kproxy["kube-proxy"]
        runtime["Container Runtime"]
        subgraph Pods["Pods"]
            P1["Pod"]
            P2["Pod"]
            P3["Pod"]
            P4["Pod"]
        end
    end
ComponenteFuncao
kubeletAgente que gerencia Pods no no
kube-proxyGerencia regras de rede e implementa funcionalidade de Service
Container RuntimeExecuta containers (containerd, CRI-O, etc.)

Step 1: Iniciando o minikube

minikube e uma ferramenta que permite construir facilmente um cluster Kubernetes em ambiente local. Ideal para aprendizado e desenvolvimento.

# Iniciar cluster minikube
# Opcao --driver especifica o driver (docker, virtualbox, hyperkit, etc.)
minikube start

# Iniciar com memoria e CPU especificados (para reproduzir ambiente proximo a producao)
minikube start --memory=4096 --cpus=2

# Verificar estado do cluster
minikube status

# Verificar conexao do kubectl
kubectl cluster-info

# Verificar informacoes dos nos
kubectl get nodes -o wide

Outras ferramentas locais: kind (Kubernetes in Docker), k3s (Kubernetes leve) tambem sao populares. Escolha conforme o uso.


Step 2: Conceitos Basicos do Kubernetes

Vamos entender os principais recursos do Kubernetes. Explicacoes detalhadas estao disponiveis na documentacao oficial de conceitos.

Relacionamento entre Recursos Principais

flowchart BT
    External["Trafego Externo"]
    Service["Service
(LB)"] External --> Service subgraph Deployment["Deployment
(Gerencia replicas, estrategia de atualizacao, rollback)"] subgraph ReplicaSet["ReplicaSet
(Mantem numero especificado de replicas de Pod)"] Pod1["Pod
(Container)"] Pod2["Pod
(Container)"] Pod3["Pod
(Container)"] Pod4["Pod
(Container)"] end end Service --> Pod1 Service --> Pod2 Service --> Pod3 Service --> Pod4

Detalhes de Cada Recurso

RecursoDescricaoCaso de Uso
PodUnidade minima de deploy. Contem um ou mais containersInstancia unica de aplicacao
ReplicaSetMantem numero especificado de replicas de PodGeralmente gerenciado automaticamente pelo Deployment
DeploymentGerenciamento de replicas e rolling updates de PodsAplicacoes stateless
StatefulSetGerenciamento ordenado de Pods e armazenamento persistenteBancos de dados, sistemas distribuidos
DaemonSetColoca um Pod em cada noColeta de logs, agentes de monitoramento
ServiceAbstrai acesso de rede aos PodsBalanceamento de carga, service discovery
IngressRoteamento HTTP/HTTPS e terminacao TLSExposicao externa, roteamento por caminho
ConfigMapArmazena dados de configuracaoVariaveis de ambiente, arquivos de configuracao
SecretArmazena dados confidenciaisSenhas, chaves de API, certificados
NamespaceIsolamento logico de recursosSeparacao de ambientes (dev/staging/prod)

Step 3: Fazendo Deploy do Primeiro Pod

Criacao Direta via Linha de Comando (para desenvolvimento/depuracao)

# Criar Pod nginx
kubectl run my-nginx --image=nginx:latest

# Verificar estado do Pod
# Aguardar STATUS ficar Running
kubectl get pods

# Monitorar estado em tempo real
kubectl get pods -w

# Verificar detalhes do Pod (eventos, uso de recursos, etc.)
kubectl describe pod my-nginx

# Verificar logs do Pod
kubectl logs my-nginx

# Deletar Pod
kubectl delete pod my-nginx

Dica: Pods criados com kubectl run nao sao recriados automaticamente quando deletados. Em producao, sempre use Deployment.

Depuracao dentro do Pod

# Iniciar shell dentro do Pod
kubectl exec -it my-nginx -- /bin/bash

# Executar comando especifico
kubectl exec my-nginx -- cat /etc/nginx/nginx.conf

# Verificar rede de dentro do Pod
kubectl exec my-nginx -- curl -s localhost

Step 4: Deploy com Manifesto YAML

Em producao, seguindo o principio de Infrastructure as Code, definimos recursos em arquivos YAML. Isso garante controle de versao, revisao e reprodutibilidade.

“Store the declarative configuration in source control. This allows you to roll back and roll forward configurations.”

Kubernetes Best Practices

Manifesto de Deployment

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
    # Use labels para organizar recursos
    environment: development
    version: v1.0.0
spec:
  replicas: 3  # Manter 3 replicas de Pod
  selector:
    matchLabels:
      app: my-app
  # Configuracao de estrategia de atualizacao
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Numero de Pods extras que podem ser criados durante atualizacao
      maxUnavailable: 0  # Numero de Pods que podem ficar indisponiveis durante atualizacao
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: nginx:1.24
        ports:
        - containerPort: 80
        # Limites de recursos (melhor pratica obrigatoria)
        resources:
          requests:  # Recursos reservados durante agendamento
            memory: "64Mi"
            cpu: "250m"    # 250 milicores = 0.25 CPU
          limits:    # Limites (OOMKilled ou throttling se exceder)
            memory: "128Mi"
            cpu: "500m"
        # Liveness Probe: Verifica se o Pod esta vivo
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        # Readiness Probe: Verifica se pode aceitar trafego
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 3

Aplicando o Deploy

# Aplicar manifesto
kubectl apply -f deployment.yaml

# Verificar estado do Deployment
kubectl get deployments

# Verificar ReplicaSet (criado automaticamente pelo Deployment)
kubectl get replicasets

# Verificar estado dos Pods (filtrar por label selector)
kubectl get pods -l app=my-app

# Exportar informacoes detalhadas em formato YAML
kubectl get deployment my-app -o yaml

Importancia dos Health Checks (Probes)

Os Probes do Kubernetes sao mecanismos para verificar a saude da aplicacao.

ProbePropositoAcao em caso de falha
livenessProbeVerifica se o Pod esta vivoReinicia o container
readinessProbeVerifica se pode aceitar requisicoesRemove dos endpoints do Service
startupProbeVerifica se a inicializacao foi concluidaDesabilita liveness/readiness ate conclusao

Atencao: Se usar verificacao de conexao com DB no livenessProbe, pode causar falha em cascata com reinicio infinito dos Pods quando o DB falhar.


Step 5: Expondo a Aplicacao com Service

Service fornece acesso de rede estavel aos Pods. Pods sao criados e deletados dinamicamente e seus IPs mudam, mas o Service fornece DNS e IP fixos.

Tipos de Service

TipoUsoEscopo de Acesso
ClusterIPPadrao. Apenas interno ao clusterComunicacao entre microservicos internos
NodePortExpoe externamente via porta do noAmbientes de desenvolvimento/teste
LoadBalancerProvisiona LB na nuvem automaticamenteExposicao externa em producao
ExternalNameAlias para servico externoConexao com DB externo

Manifesto de Service

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
  labels:
    app: my-app
spec:
  type: NodePort  # Para desenvolvimento. Use LoadBalancer em producao
  selector:
    app: my-app   # Encaminha trafego para Pods com este label
  ports:
  - name: http
    protocol: TCP
    port: 80         # Porta do Service
    targetPort: 80   # Porta do Pod
    nodePort: 30080  # Porta do no (30000-32767)

Aplicando e Verificando o Service

# Criar Service
kubectl apply -f service.yaml

# Verificar Service
kubectl get services

# Detalhes do Service (verificar IPs dos Pods nos Endpoints)
kubectl describe service my-app-service

# Verificar Endpoints diretamente
kubectl get endpoints my-app-service

# Obter URL de acesso no minikube
minikube service my-app-service --url

# Abrir no navegador
minikube service my-app-service

Exemplo de Service ClusterIP (para comunicacao interna)

apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  type: ClusterIP  # Padrao
  selector:
    app: backend
  ports:
  - port: 8080
    targetPort: 8080

Acessivel de dentro do cluster via backend-service.default.svc.cluster.local ou simplesmente backend-service.


Step 6: Escalonamento

Uma das funcionalidades poderosas do Kubernetes e o escalonamento flexivel.

Escalonamento Manual

# Alterar numero de replicas
kubectl scale deployment my-app --replicas=5

# Verificar aumento de Pods
kubectl get pods -l app=my-app

# Verificar estado do Deployment
kubectl get deployment my-app

Horizontal Pod Autoscaler (HPA)

HPA ajusta automaticamente o numero de Pods com base na utilizacao de CPU ou metricas customizadas.

# Configurar autoscaling baseado em CPU
# Scale out quando CPU exceder 50%
kubectl autoscale deployment my-app --min=2 --max=10 --cpu-percent=50

# Verificar estado do HPA
kubectl get hpa

# Verificar detalhes
kubectl describe hpa my-app

Manifesto YAML do HPA

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  # Controle fino do comportamento de escalonamento
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # Aguardar 5 minutos de estabilidade antes de scale down

Nota: Para usar HPA, o Metrics Server deve estar instalado no cluster. No minikube, habilite com minikube addons enable metrics-server.


Step 7: Rolling Updates

Os Rolling Updates do Kubernetes permitem atualizar aplicacoes sem downtime.

Executando Atualizacoes

# Atualizar imagem
kubectl set image deployment/my-app my-app=nginx:1.25

# Ou editar manifesto e aplicar
kubectl apply -f deployment.yaml

# Verificar estado do rollout em tempo real
kubectl rollout status deployment/my-app

# Verificar historico de rollout
kubectl rollout history deployment/my-app

# Verificar detalhes de revisao especifica
kubectl rollout history deployment/my-app --revision=2

Rollback

# Rollback para versao anterior
kubectl rollout undo deployment/my-app

# Rollback para revisao especifica
kubectl rollout undo deployment/my-app --to-revision=1

# Pausar rollout (para canary release, etc.)
kubectl rollout pause deployment/my-app

# Retomar rollout
kubectl rollout resume deployment/my-app

Estrategias de Atualizacao

O campo strategy do Deployment especifica a estrategia de atualizacao:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%        # Porcentagem de Pods extras permitidos durante atualizacao
      maxUnavailable: 25%  # Porcentagem de Pods que podem parar durante atualizacao
ConfiguracaoEfeito
maxSurge: 1, maxUnavailable: 0Prioridade seguranca (novo Pod inicia antes de parar o antigo)
maxSurge: 0, maxUnavailable: 1Economia de recursos (para Pod antigo primeiro)

Step 8: ConfigMap e Secret

Externalizando configuracao e informacoes confidenciais da aplicacao, voce pode alterar configuracoes sem reconstruir a imagem. Isso segue o principio The Twelve-Factor App de “armazenar configuracao em variaveis de ambiente”.

ConfigMap

Armazena dados de configuracao em formato chave-valor.

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  # Formato chave-valor
  APP_ENV: "production"
  LOG_LEVEL: "info"
  MAX_CONNECTIONS: "100"
  # Incorporar como arquivo
  nginx.conf: |
    server {
      listen 80;
      location / {
        root /usr/share/nginx/html;
      }
    }

Secret

Armazena dados confidenciais. Valores sao codificados em base64.

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  # Valores codificados em base64
  # echo -n "password123" | base64 → cGFzc3dvcmQxMjM=
  DB_PASSWORD: cGFzc3dvcmQxMjM=
  API_KEY: c2VjcmV0LWFwaS1rZXk=

Aviso de Seguranca: Por padrao, Secrets do Kubernetes sao apenas codificados em base64, nao criptografados. Para producao, considere:

Usando ConfigMap/Secret em Pods

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
      - name: my-app
        image: nginx:1.24
        # Injetar como variaveis de ambiente
        env:
        - name: APP_ENVIRONMENT
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: APP_ENV
        - name: DATABASE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: DB_PASSWORD
        # Injetar todas as chaves como variaveis de ambiente
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: app-secret
        # Montar como arquivo
        volumeMounts:
        - name: config-volume
          mountPath: /etc/nginx/conf.d
          readOnly: true
      volumes:
      - name: config-volume
        configMap:
          name: app-config
          items:
          - key: nginx.conf
            path: default.conf

Step 9: Isolamento de Recursos com Namespace

Use Namespace para isolar recursos logicamente.

Criando e Usando Namespaces

# Criar Namespace
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production

# Verificar Namespaces existentes
kubectl get namespaces

# Criar recurso em Namespace especifico
kubectl apply -f deployment.yaml -n development

# Verificar recursos especificando Namespace
kubectl get pods -n development

# Verificar recursos de todos os Namespaces
kubectl get pods --all-namespaces
kubectl get pods -A  # Forma abreviada

Alterando Namespace Padrao

# Verificar contexto atual
kubectl config current-context

# Alterar Namespace padrao
kubectl config set-context --current --namespace=development

# Verificar alteracao
kubectl config view --minify | grep namespace

ResourceQuota por Namespace

Voce pode limitar o uso de recursos por equipe ou ambiente.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: development-quota
  namespace: development
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "20"
    services: "10"

Comandos kubectl Uteis

Verificando Recursos

# Mostrar todos os recursos
kubectl get all

# Formato de saida amplo
kubectl get pods -o wide

# Saida em formato YAML/JSON
kubectl get deployment my-app -o yaml
kubectl get deployment my-app -o json

# Saida com colunas customizadas
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase

# Watch de recursos (atualizacao em tempo real)
kubectl get pods -w

Depuracao e Troubleshooting

# Executar comando dentro do Pod
kubectl exec -it pod-name -- /bin/sh

# Com multiplos containers, especificar container
kubectl exec -it pod-name -c container-name -- /bin/sh

# Port forward (acesso direto do local para o Pod)
kubectl port-forward pod/my-app-xxx 8080:80

# Port forward para Service
kubectl port-forward service/my-app-service 8080:80

# Verificar eventos do recurso
kubectl get events --sort-by='.lastTimestamp'

# Eventos de Pod especifico
kubectl describe pod my-app-xxx | grep -A 10 Events

Deletando Recursos

# Deletar via manifesto
kubectl delete -f deployment.yaml

# Deletar em lote por label
kubectl delete pods -l app=my-app

# Deletar Namespace (atencao: deleta todos os recursos dentro)
kubectl delete namespace development

# Deletar forcadamente (Pods travados, etc.)
kubectl delete pod my-app-xxx --force --grace-period=0

Melhores Praticas para Ambiente de Producao

1. Configurar Limites de Recursos

Defina requests e limits em todos os containers.

resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"

Por que e importante: Sem limites de recursos, um Pod pode consumir todos os recursos do no, afetando outros Pods.

2. Implementar Health Checks (Probes)

Sempre configure livenessProbe e readinessProbe.

3. Pod Disruption Budget (PDB)

Manter numero minimo de Pods mesmo durante manutencao.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-app-pdb
spec:
  minAvailable: 2  # Ou maxUnavailable: 1
  selector:
    matchLabels:
      app: my-app

4. Configuracao de Anti-Affinity

Distribua Pods em diferentes nos para melhorar disponibilidade.

spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: my-app
          topologyKey: kubernetes.io/hostname

5. NetworkPolicy

Restrinja trafego de rede dos Pods.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

6. Security Context

Configure privilegios minimos para containers.

spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 1000
  containers:
  - name: my-app
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL

Erros Comuns e Antipatterns

O que Evitar

AntipatternProblemaSolucao
Usar tag latestSem reprodutibilidade, atualizacoes inesperadasUse tags de versao explicitas
Sem limites de recursosEsgotamento de recursos, no downSempre configure requests/limits
Sem ProbesDeteccao tardia de falhasConfigure liveness/readinessProbe
Secrets hardcodedRisco de segurancaUse ConfigMap/Secret
Executar como rootRisco de segurancaConfigure runAsNonRoot: true
Replica unicaPonto unico de falhaManter minimo 2 replicas

Praticas Recomendadas

# Bom exemplo
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: my-app
        image: my-app:1.2.3  # Versao explicita
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
        securityContext:
          runAsNonRoot: true
          readOnlyRootFilesystem: true

Cleanup

# Deletar recursos
kubectl delete -f service.yaml
kubectl delete -f deployment.yaml
kubectl delete -f configmap.yaml
kubectl delete -f secret.yaml

# Ou deletar tudo de uma vez
kubectl delete -f .

# Deletar Namespace (deleta recursos internos tambem)
kubectl delete namespace development

# Parar minikube
minikube stop

# Deletar minikube completamente
minikube delete

# Deletar todos os profiles
minikube delete --all

Proximos Passos

Com base nos fundamentos aprendidos neste tutorial, recomendamos prosseguir para os seguintes topicos:

Topicos Avancados


Documentacao Oficial

Recursos de Aprendizado

Melhores Praticas

Ferramentas

  • Lens - IDE para Kubernetes
  • k9s - UI baseada em terminal para Kubernetes
  • kubectx/kubens - Ferramenta para troca de contexto/Namespace
  • stern - Visualizacao de logs multi-Pod

Certificacoes

← Voltar para a lista