Cluster upgrades: estratégias para atualizar o Kubernetes sem downtime

1. Fundamentos da Atualização de Clusters Kubernetes

1.1. Ciclo de vida das versões do Kubernetes

O Kubernetes segue um ciclo de lançamento trimestral, com cada versão recebendo patches de segurança por aproximadamente 12 meses. Compreender o ciclo de vida é essencial para planejar upgrades sem downtime. O canal de atualização stable recebe versões testadas, enquanto fast e experimental oferecem acesso antecipado a funcionalidades.

1.2. Princípios de alta disponibilidade

Para upgrades sem downtime, o cluster deve estar configurado com múltiplos nós de control plane (3 ou 5) e workers suficientes para absorver a carga durante a migração. O princípio fundamental é nunca degradar a capacidade total do cluster abaixo do mínimo necessário para operar as workloads.

1.3. Estratégias de rollout

As principais estratégias incluem:
- Rolling update: atualiza nós um a um, mantendo a disponibilidade
- Blue/green: mantém dois ambientes completos e alterna o tráfego
- Canary: atualiza um subconjunto de nós para validar estabilidade

2. Preparação do Ambiente para Upgrade Seguro

2.1. Backup e snapshot do etcd

Antes de qualquer upgrade, realize backup do etcd:

# Backup do etcd
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

# Verificar integridade
ETCDCTL_API=3 etcdctl --write-out=table snapshot status /backup/etcd-snapshot-$(date +%Y%m%d).db

2.2. Verificação de compatibilidade

Valide APIs e Custom Resources:

# Verificar APIs obsoletas
kubectl get apiservice

# Listar CRDs instalados
kubectl get crd

# Verificar versões de API usadas nos manifests
kubectl api-resources --verbs=list --namespaced -o name | xargs -n1 -I{} sh -c "kubectl get {} --all-namespaces -o yaml | grep -E 'apiVersion:'"

2.3. Health-check do cluster

# Verificar status dos nós
kubectl get nodes -o wide

# Verificar pods com problemas
kubectl get pods --all-namespaces --field-selector status.phase!=Running

# Métricas de estabilidade
kubectl top nodes
kubectl top pods --all-namespaces

3. Estratégia Rolling Update para Nós do Cluster

3.1. Drenagem e cordon de nós

# Cordon do nó (impede novos pods)
kubectl cordon node-worker-1

# Drenagem gradual (migra pods)
kubectl drain node-worker-1 --ignore-daemonsets --delete-emptydir-data

# Verificar status após drenagem
kubectl get nodes node-worker-1 -o jsonpath='{.spec.unschedulable}'

3.2. Atualização sequencial

Para control plane (3 nós):

# Atualizar primeiro nó do control plane
kubeadm upgrade plan v1.28.0
kubeadm upgrade apply v1.28.0 --etcd-upgrade=false

# Para workers
kubeadm upgrade node config --kubelet-version v1.28.0
systemctl restart kubelet

3.3. Monitoramento em tempo real

# Monitorar eventos
kubectl get events --watch --all-namespaces

# Logs do kubelet
journalctl -u kubelet -f

# Métricas de pods migrando
kubectl get pods --all-namespaces -o wide --watch

4. Uso de Ferramentas Gerenciadas e Automatizadas

4.1. Upgrade com kubeadm

# Verificar plano de upgrade
kubeadm upgrade plan

# Aplicar upgrade no control plane
kubeadm upgrade apply v1.28.0

# Atualizar kubelet e kubectl
apt-get update && apt-get install -y kubelet=1.28.0-00 kubectl=1.28.0-00
systemctl daemon-reload && systemctl restart kubelet

# Validar pós-upgrade
kubectl get nodes
kubectl version --short

4.2. Cluster API com GitOps

# Exemplo de manifest para upgrade declarativo
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
  name: production-cluster
spec:
  version: v1.28.0
  infrastructureRef:
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    kind: AWSCluster
    name: production-cluster

4.3. Managed Kubernetes

Serviços gerenciados oferecem upgrades automatizados:

  • EKS: eksctl upgrade cluster --name production --version 1.28
  • AKS: az aks upgrade --resource-group rg-prod --name aks-prod --kubernetes-version 1.28.0
  • GKE: gcloud container clusters upgrade production --cluster-version 1.28

5. Mitigação de Riscos e Rollback

5.1. Identificação de sinais de falha

# Detectar crash loops
kubectl get pods --all-namespaces | grep CrashLoopBackOff

# Verificar falhas de API
kubectl get apiservice | grep False

# Degradação de nós
kubectl describe node node-worker-1 | grep -A5 Conditions

5.2. Procedimentos de rollback

# Restaurar etcd
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot-20240101.db \
  --data-dir=/var/lib/etcd-restore

# Reverter versão do kubelet
apt-get install -y kubelet=1.27.0-00 kubectl=1.27.0-00
systemctl restart kubelet

5.3. Testes em staging

# Criar cluster canary
kind create cluster --name canary --config canary-config.yaml

# Aplicar upgrade e validar
kubeadm upgrade apply v1.28.0 --experimental-patches /patches
kubectl run test-pod --image=nginx --restart=Never

6. Atualização de Workloads e Add-ons

6.1. Atualização de componentes

# Atualizar Ingress Controller
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --set controller.image.tag=v1.9.0

# Atualizar CNI
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

6.2. Migração de APIs obsoletas

# Identificar APIs obsoletas
kubectl convert -f deployment.yaml --output-version apps/v1

# Adaptar manifests
kubectl convert -f old-deployment.yaml | kubectl apply -f -

6.3. Sincronização de certificados

# Revalidar certificados do cert-manager
kubectl get certificates --all-namespaces
kubectl describe certificate <nome> -n <namespace>

# Atualizar External DNS
kubectl rollout restart deployment/external-dns -n external-dns

7. Boas Práticas e Automação Contínua

7.1. Pipeline de upgrade automatizado

# Exemplo de pipeline CI/CD para upgrade
stages:
  - validate
  - backup
  - upgrade
  - test
  - promote

upgrade-job:
  stage: upgrade
  script:
    - kubectl cordon node-1
    - kubectl drain node-1
    - kubeadm upgrade apply v1.28.0
    - kubectl uncordon node-1

7.2. Políticas de versionamento

# Política de versões recomendada
# - Nunca pular mais de 2 versões minor
# - Upgrade de patch: semanal
# - Upgrade minor: trimestral com janela de 4h
# - Manter 3 versões anteriores como fallback

7.3. Documentação e Runbooks

# Estrutura de runbook recomendada
runbook/
├── pre-upgrade-checklist.md
├── upgrade-procedure.md
├── rollback-procedure.md
├── post-upgrade-validation.md
└── lessons-learned/
    └── upgrade-v1.27-to-v1.28.md

Referências