Capítulo 38 — Kubernetes e Orquestração de Containers
Este capítulo aprofunda a operação do Kubernetes como plataforma de orquestração da Plataforma de Relacionamento Digital com o Cidadão. Detalha como workloads são empacotados em containers, declarados em manifests, distr…
38.1 Objetivo do Capítulo
Este capítulo aprofunda a operação do Kubernetes como plataforma de orquestração da Plataforma de Relacionamento Digital com o Cidadão. Detalha como workloads são empacotados em containers, declarados em manifests, distribuídos em clusters resilientes, escalados conforme demanda e observados em produção.
O capítulo complementa o Capítulo 37 (Infraestrutura e Computação em Nuvem) com foco específico em: arquitetura de cluster, tipos de workloads, namespaces e isolamento, helm charts, estratégias de deploy, autoscaling, gestão de configuração e secrets, troubleshooting operacional.
38.2 Arquitetura do Cluster Kubernetes
38.2.1 Control Plane
O control plane gerencia o estado do cluster e responde a requisições de criação/modificação de recursos:
┌─────────────────────────────────────────────────────────┐
│ Control Plane │
│ │
│ kube-apiserver │
│ ├─ API REST exposta em HTTPS │
│ ├─ Valida e processa requests │
│ └─ Persiste estado em etcd │
│ │
│ etcd │
│ ├─ Banco chave-valor distribuído │
│ ├─ Source of truth do cluster │
│ └─ Réplicas para HA (3 ou 5 nós) │
│ │
│ kube-scheduler │
│ ├─ Decide em qual nó pods executam │
│ ├─ Considera recursos, afinidade, taints │
│ └─ Recalcula continuamente │
│ │
│ kube-controller-manager │
│ ├─ ReplicaSet controller │
│ ├─ Deployment controller │
│ ├─ Service controller │
│ ├─ Node controller │
│ ├─ Namespace controller │
│ └─ ... (mais de 30 controllers) │
│ │
│ cloud-controller-manager (opcional) │
│ ├─ Integração com cloud provider │
│ └─ Provisiona LoadBalancer, PersistentDisk │
└─────────────────────────────────────────────────────────┘
38.2.2 Worker Nodes
Worker nodes executam os workloads:
┌─────────────────────────────────────────────────────────┐
│ Worker Node │
│ │
│ kubelet │
│ ├─ Agente que reporta ao control plane │
│ ├─ Inicia pods via container runtime │
│ └─ Health checks (liveness, readiness) │
│ │
│ kube-proxy │
│ ├─ Mantém regras iptables/IPVS │
│ └─ Habilita comunicação entre pods e Services │
│ │
│ container runtime (containerd ou CRI-O) │
│ ├─ Executa containers │
│ └─ Puxa imagens de registries │
│ │
│ Pods │
│ ├─ Menor unidade implantável │
│ ├─ 1+ containers que compartilham network/storage │
│ └─ Scheduling atômico │
└─────────────────────────────────────────────────────────┘
38.2.3 Distribuição Geográfica
Os componentes do control plane são distribuídos entre zonas de disponibilidade:
Zone A Zone B Zone C
kube-apiserver kube-apiserver kube-apiserver
etcd (a) etcd (b) etcd (c)
scheduler scheduler scheduler
Workers distribuídos:
node-pool-app-1 (a) node-pool-app-1 (b) node-pool-app-1 (c)
node-pool-data-1 (a) node-pool-data-1 (b) node-pool-data-1 (c)
Falha de uma zona não derruba o cluster. Kubernetes continua atendendo com capacidade reduzida.
38.3 Workloads
38.3.1 Tipos de Workloads
A plataforma utiliza diferentes tipos de workloads conforme natureza do serviço:
| Tipo | Caso de Uso | Kubernetes Resource |
|---|---|---|
| Serviço stateless HTTP | API backend | Deployment |
| Serviço stateful | Banco de dados | StatefulSet + PVC |
| Job único | Migration, cleanup | Job |
| Job recorrente | Limpeza de logs, backup | CronJob |
| Serviço de mensagens | Consumer RabbitMQ | Deployment |
| Daemon | Log forwarder, metrics exporter | DaemonSet |
38.3.2 Pod Specification
Pod é a menor unidade implantável. Especificação típica:
apiVersion: v1
kind: Pod
metadata:
name: api-solicitacoes-7d4b
namespace: tenant-org-a
labels:
app: api-solicitacoes
tier: backend
tenant: org-a
spec:
containers:
- name: api
image: registry.example.com/api-solicitacoes:1.2.3
ports:
- containerPort: 8080
name: http
env:
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-credentials
key: host
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 2Gi
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
38.4 Deployments
38.4.1 Deployment como Padrão para Stateless
Deployment gerencia réplicas de pods e rolling updates:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-solicitacoes
namespace: tenant-org-a
spec:
replicas: 3
selector:
matchLabels:
app: api-solicitacoes
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: api-solicitacoes
tier: backend
tenant: org-a
spec:
containers:
- name: api
image: registry.example.com/api-solicitacoes:1.2.3
# ... (como no pod spec)
38.4.2 Rolling Update com Zero Downtime
Estado inicial: 3 réplicas com versão v1
Estado desejado: 3 réplicas com versão v2
Kubernetes:
1. Cria 1 réplica v2 (maxSurge: 1)
Estado: 3 v1 + 1 v2
2. Termina 1 réplica v1 (maxUnavailable: 0)
Estado: 2 v1 + 1 v2 + 1 v2 = 2 v1 + 2 v2
3. Cria mais 1 réplica v2
Estado: 2 v1 + 2 v2 + 1 v2 = 2 v1 + 3 v2
4. Termina mais 1 réplica v1
Estado: 1 v1 + 3 v2
... continua até 0 v1 + 3 v2
Em cada momento, há capacidade total (3 réplicas) atendendo.
38.4.3 Health Checks
Liveness probe detecta se pod precisa ser reiniciado:
Liveness probe falha
│
└─ Kubernetes mata o pod
│
└─ ReplicaSet cria novo pod
Readiness probe detecta se pod está pronto para receber tráfego:
Readiness probe falha
│
└─ Pod removido de Service endpoints
│
└─ Tráfego não chega ao pod
Startup probe aguarda inicialização longa sem disparar liveness:
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
38.4.4 Estratégia de Deploy
| Estratégia | Caso de Uso | Risco |
|---|---|---|
| Rolling Update | Padrão para APIs | Versões diferentes coexistem brevemente |
| Recreate | Aplicações com estado compartilhado | Downtime durante recreate |
| Blue/Green | Zero downtime crítico | Dobra capacidade durante deploy |
| Canary | Release progressiva com validação | Complexidade de roteamento |
A plataforma usa Rolling Update como padrão. Blue/Green e Canary são reservados para serviços críticos ou releases de risco.
38.5 Services e Networking
38.5.1 Service Types
Kubernetes oferece diferentes tipos de Service:
ClusterIP (padrão):
Service com IP interno do cluster
│
└─ Roteamento para pods via selector
│
└─ kube-proxy atualiza iptables/IPVS
Acesso apenas dentro do cluster.
NodePort:
Service exposto em porta fixa em cada node
│
└─ ClusterIP + porta em cada node (30000-32767)
│
└─ Acessível via <node-ip>:<node-port>
Útil para debug ou em redes privadas.
LoadBalancer (cloud provider):
Service provisiona Load Balancer externo
│
└─ Cloud provider cria LB
│
└─ Tráfego roteado para nodes/pods
Padrão para serviços externos em cloud.
Ingress:
Service exposto via Ingress Controller
│
└─ Roteamento baseado em host/path
│
└─ TLS termination, rate limiting, etc.
Recomendado para HTTP/HTTPS externos.
38.5.2 Ingress Controller
Ingress é o ponto de entrada HTTP/HTTPS para a plataforma:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: portal-cidadao
namespace: tenant-org-a
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- portal.org-a.example.com
secretName: portal-tls
rules:
- host: portal.org-a.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-portal
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-gateway
port:
number: 8080
Ingress Controller (NGINX, HAProxy, Traefik) implementa TLS termination, rate limiting, e rewrites.
38.5.3 Service Mesh (Istio / Linkerd)
Para comunicação interna com mTLS e observabilidade:
Service A → Service B
│
└─ Sidecar proxy intercepta
│
├─ mTLS automático
├─ Tracing distribuído
├─ Retry policies
└─ Circuit breaking
Service mesh adiciona latência de ~1-3ms mas oferece segurança e observabilidade significativas.
A plataforma usa service mesh para serviços críticos (request service, citizen service). Para serviços de menor criticidade, mTLS via Network Policies é suficiente.
38.6 Namespaces e Isolamento Multi-Tenant
38.6.1 Namespace por Tenant
Cada tenant tem namespace dedicado:
Namespaces:
- tenant-org-a
- tenant-org-b
- tenant-org-c
- platform-system (recursos compartilhados)
- monitoring (Prometheus, Grafana)
- logging (Elasticsearch, Kibana)
- ingress-nginx
- cert-manager
38.6.2 Resource Quota
Resource Quota limita consumo agregado do namespace:
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-org-a-quota
namespace: tenant-org-a
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Gi
persistentvolumeclaims: "10"
pods: "100"
services: "50"
secrets: "100"
configmaps: "100"
loadbalancers: "5" # limite de LBs externos
38.6.3 LimitRange
LimitRange aplica defaults e limites por pod/container:
apiVersion: v1
kind: LimitRange
metadata:
name: tenant-org-a-limits
namespace: tenant-org-a
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 1Gi
defaultRequest:
cpu: 100m
memory: 256Mi
max:
cpu: 2
memory: 4Gi
min:
cpu: 50m
memory: 64Mi
38.6.4 Network Policies
Network Policies controlam comunicação entre pods:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tenant-org-a-isolation
namespace: tenant-org-a
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
tenant: org-a
- namespaceSelector:
matchLabels:
name: ingress-nginx
egress:
- to:
- namespaceSelector:
matchLabels:
tenant: org-a
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
Pods do tenant-org-a só se comunicam com:
- outros pods do mesmo tenant;
- ingress controller;
- kube-dns (para resolução DNS).
Cross-tenant é bloqueado por padrão.
38.7 ConfigMaps e Secrets
38.7.1 ConfigMap para Configuração Não-Sensível
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: tenant-org-a
data:
LOG_LEVEL: "INFO"
SERVICE_NAME: "api-solicitacoes"
CACHE_TTL_SECONDS: "300"
FEATURE_FLAG_NEW_UI: "true"
Aplicação consome via variável de ambiente ou volume mount:
spec:
containers:
- name: api
envFrom:
- configMapRef:
name: app-config
38.7.2 Secret para Credenciais
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: tenant-org-a
type: Opaque
stringData:
username: app_user
password: super-secret-password-123
Secrets são criptografados em repouso no etcd (EncryptionConfiguration) e em trânsito (HTTPS na API).
38.7.3 External Secrets Operator
External Secrets sincroniza secrets de vault externo (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) para Kubernetes:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
namespace: tenant-org-a
spec:
refreshInterval: 5m
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: db-credentials
data:
- secretKey: username
remoteRef:
key: tenant-org-a/db
property: username
- secretKey: password
remoteRef:
key: tenant-org-a/db
property: password
Rotação de credencial no vault é refletida em Kubernetes automaticamente.
38.8 Helm como Package Manager
38.8.1 Helm Charts para Templates
Helm permite empacotar e versionar configurações Kubernetes:
chart: api-solicitacoes
├── Chart.yaml (metadata da chart)
├── values.yaml (configuração padrão)
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ ├── hpa.yaml
│ └── _helpers.tpl
├── values-dev.yaml (override para dev)
├── values-staging.yaml (override para staging)
└── values-prod.yaml (override para prod)
38.8.2 Estrutura de Chart
# Chart.yaml
apiVersion: v2
name: api-solicitacoes
description: API de solicitações
type: application
version: 1.2.3
appVersion: "1.2.3"
# values.yaml
replicaCount: 3
image:
repository: registry.example.com/api-solicitacoes
tag: "1.2.3"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
hosts:
- host: api.org-a.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: api-tls
hosts:
- api.org-a.example.com
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 2Gi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 30
targetCPUUtilizationPercentage: 70
38.8.3 Template Rendering
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "api-solicitacoes.fullname" . }}
namespace: {{ .Values.namespace }}
labels:
{{- include "api-solicitacoes.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "api-solicitacoes.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "api-solicitacoes.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
38.8.4 Instalação por Tenant
helm install api-solicitacoes ./chart \
--namespace tenant-org-a \
--values values-prod.yaml \
--set image.tag=1.2.3
Helm mantém histórico de releases:
helm history api-solicitacoes -n tenant-org-a
REVISION UPDATED STATUS CHART DESCRIPTION
1 2026-07-01 10:30:00 deployed api-solicitacoes-1.2.3 Install complete
2 2026-07-08 14:15:00 deployed api-solicitacoes-1.2.4 Upgrade complete
3 2026-07-15 09:00:00 superseded api-solicitacoes-1.3.0 Upgrade complete
helm rollback api-solicitacoes 2 -n tenant-org-a
38.9 Auto-Scaling
38.9.1 Horizontal Pod Autoscaler (HPA)
HPA ajusta réplicas conforme métricas observadas:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-solicitacoes-hpa
namespace: tenant-org-a
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-solicitacoes
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "100"
behavior:
scaleUp:
stabilizationWindowSeconds: 30
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
HPA responde a: CPU, memory, métricas customizadas (RPS, latência). behavior controla velocidade de scale up/down para evitar flapping.
38.9.2 Vertical Pod Autoscaler (VPA)
VPA ajusta requests/limits conforme uso histórico:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-solicitacoes-vpa
namespace: tenant-org-a
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-solicitacoes
updatePolicy:
updateMode: Auto
resourcePolicy:
containerPolicies:
- containerName: api
minAllowed:
cpu: 100m
memory: 256Mi
maxAllowed:
cpu: 2
memory: 4Gi
VPA reinicia pods com novos recursos. Não usar em conjunto com HPA na mesma métrica (CPU/memory) para evitar conflitos.
38.9.3 Cluster Autoscaler
Cluster Autoscaler provisiona/destrói nós conforme demanda:
apiVersion: autoscaling.k8s.io/v1
kind: ClusterAutoscaler
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
scaleDown:
enabled: true
delayAfterAdd: 10m
delayAfterDelete: 10m
unneededTime: 5m
minNodes: 6
maxNodes: 50
nodeGroups:
- name: node-pool-app
minSize: 3
maxSize: 20
instanceType: m5.large
- name: node-pool-data
minSize: 3
maxSize: 10
instanceType: r5.xlarge
Quando pods ficam pendentes por falta de recursos, novo nó é provisionado. Quando nós ficam subutilizados por período prolongado, são destruídos.
38.9.4 KEDA para Event-Driven Scaling
KEDA escala workloads baseado em eventos externos (filas, banco, etc.):
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: workflow-processor
namespace: tenant-org-a
spec:
scaleTargetRef:
name: workflow-processor
minReplicaCount: 2
maxReplicaCount: 50
triggers:
- type: rabbitmq
metadata:
host: rabbitmq.platform.svc.cluster.local
protocol: amqp
queueName: workflow.pending
mode: QueueLength
value: "10"
Workers escalam conforme tamanho da fila. Zero workers quando fila vazia (otimização de custo).
38.10 Persistência
38.10.1 StatefulSet para Workloads com Estado
StatefulSet gerencia pods com identidade estável:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: elasticsearch-data
namespace: tenant-org-a
spec:
serviceName: elasticsearch-data
replicas: 3
selector:
matchLabels:
app: elasticsearch-data
template:
metadata:
labels:
app: elasticsearch-data
spec:
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:8.10.0
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: gp3
resources:
requests:
storage: 100Gi
Cada pod recebe nome estável: elasticsearch-data-0, elasticsearch-data-1, elasticsearch-data-2.
38.10.2 PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
namespace: tenant-org-a
spec:
accessModes:
- ReadWriteOnce
storageClassName: gp3
resources:
requests:
storage: 100Gi
38.10.3 Storage Classes
Storage classes definem provisionamento dinâmico:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3-replicated
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
allowVolumeExpansion: true
38.11 Segurança em Kubernetes
38.11.1 RBAC (Role-Based Access Control)
Permissões granulares por papel:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
namespace: tenant-org-a
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "update", "patch"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: tenant-org-a
subjects:
- kind: User
name: alice@example.com
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
38.11.2 Pod Security Standards
Restrições de segurança para pods:
apiVersion: v1
kind: Namespace
metadata:
name: tenant-org-a
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
restricted profile aplica:
- runAsNonRoot obrigatório;
- readOnlyRootFilesystem recomendado;
- sem privileged containers;
- sem host namespaces compartilhados;
- capabilities limitadas.
38.11.3 Image Registry
Apenas imagens aprovadas podem ser deployadas:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
spec:
validations:
- expression: "object.spec.containers.all(c, c.image.startsWith('registry.example.com/'))"
Adicionalmente, OPA Gatekeeper ou Kyverno aplicam regras de compliance.
38.11.4 Image Pull Secrets
spec:
imagePullSecrets:
- name: registry-credentials
containers:
- name: api
image: registry.example.com/api-solicitacoes:1.2.3
Credenciais de registry em Secret dedicado, rotacionado trimestralmente.
38.11.5 mTLS com Service Mesh
Istio ou Linkerd impõem mTLS automático:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: tenant-org-a
spec:
mtls:
mode: STRICT
Todo tráfego entre pods no namespace é criptografado e autenticado.
38.12 GitOps com Argo CD ou Flux
38.12.1 GitOps como Padrão
Manifests e configurações Kubernetes vivem em repositório Git. Argo CD reconcilia cluster com estado declarado:
Git repository (source of truth)
│
└─ Argo CD monitora mudanças
│
├─ Detecta divergência
│
└─ Sincroniza cluster para estado declarado
│
└─ Auto-sync ou manual approval
38.12.2 Estrutura de Repositório
platform-gitops/
├── apps/
│ ├── api-solicitacoes/
│ │ ├── base/
│ │ │ ├── kustomization.yaml
│ │ │ ├── deployment.yaml
│ │ │ └── service.yaml
│ │ └── overlays/
│ │ ├── dev/
│ │ ├── staging/
│ │ └── prod/
│ ├── frontend-portal/
│ └── ...
└── infrastructure/
├── namespaces/
├── network-policies/
├── rbac/
└── secrets-external/
38.12.3 Kustomize para Overlays
# apps/api-solicitacoes/base/kustomization.yaml
resources:
- deployment.yaml
- service.yaml
- ingress.yaml
# apps/api-solicitacoes/overlays/prod/kustomization.yaml
bases:
- ../../base
replicas:
- name: api-solicitacoes
count: 10
images:
- name: api-solicitacoes
newTag: 1.2.3
38.12.4 Argo CD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-solicitacoes-org-a
namespace: argocd
spec:
project: platform
source:
repoURL: https://git.example.com/platform-gitops.git
targetRevision: main
path: apps/api-solicitacoes/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: tenant-org-a
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=false
Argo CD aplica mudanças automaticamente e mantém cluster em sincronia.
38.13 Troubleshooting Operacional
38.13.1 Comandos Essenciais
# Listar pods
kubectl get pods -n tenant-org-a
# Logs de um pod
kubectl logs api-solicitacoes-7d4b -n tenant-org-a --tail=100
# Logs de múltiplos pods (Deployment)
kubectl logs -l app=api-solicitacoes -n tenant-org-a --tail=100
# Executar shell em pod
kubectl exec -it api-solicitacoes-7d4b -n tenant-org-a -- /bin/sh
# Descrever pod (events, status)
kubectl describe pod api-solicitacoes-7d4b -n tenant-org-a
# Eventos recentes
kubectl get events -n tenant-org-a --sort-by='.lastTimestamp'
# Uso de recursos
kubectl top pods -n tenant-org-a
kubectl top nodes
# Estado de deployments
kubectl rollout status deployment/api-solicitacoes -n tenant-org-a
# Histórico de rollout
kubectl rollout history deployment/api-solicitacoes -n tenant-org-a
# Rollback
kubectl rollout undo deployment/api-solicitacoes -n tenant-org-a
# Port forward para debug
kubectl port-forward api-solicitacoes-7d4b 8080:8080 -n tenant-org-a
38.13.2 Cenários Comuns de Troubleshooting
Pod em CrashLoopBackOff:
# 1. Verificar logs
kubectl logs api-solicitacoes-7d4b -n tenant-org-a
# 2. Verificar events (OOM, ImagePullBackOff, etc.)
kubectl describe pod api-solicitacoes-7d4b -n tenant-org-a
# 3. Cenários comuns:
# - ImagePullBackOff: registry inacessível ou tag incorreta
# - OOMKilled: aumentar memory limit
# - CrashLoopBackOff: bug na aplicação (ver stack trace em logs)
Service não responde:
# 1. Verificar pods do deployment
kubectl get pods -l app=api-solicitacoes -n tenant-org-a
# 2. Verificar endpoints do Service
kubectl get endpoints api-solicitacoes -n tenant-org-a
# 3. Cenários comuns:
# - Selector incorreto: pods não match
# - Porta incorreta no Service vs Pod
# - Readiness probe falhando
Performance degradada:
# 1. Verificar uso de recursos
kubectl top pods -n tenant-org-a
kubectl top nodes
# 2. Verificar métricas de aplicação
# Via Prometheus/Grafana
# 3. Verificar throttling de CPU
# dmesg ou container logs podem mostrar throttling
38.14 Upgrade de Cluster
38.14.1 Estratégia de Upgrade
Upgrades de Kubernetes seguem versões semestrais:
1.17 → 1.18 → 1.19 → 1.20 → 1.21
Em produção, plataforma suporta N-2 (3 versões atrás). Versões mais antigas são forçadas a upgrade.
38.14.2 Sequência de Upgrade
1. Ler release notes (breaking changes)
2. Atualizar cluster de desenvolvimento
3. Validar suite de testes
4. Atualizar cluster de staging
5. Smoke tests em staging (1 semana)
6. Atualizar cluster de produção
a. Upgrade control plane (1 nó por vez)
b. Aguardar estabilização
c. Upgrade worker nodes (drain + replace)
7. Validar workloads em produção
38.14.3 Upgrade de Worker Nodes
Node em produção
│
├─ kubectl drain (remove pods)
│ └─ Pods são realocados para outros nodes
│
├─ Terminate node
│
├─ Novo node provisionado com nova versão
│
└─ kubectl uncordon (permite novos pods)
drain respeita PodDisruptionBudget para garantir disponibilidade mínima.
38.15 Operadores (Operators)
38.15.1 Padrão Operator
Operator encapsula conhecimento operacional de um aplicação:
Operator (controller customizado)
│
├─ Observa recursos customizados (CRDs)
│
├─ Reconcilia estado desejado
│
└─ Aplica ações (create, update, delete)
Exemplos de Operators:
- PostgreSQL Operator: gerencia PostgreSQL com backup, restore, scaling;
- Redis Operator: cluster Redis com sharding e failover;
- ElasticSearch Operator: índices, snapshots, scaling;
- Cert-Manager: certificados TLS automáticos;
- External Secrets: sincronização de secrets externos.
38.15.2 Exemplo: PostgreSQL Operator
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
name: tenant-org-a-db
namespace: tenant-org-a
spec:
teamId: "platform"
volume:
size: 100Gi
storageClass: gp3
numberOfInstances: 3
users:
app_user:
- superuser
- createdb
databases:
tenant_org_a: app_user
postgresql:
version: "15"
resources:
requests:
cpu: 500m
memory: 2Gi
limits:
cpu: 2
memory: 8Gi
Operator provisiona: StatefulSet com 3 réplicas, Service, Secret com credenciais, configuração de replicação, backup automático.
38.16 Rastreabilidade com o Anexo III
| Item ANX-III | Atendimento |
|---|---|
| 6.1 | Infraestrutura em Kubernetes com segregação de workloads por tenant |
| 6.2 | Isolamento via RBAC e Network Policies |
| 6.3 | Auditoria de eventos do cluster |
38.17 Benefícios do Capítulo
- orquestração declarativa, imutável e auditável via GitOps;
- escalabilidade horizontal com HPA e Cluster Autoscaler;
- isolamento estrutural de tenants via namespaces e network policies;
- alta disponibilidade com pod redistribution automática e node recovery;
- observabilidade nativa com métricas Prometheus e logs estruturados;
- segurança por design com RBAC, NetworkPolicy, Pod Security Policies;
- operação consistente em cloud híbrida, pública ou on-premise;
- evolução de aplicações sem downtime via rolling updates;
- troubleshooting facilitado com ferramentas padronizadas.
38.18 Riscos e Mitigações
| Risco | Consequência | Mitigação |
|---|---|---|
| Pod em namespace de outro tenant | Vazamento de dados | NetworkPolicy deny-all default + allow explícito |
| RBAC permissivo | Usuário executa ação não autorizada | Menor privilégio, auditoria de eventos, revisão periódica |
| Secret em etcd sem criptografia | Exposição de credencial | Criptografia em repouso de etcd obrigatória |
| Node não drenado antes de upgrade | Pod loss, downtime | kubectl drain respeitando PodDisruptionBudget |
| Imagem vulnerável deployada | Execução de código malicioso | Scanning em pipeline, image signature validation |
| Resource limit insuficiente | OOMKilled, pod eviction | Rightsizing, VPA, monitoramento contínuo |
| Cluster em single AZ | Downtime por falha da AZ | Multi-AZ, pod anti-affinity, failover automático |
| Argo CD desconectada de Git | Drift config vs. cluster | Detecção de drift, alertas, sync policy |
38.19 Decisões Arquiteturais
| ADR | Tema |
|---|---|
| ADR-501 | Kubernetes como plataforma de orquestração (vs. cloud nativa proprietária) |
| ADR-502 | Modelo de namespaces: por tenant vs. por aplicação |
| ADR-503 | Estratégia de network policy: deny-all default vs. permissive |
| ADR-504 | Ingress controller: NGINX vs. alternativas |
| ADR-505 | Service mesh: Istio vs. Linkerd vs. nenhum |
| ADR-506 | CNI: Calico vs. alternativas |
| ADR-507 | Storage: local vs. EBS vs. shared filesystem |
| ADR-508 | Helm vs. Kustomize para package management |
| ADR-509 | GitOps controller: Argo CD vs. Flux |
| ADR-510 | Pod Security Policy vs. Pod Security Standards |
38.20 Considerações Finais
Kubernetes é a plataforma que permite escalabilidade e confiabilidade em escala. Mas seu poder vem com complexidade: é necessário rigor na definição de limites de recursos, policies de segurança, estratégias de alta disponibilidade e procedimentos operacionais. A plataforma de Relacionamento Digital com o Cidadão trata Kubernetes não como ferramenta experimental, mas como fundação de produção — com observabilidade, backup, disaster recovery e processos de upgrade bem definidos.
O Capítulo 39 detalha os Containers e Empacotamento.
38.21 Controle de Versão
| Campo | Valor |
|---|---|
| Documento | Documento Mestre — Plataforma de Relacionamento Digital com o Cidadão |
| Capítulo | 38 — Kubernetes e Orquestração de Containers |
| Versão | 1.0 |
| Situação | Concluído |
| Última atualização | 16/07/2026 |
38.22 Rastreabilidade PRODEMGE
- [ANX-III] Bloco 6 — Infraestrutura, Segurança e Governança: itens 6.1, 6.2, 6.3 cobertos conforme seção 38.16.
- [ANX-IV] — Capacidades técnicas de orquestração, escalabilidade horizontal, isolamento multi-tenant, alta disponibilidade, observabilidade.
- [ANX-V] Item 2.1 — Manutenibilidade: IaC com Helm/Kustomize, GitOps declarativo, repetibilidade de deploymentsda.
- [PNR] — Plano de Negócio Referencial: orquestração em Kubernetes, suporte a cloud híbrida/pública/on-premise.
- [EDITAL] — Edital CP001/2026: plataforma com orquestração de containers, escalabilidade automática, isolamento multi-tenant estrutural.
Capítulo 37 — Infraestrutura e Computação em Nuvem
Este capítulo detalha a arquitetura de infraestrutura da Plataforma de Relacionamento Digital com o Cidadão, descrevendo como recursos computacionais, de armazenamento e de rede são provisionados, organizados em topologi…
Capítulo 39 — Containers e Empacotamento
Este capítulo detalha a estratégia de empacotamento de componentes da Plataforma de Relacionamento Digital com o Cidadão em containers Docker, cobrindo: construção de imagens, segurança do container, versionamento, distr…