Relacionamento Digitalcom o Cidadão
Parte V — Tecnologia
Parte V — TecnologiaCapítulo 38

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:

TipoCaso de UsoKubernetes Resource
Serviço stateless HTTPAPI backendDeployment
Serviço statefulBanco de dadosStatefulSet + PVC
Job únicoMigration, cleanupJob
Job recorrenteLimpeza de logs, backupCronJob
Serviço de mensagensConsumer RabbitMQDeployment
DaemonLog forwarder, metrics exporterDaemonSet

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égiaCaso de UsoRisco
Rolling UpdatePadrão para APIsVersões diferentes coexistem brevemente
RecreateAplicações com estado compartilhadoDowntime durante recreate
Blue/GreenZero downtime críticoDobra capacidade durante deploy
CanaryRelease progressiva com validaçãoComplexidade 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-IIIAtendimento
6.1Infraestrutura em Kubernetes com segregação de workloads por tenant
6.2Isolamento via RBAC e Network Policies
6.3Auditoria 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

RiscoConsequênciaMitigação
Pod em namespace de outro tenantVazamento de dadosNetworkPolicy deny-all default + allow explícito
RBAC permissivoUsuário executa ação não autorizadaMenor privilégio, auditoria de eventos, revisão periódica
Secret em etcd sem criptografiaExposição de credencialCriptografia em repouso de etcd obrigatória
Node não drenado antes de upgradePod loss, downtimekubectl drain respeitando PodDisruptionBudget
Imagem vulnerável deployadaExecução de código maliciosoScanning em pipeline, image signature validation
Resource limit insuficienteOOMKilled, pod evictionRightsizing, VPA, monitoramento contínuo
Cluster em single AZDowntime por falha da AZMulti-AZ, pod anti-affinity, failover automático
Argo CD desconectada de GitDrift config vs. clusterDetecção de drift, alertas, sync policy

38.19 Decisões Arquiteturais

ADRTema
ADR-501Kubernetes como plataforma de orquestração (vs. cloud nativa proprietária)
ADR-502Modelo de namespaces: por tenant vs. por aplicação
ADR-503Estratégia de network policy: deny-all default vs. permissive
ADR-504Ingress controller: NGINX vs. alternativas
ADR-505Service mesh: Istio vs. Linkerd vs. nenhum
ADR-506CNI: Calico vs. alternativas
ADR-507Storage: local vs. EBS vs. shared filesystem
ADR-508Helm vs. Kustomize para package management
ADR-509GitOps controller: Argo CD vs. Flux
ADR-510Pod 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

CampoValor
DocumentoDocumento Mestre — Plataforma de Relacionamento Digital com o Cidadão
Capítulo38 — Kubernetes e Orquestração de Containers
Versão1.0
SituaçãoConcluído
Última atualização16/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.

Nesta página

38.1 Objetivo do Capítulo38.2 Arquitetura do Cluster Kubernetes38.2.1 Control Plane38.2.2 Worker Nodes38.2.3 Distribuição Geográfica38.3 Workloads38.3.1 Tipos de Workloads38.3.2 Pod Specification38.4 Deployments38.4.1 Deployment como Padrão para Stateless38.4.2 Rolling Update com Zero Downtime38.4.3 Health Checks38.4.4 Estratégia de Deploy38.5 Services e Networking38.5.1 Service Types38.5.2 Ingress Controller38.5.3 Service Mesh (Istio / Linkerd)38.6 Namespaces e Isolamento Multi-Tenant38.6.1 Namespace por Tenant38.6.2 Resource Quota38.6.3 LimitRange38.6.4 Network Policies38.7 ConfigMaps e Secrets38.7.1 ConfigMap para Configuração Não-Sensível38.7.2 Secret para Credenciais38.7.3 External Secrets Operator38.8 Helm como Package Manager38.8.1 Helm Charts para Templates38.8.2 Estrutura de Chart38.8.3 Template Rendering38.8.4 Instalação por Tenant38.9 Auto-Scaling38.9.1 Horizontal Pod Autoscaler (HPA)38.9.2 Vertical Pod Autoscaler (VPA)38.9.3 Cluster Autoscaler38.9.4 KEDA para Event-Driven Scaling38.10 Persistência38.10.1 StatefulSet para Workloads com Estado38.10.2 PersistentVolumeClaim38.10.3 Storage Classes38.11 Segurança em Kubernetes38.11.1 RBAC (Role-Based Access Control)38.11.2 Pod Security Standards38.11.3 Image Registry38.11.4 Image Pull Secrets38.11.5 mTLS com Service Mesh38.12 GitOps com Argo CD ou Flux38.12.1 GitOps como Padrão38.12.2 Estrutura de Repositório38.12.3 Kustomize para Overlays38.12.4 Argo CD Application38.13 Troubleshooting Operacional38.13.1 Comandos Essenciais38.13.2 Cenários Comuns de Troubleshooting38.14 Upgrade de Cluster38.14.1 Estratégia de Upgrade38.14.2 Sequência de Upgrade38.14.3 Upgrade de Worker Nodes38.15 Operadores (Operators)38.15.1 Padrão Operator38.15.2 Exemplo: PostgreSQL Operator38.16 Rastreabilidade com o Anexo III38.17 Benefícios do Capítulo38.18 Riscos e Mitigações38.19 Decisões Arquiteturais38.20 Considerações Finais38.21 Controle de Versão38.22 Rastreabilidade PRODEMGE