☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta Pods. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Pods. Mostrar todas as mensagens

terça-feira, 11 de agosto de 2026

Kubernetes para COBOLzeiros: o Guia do Mochileiro das Galáxias para quem saiu do JES2, encontrou um Pod e perguntou onde diabos colocaram o JCL

 

Bellacosa Mainframe apresenta kubernetes para coboleiros

☕ Um Café no Bellacosa Mainframe

Kubernetes para COBOLzeiros: o Guia do Mochileiro das Galáxias para quem saiu do JES2, encontrou um Pod e perguntou onde diabos colocaram o JCL

🚀 Pods, Deployments, Services, YAML, containers, RBAC, storage, GitOps e a estranha descoberta de que o mundo cloud-native passou décadas reinventando problemas que o velho operador do mainframe já conhecia — só que agora tudo tem nomes novos, logos simpáticos e pode desaparecer antes do café esfriar

Há uma frase impressa em letras grandes e amistosas na capa do Guia do Mochileiro das Galáxias:

NÃO ENTRE EM PÂNICO.

Se Douglas Adams tivesse vivido tempo suficiente para trabalhar com Kubernetes, provavelmente acrescentaria uma segunda:

E NÃO APAGUE O NAMESPACE prod.

Porque Kubernetes tem uma característica curiosa.

Quando você olha pela primeira vez, encontra palavras como:

Pod, Deployment, ReplicaSet, Service, Ingress, ConfigMap, Secret, StatefulSet, DaemonSet, Helm, Operator, CRD.

O COBOLzeiro veterano olha aquilo e pensa:

— Meu Deus. Inventaram outra computação.

Não inventaram.

Mudaram a arquitetura, mudaram a escala, mudaram a implementação, inventaram abstrações extremamente poderosas e deram nomes diferentes a problemas que, em muitos casos, nós já enfrentávamos quando o terminal ainda era verde.

Precisamos executar programas.

Precisamos saber onde executá-los.

Precisamos distribuir recursos.

Precisamos armazenar configurações.

Precisamos controlar acesso.

Precisamos monitorar aplicações.

Precisamos guardar dados.

Precisamos recuperar processos que morreram.

Precisamos instalar novas versões sem transformar terça-feira à noite numa reunião extraordinária com 27 pessoas.

E, acima de tudo:

precisamos impedir que alguma coisa quebrou às 02:47 da manhã sem ninguém saber por quê.

Então pegue sua toalha, seu café e talvez aquele manual de JCL que você insiste em manter na gaveta.

Hoje vamos viajar para Kubernetes.


1. Antes de Kubernetes havia... computadores

Vamos começar pelo começo.

Um programador COBOL iniciante conhece aproximadamente este universo:

Programa COBOL
      |
      v
Compilação
      |
      v
LOAD MODULE
      |
      v
JCL
      |
      v
JES
      |
      v
Execução

Naturalmente estou simplificando.

Mas existe uma ideia importante:

o programa precisa de um ambiente para executar.

Ele precisa de CPU, memória, arquivos, bibliotecas, configuração, permissões e recursos.

Isso nunca desapareceu.

No universo moderno surgiu outro problema.

Imagine uma aplicação desenvolvida em determinado ambiente:

Aplicação
+
bibliotecas
+
runtime
+
dependências
+
configuração

Na máquina do desenvolvedor funciona perfeitamente.

Vai para outro servidor:

ABEND GALÁCTICO

— Mas na minha máquina funciona!

Essa frase provavelmente causou mais sofrimento humano que Vogons lendo poesia.

Uma das respostas modernas para esse problema foram os containers.


2. Container: coloque a aplicação numa caixinha

De maneira bastante simplificada, um container empacota a aplicação e aquilo de que ela precisa para executar de forma consistente.

Pense:

+----------------------+
|      CONTAINER       |
|                      |
| aplicação            |
| runtime              |
| bibliotecas          |
| dependências         |
|                      |
+----------------------+

Isso melhora enormemente a portabilidade.

Mas imediatamente surge outro problema.

Você possui:

1 container

Tudo maravilhoso.

Depois:

10 containers

Administrável.

Depois:

100 containers

Interessante.

Depois:

3.000 containers

Alguém pergunta:

— Quem administra isso?

Silêncio na sala.

É nesse momento que Kubernetes entra pela porta.


3. Kubernetes não é simplesmente um “Docker grandão”

Essa comparação ajuda durante cinco minutos e depois começa a atrapalhar.

Kubernetes é uma plataforma para orquestração de workloads containerizadas.

A palavra mágica é:

ORQUESTRAÇÃO

Imagine uma orquestra com 200 músicos.

O maestro não toca simultaneamente todos os instrumentos.

Ele coordena o conjunto.

Kubernetes tenta responder perguntas como:

  • onde uma aplicação será executada?

  • quantas cópias dela devem existir?

  • o que fazer quando uma morre?

  • como encontrar essas cópias?

  • como distribuir tráfego?

  • como atualizar uma versão?

  • como fornecer configuração?

  • como controlar recursos?

  • como armazenar dados persistentes?

  • quem pode alterar o quê?

Isso já começa a parecer menos alienígena para alguém vindo de ambientes corporativos.


4. A ideia que muda tudo: estado desejado

Aqui está provavelmente o conceito mais importante de Kubernetes.

Você declara aquilo que deseja.

Por exemplo:

replicas: 3

Traduzindo para português de máquina do café:

“Senhor Kubernetes, eu gostaria que existissem três instâncias dessa aplicação.”

Ele observa:

DESEJADO = 3
ATUAL    = 3

Tudo certo.

Então uma delas morre:

DESEJADO = 3
ATUAL    = 2

Kubernetes percebe:

— Isso não está certo.

E tenta retornar para:

3

Esse processo é chamado, em essência, de reconciliação.

Podemos imaginar:

Estado desejado
      |
      v
Estado atual
      |
      v
São iguais?
  /       \
SIM       NÃO
 |         |
OK      corrigir
           |
           +------+
                  |
                  v
              observar
              novamente

Kubernetes é, em grande parte, uma enorme máquina dizendo:

“O universo não está como deveria estar. Vou tentar consertá-lo.”

É uma ambição que normalmente encontramos apenas em sistemas distribuídos, religiões e departamentos de arquitetura corporativa.


5. Control Plane: conheça o cérebro da criatura

Um cluster Kubernetes pode ser imaginado assim:

                 KUBERNETES CLUSTER
                        |
           +------------+------------+
           |                         |
     CONTROL PLANE              WORKER NODES
           |                         |
     API Server                    Pods
     Scheduler                     kubelet
     Controllers                   runtime
     etcd                          network

O Control Plane administra o estado do cluster.

E um dos personagens principais é:

kube-apiserver

Quando você executa:

kubectl get pods

não está indo de porta em porta perguntar aos containers:

— Boa tarde, senhor Pod, o senhor está vivo?

Você fala com a API do Kubernetes.

Conceitualmente:

VOCÊ
 |
kubectl
 |
 v
API SERVER
 |
 +-- autenticação
 +-- autorização
 +-- validação
 +-- recursos do cluster

Esse detalhe revela uma característica fundamental:

Kubernetes é profundamente API-driven.


6. etcd: o sujeito que sabe das coisas

O etcd é um armazenamento distribuído chave-valor usado pelo Kubernetes para guardar dados essenciais sobre o estado do cluster.

Imagine que alguém diga:

— Temos backup dos servidores.

Ótimo.

— E do etcd?

Silêncio.

Uma mosca passa.

O operador começa lentamente a beber o café.

Informações críticas do estado do cluster dependem dele. Portanto backup e recuperação do etcd são assuntos sérios.

Primeira regra da produção:

Backup que nunca teve restauração testada é uma crença religiosa.


7. Scheduler: o JES encontrou um primo distante

Você solicita uma workload.

Existem vários Nodes:

NODE-A
NODE-B
NODE-C
NODE-D

Onde ela será executada?

O Scheduler participa dessa decisão.

Ele considera recursos e restrições como:

CPU
memória
afinidade
anti-afinidade
taints
tolerations
restrições de placement

O COBOLzeiro começa a sorrir.

— Espere... alguém recebe uma carga de trabalho, olha recursos e decide onde executar?

Sim.

— Então é JES?

NÃO.

Guarde a toalha.

As tecnologias, arquiteturas e responsabilidades são diferentes.

Mas existe um parentesco conceitual extremamente útil para aprender.

O truque para um profissional experiente aprender tecnologia nova não é fingir que tudo é completamente novo.

É perguntar:

“Qual problema antigo essa abstração está tentando resolver de uma maneira nova?”


8. Worker Node: onde a marmota realmente trabalha

O Control Plane coordena.

Os Worker Nodes executam as workloads.

Dentro deles encontramos componentes como o kubelet, runtime de containers e elementos relacionados a networking.

Podemos imaginar:

WORKER NODE
 |
 +-- kubelet
 |
 +-- runtime
 |
 +-- POD
 |    |
 |    +-- container
 |
 +-- POD
      |
      +-- container

E aqui encontramos talvez a palavra mais famosa do Kubernetes.


9. POD — não é ervilha espacial

O Kubernetes não trabalha simplesmente administrando containers isoladamente.

Uma unidade fundamental de execução é o:

Pod

Normalmente encontramos:

Pod
 |
 +-- Container

Mas um Pod pode possuir mais de um container quando existe uma razão arquitetural para isso:

Pod
 |
 +-- aplicação
 |
 +-- container auxiliar

Containers no mesmo Pod compartilham aspectos importantes de seu ambiente.

Portanto:

POD != CONTAINER

Grave isso.

Pode parecer uma distinção acadêmica no primeiro dia.

No vigésimo ela salva sua compreensão do ambiente.


10. E o Pod morreu

Aqui acontece uma transformação filosófica interessante para quem passou décadas tratando servidores como indivíduos.

No mundo tradicional:

“Esse é o servidor XPTO01. Cuide dele.”

No Kubernetes, muita infraestrutura é tratada como efêmera.

O Pod morreu?

Pode surgir outro.

Hoje:

Pod A
10.20.1.17

Amanhã:

Pod A = morto

Pod B
10.20.4.38

Por isso construir dependências baseadas diretamente na identidade transitória de um Pod seria uma péssima ideia.

Precisamos de abstrações.


11. ReplicaSet: quero três vivos

Imagine:

Desejado = 3 Pods

Temos:

Pod
Pod
Pod

Um desaparece:

Pod
X
Pod

O ReplicaSet ajuda a manter:

3

criando outro.

Aqui reencontramos nosso velho amigo:

estado desejado.


12. Deployment: agora precisamos atualizar tudo

Na prática, para aplicações comuns, normalmente trabalhamos com um Deployment, que administra ReplicaSets e facilita rollouts.

Imagine:

Deployment
    |
ReplicaSet V1
    |
 +-- Pod
 +-- Pod
 +-- Pod

Sai versão nova.

Em vez de:

PARE TUDO!

podemos fazer uma substituição progressiva:

V1  V1  V1

V2  V1  V1

V2  V2  V1

V2  V2  V2

Isso é tremendamente importante em ambientes modernos onde deploys podem ocorrer com frequência.

E quando algo dá errado?

Rollback passa a fazer parte da conversa.


13. Service: “mas qual IP eu chamo?”

Lembra que Pods podem desaparecer?

Temos:

Frontend
    |
    ???
    |
Backend Pods

Como o frontend encontra o backend se os Pods mudam?

Usamos uma abstração chamada:

Service

CLIENTE
   |
   v
SERVICE
   |
   +---- Pod
   |
   +---- Pod
   |
   +---- Pod

O Service fornece um ponto lógico estável para acessar um conjunto de Pods selecionados.

Aqui existe uma das ideias mais bonitas do cloud-native:

colocar identidade lógica estável diante de componentes fisicamente transitórios.


14. ConfigMap: não coloque o universo dentro do programa

Aplicações precisam de configurações:

LOG_LEVEL=INFO
LANGUAGE=PT_BR
API_HOST=...

Você poderia colocar tudo dentro da imagem.

Mas então qualquer mudança exigiria outra construção da imagem.

ConfigMaps permitem separar parte da configuração da aplicação.

É uma evolução daquele princípio antigo:

programa é uma coisa; parâmetros do ambiente são outra.

COBOLzeiro conhece essa conversa há décadas, mesmo usando mecanismos completamente diferentes.


15. Secret: o nome promete mais do que parece

Temos informações sensíveis:

senha
token
chave
certificado

Kubernetes possui o objeto Secret.

Mas cuidado com uma armadilha clássica:

Um objeto chamado Secret não significa automaticamente “segredo absolutamente protegido contra tudo”.

Segurança adequada envolve também:

  • RBAC;

  • criptografia em repouso;

  • proteção do etcd;

  • controle de Service Accounts;

  • secret managers;

  • rotação;

  • auditoria;

  • mínimo privilégio.

Colocar a senha em Secret e declarar vitória é como escrever:

//PASSWORD DD *
SUPERSECRETA123
/*

e colocar uma etiqueta dizendo CONFIDENCIAL.

A etiqueta não é o controle de segurança.


16. Storage: containers morrem; saldo bancário não deveria

Containers são naturalmente descartáveis.

Dados empresariais frequentemente não são.

Imagine:

Banco de dados
     |
 container
     |
   morreu

Kubernetes responde:

— Sem problemas, fazemos outro!

O DBA responde:

— E MEUS DADOS?

E nesse instante nasce uma reunião.

Para persistência encontramos conceitos como:

PersistentVolume
PersistentVolumeClaim
StorageClass

Simplificando:

POD
 |
PVC
 |
PV
 |
STORAGE REAL

O Pod pode ser transitório.

O armazenamento precisa seguir regras diferentes.


17. StatefulSet: quando identidade importa

Deployments funcionam muito bem quando as instâncias podem ser relativamente intercambiáveis.

Mas nem toda workload funciona assim.

Algumas precisam de identidade previsível:

db-0
db-1
db-2

e armazenamento associado.

Aparece então o:

StatefulSet

Ele é especialmente relevante para workloads stateful e sistemas distribuídos que precisam de identidade e ordenação mais previsíveis.

Isso não significa:

“StatefulSet transforma magicamente qualquer banco em banco cloud-native.”

Se fosse tão fácil, DBA seria uma profissão de seis minutos.


18. DaemonSet: um para cada Node

Imagine um agente de monitoramento que precisa existir em todos os Nodes:

NODE A → agente
NODE B → agente
NODE C → agente
NODE D → agente

O DaemonSet serve muito bem para esse padrão.

Aplicações típicas incluem agentes de:

  • observabilidade;

  • logging;

  • segurança;

  • networking.

Quando surge outro Node, a intenção pode ser automaticamente refletida nele.

Estado desejado novamente.

Kubernetes é quase obsessivo.


19. Jobs e CronJobs: o COBOLzeiro reconhece um parente

Nem tudo precisa ficar executando eternamente.

Temos tarefas:

INÍCIO
 |
PROCESSAMENTO
 |
FIM

Kubernetes possui Jobs.

E para tarefas periódicas:

CronJobs

O COBOLzeiro imediatamente pergunta:

— Então isso é batch?

Em espírito, estamos no mesmo bairro.

Mas não na mesma casa.

Um Job Kubernetes não substitui automaticamente décadas de ecossistema batch corporativo, scheduling, dependências, restart/recovery, controles operacionais e processamento transacional.

Ainda assim, a analogia ajuda enormemente:

Job → trabalho finito

CronJob → trabalho agendado

20. Requests e Limits: WLM manda lembranças

Aqui chegamos a uma área deliciosa para quem conhece mainframe.

Uma workload pode declarar algo semelhante a:

resources:
  requests:
    cpu: "500m"
    memory: "512Mi"
  limits:
    cpu: "1"
    memory: "1Gi"

Simplificando, requests ajudam a expressar recursos necessários para scheduling; limits impõem tetos de utilização conforme o recurso.

A pergunta filosófica é antiga:

Temos recursos finitos e consumidores potencialmente infinitos. Quem recebe quanto?

O mainframe possui décadas de engenharia sofisticadíssima em workload management.

Kubernetes aborda isso dentro de seu próprio modelo.

Não diga:

Kubernetes WLM = IBM WLM

Não são equivalentes.

Diga:

Ambos enfrentam aspectos do velho problema de administrar recursos compartilhados e workloads concorrentes.

Essa comparação ensina.

A equivalência enganaria.


21. Agora chegamos ao inferno: produção

Até aqui tudo funciona.

Tutorial:

pod/myapp created

Aluno:

— Kubernetes é fácil!

Produção:

CrashLoopBackOff

Aluno:

— Chamem um adulto.

E aqui começa o verdadeiro treinamento.

Você precisa conhecer:

  • logs;

  • events;

  • probes;

  • métricas;

  • CPU;

  • memória;

  • DNS;

  • networking;

  • storage;

  • permissões;

  • dependências;

  • configuração.

Porque:

CrashLoopBackOff

não significa:

“Execute o comando secreto número 17.”

Significa que existe um comportamento de reinício repetido a investigar.

A causa pode ser:

configuração errada
dependência indisponível
credencial
permissão
OOM
bug
porta
DNS
storage
probe

É quase o nosso querido:

S0C7

O código oferece uma pista.

Mas experiência transforma a pista em investigação.


22. Observabilidade: o cluster precisa falar

Imagine:

Usuário
  |
Ingress
  |
Service
  |
Pod
  |
Aplicação
  |
API
  |
Banco

Usuário diz:

“Está lento.”

Maravilha.

Onde?

Precisamos de diferentes sinais:

METRICS
LOGS
TRACES
EVENTS

Não basta saber que um Pod está Running.

Um processo pode estar vivo e a aplicação completamente inútil.

É por isso que existem conceitos como:

liveness probe e readiness probe.

De forma simplificada:

Liveness:
"Você ainda está vivo?"

Readiness:
"Você está pronto para receber tráfego?"

São perguntas diferentes.

Um sujeito pode estar vivo às seis da manhã e absolutamente não estar pronto para receber tráfego.

Eu sou prova disso antes do café.


23. RBAC: RACF olha pela janela

RBAC significa Role-Based Access Control.

A pergunta é familiar:

QUEM
 |
pode fazer
 |
O QUÊ
 |
sobre QUAL RECURSO?

Exemplo:

PROGRAMADOR
 |
 +--> visualizar Pods       SIM
 +--> consultar logs        SIM
 +--> destruir cluster      NÃO, ESPERAMOS

Quem conhece RACF encontra aqui outra ponte conceitual.

RBAC não é RACF.

Mas autorização baseada em identidades, recursos, permissões e mínimo privilégio definitivamente não nasceu ontem.


24. NetworkPolicy: “você não precisa conversar com ele”

Imagine:

FRONTEND
    |
BACKEND
    |
DATABASE

O frontend precisa realmente acessar diretamente o banco?

Talvez não.

Então podemos desejar:

Frontend ---> Backend     OK
Frontend -X-> Database    NÃO

Backend ----> Database    OK

Network Policies permitem controlar fluxos de rede entre workloads quando suportadas adequadamente pelo ambiente de networking.

Aqui começamos a caminhar em direção a arquiteturas mais próximas do princípio de:

negue aquilo que não é necessário.


25. Helm: porque 47 YAMLs também cansam

No início temos:

deployment.yaml

Depois:

deployment.yaml
service.yaml
configmap.yaml
ingress.yaml
secret.yaml
pvc.yaml
...

Em determinado momento alguém pergunta:

— Não poderíamos empacotar isso?

Entra Helm.

Helm trabalha com Charts, templates e valores configuráveis.

Conceitualmente:

Chart
 |
 +-- templates
 |
 +-- values
 |
 +-- metadata

E aqui ocorre um ritual iniciático cloud-native:

  1. você aprende YAML;

  2. aprende templates;

  3. aprende templates que produzem YAML;

  4. recebe uma mensagem de erro;

  5. olha para o teto;

  6. reconsidera decisões profissionais;

  7. resolve;

  8. coloca no LinkedIn.


26. CRD: “eu também posso inventar objetos?”

Sim.

Uma das capacidades mais interessantes do Kubernetes são as Custom Resource Definitions.

Originalmente você trabalha com recursos como:

Pod
Service
Deployment

Com CRDs podemos estender a API com recursos específicos.

Conceitualmente:

Database
Certificate
KafkaCluster
Backup
MeuObjetoCorporativo

Isso revela que Kubernetes é mais que um mero lançador de containers.

Ele oferece uma espécie de framework declarativo extensível para sistemas de controle.

Essa mudança mental é importante.


27. Operator: o runbook ganhou pernas

Imagine o velho especialista.

Ele sabe:

SE A acontecer
   verifique B

SE B estiver assim
   execute C

SE C falhar
   tente D

Décadas de conhecimento operacional.

Um Operator tenta codificar conhecimento operacional específico usando o modelo de controllers e reconciliação do Kubernetes.

Simplificando:

Conhecimento operacional
          |
          v
       código
          |
          v
      Operator
          |
          v
observa → decide → reconcilia

É como se parte do runbook ganhasse vida.

Não elimina o especialista.

Muda o lugar onde parte do conhecimento dele vive.


28. CI/CD: ninguém deveria levar o deploy num disquete

O próximo passo natural é automação.

Temos:

Código
 |
Git
 |
Build
 |
Teste
 |
Imagem
 |
Registry
 |
Deploy
 |
Kubernetes

Entramos no território de CI/CD.

E depois aparece GitOps.

Em vez de alguém alterar manualmente produção:

OPERADOR
 |
kubectl
 |
PRODUÇÃO

podemos trabalhar com um modelo no qual o Git representa o estado desejado relevante:

Developer
   |
   v
  Git
   |
Pull Request
   |
Review
   |
   v
GitOps Controller
   |
   v
Cluster

Isso melhora possibilidades de:

  • rastreabilidade;

  • auditoria;

  • revisão;

  • versionamento;

  • recuperação;

  • consistência.

Mas lembre-se:

automatizar processo ruim produz desastre em velocidade industrial.


29. O que aquele roadmap deveria mostrar antes do Kubernetes

Aqui está minha principal crítica à figura.

Eu colocaria uma Fase Zero:

FASE ZERO

Linux
  |
processos
  |
filesystem
  |
CPU/memória
  |
networking
  |
TCP/IP
  |
DNS
  |
HTTP
  |
TLS
  |
containers
  |
images
  |
runtime
  |
KUBERNETES

Por quê?

Porque Kubernetes não aboliu o sistema operacional.

Nem aboliu rede.

Nem DNS.

Especialmente DNS.

Existe um antigo espírito maligno vagando pelos datacenters dizendo:

“It's always DNS.”

Quando você acha que não é DNS, eventualmente descobre que era DNS usando bigode falso.


30. Networking merece uma fase própria

Eu ampliaria o roadmap para incluir profundamente:

IP
CIDR
TCP
UDP
DNS
NAT
routing
TLS
Load Balancing
ClusterIP
NodePort
LoadBalancer
Ingress
CNI
NetworkPolicy

Porque um dos incidentes mais frustrantes é:

Pod: Running
Application: Healthy
Service: Exists

Usuário: NÃO FUNCIONA.

Então começa a expedição arqueológica.


31. Segurança de supply chain também precisa entrar

Em 2026 não basta perguntar:

“A imagem funciona?”

Precisamos perguntar:

Quem construiu essa imagem?
De onde veio?
Qual imagem base foi usada?
Possui vulnerabilidades?
Tem SBOM?
Foi assinada?
Quem pode publicar?
Foi adulterada?

Ou seja, o roadmap moderno precisa incluir:

  • scanning;

  • provenance;

  • SBOM;

  • assinatura;

  • admission policies;

  • least privilege;

  • gestão de secrets;

  • identidade de workloads;

  • atualização segura.

O container é conveniente justamente porque carrega muita coisa consigo.

E tudo aquilo que carregamos conosco também pode carregar problemas.


32. E o mainframe no meio dessa galáxia?

Aqui existe uma oportunidade fantástica para o COBOLzeiro.

Não pense:

Kubernetes
VERSUS
Mainframe

Pense:

                 INTERNET
                    |
              KUBERNETES
                    |
              APIs / serviços
                    |
          +---------+---------+
          |                   |
       CLOUD              MAINFRAME
                           |
                   +-------+-------+
                   |       |       |
                  CICS    IMS     Db2
                   |
                 COBOL

Kubernetes não precisa destruir o mainframe para justificar sua existência.

Um banco pode perfeitamente ter sistemas transacionais críticos em IBM Z enquanto utiliza Kubernetes para APIs, integração, canais digitais, serviços distribuídos, observabilidade e outras workloads.

O mundo corporativo real é híbrido.

A Millennium Falcon também não foi construída inteira pela mesma consultoria.

Provavelmente por isso funcionava.


33. O laboratório que eu faria para um COBOLzeiro

Aqui está o caminho prático.

Não faça 25 tutoriais desconectados.

Construa uma aplicação e faça-a evoluir.

Chamaremos:

BELLACOSA INTERGALACTIC BANK

Versão 1:

Frontend

Versão 2:

Frontend
   |
Backend

Versão 3:

Frontend
   |
Service
   |
Backend

Versão 4:

Ingress
   |
Frontend
   |
Service
   |
Backend
   |
Database

Depois acrescente:

ConfigMap
Secrets
PVC
Requests
Limits
Probes
RBAC
NetworkPolicy
Monitoring
Logging

Depois:

CI/CD

Depois:

GitOps

E somente então:

Helm
Operators
CRDs

Não tente aprender a galáxia inteira antes de visitar a Lua.


34. Agora destrua tudo

Esta é a etapa que falta em muitos cursos.

Faça o Pod morrer.

kubectl delete pod ...

Observe o que acontece.

Coloque memória insuficiente.

Quebre uma configuração.

Use uma imagem inexistente.

Quebre uma readiness probe.

Remova uma permissão.

Altere uma NetworkPolicy.

Crie problema de storage.

Observe:

Pending
ImagePullBackOff
CrashLoopBackOff
OOMKilled
Forbidden
Readiness probe failed

Para cada incidente pergunte:

O QUE aconteceu?

POR QUE aconteceu?

QUAL componente percebeu?

QUAL estado era desejado?

QUAL estado existia?

QUEM tentou reconciliar?

ONDE encontro evidência?

COMO evitar novamente?

Esse exercício ensina dez vezes mais do que decorar cinquenta comandos.


35. O COBOLzeiro possui uma vantagem escondida

O programador COBOL iniciante talvez olhe Kubernetes e pense que está começando do zero.

Não está.

Se ele está aprendendo o ecossistema mainframe simultaneamente, já está entrando em contato com perguntas universais:

Como programas são executados?

Como recursos são alocados?

Como identidade funciona?

Como permissões são verificadas?

Como dados persistem?

Como jobs são agendados?

Como falhas são diagnosticadas?

Como mudanças chegam à produção?

Como recuperamos alguma coisa que quebrou?

Essas perguntas atravessaram gerações de computadores.

As respostas mudaram.

As perguntas continuam surpreendentemente parecidas.


36. A tabela de tradução intergaláctica

Não como equivalência técnica, mas como pontes mentais:

Universo MainframeUniverso KubernetesIdeia em comum
JES/schedulingScheduler/Jobsexecução organizada de workloads
JCL/parâmetrosmanifests/configuraçãodeclarar como executar
PROCtemplates/Helmreutilização
RACFRBACautorização
WLMrequests/limits/schedulinggestão de recursos
Started Tasksserviços/workloads contínuasprocessos duradouros
Scheduler batchCronJobexecução periódica
datasets/storagePV/PVCpersistência
Sysplex/HAcluster/replicasdisponibilidade
SMF/RMF/logsmetrics/logs/tracesobservabilidade
RunbookOperatorconhecimento operacional

Novamente:

não são equivalentes.

Essa tabela é mapa turístico, não especificação de arquitetura.

Se você tentar usar um mapa turístico para fazer cirurgia, o resultado será digno dos Vogons.


37. Do iniciante ao arquiteto

Existe uma progressão interessante.

Nível 1

O aluno pergunta:

“Como crio um Pod?”

Nível 2

Pergunta:

“Como faço três réplicas?”

Nível 3

Pergunta:

“Por que esse Pod morreu?”

Nível 4

Pergunta:

“Por que ele continua morrendo?”

Nível 5

Pergunta:

“Por que nossa arquitetura permitiu que a morte desse Pod afetasse usuários?”

Nível 6

Pergunta:

“Como eliminamos essa classe inteira de falhas?”

Essa é a transformação.

COMANDO
   ↓
OBJETO
   ↓
PLATAFORMA
   ↓
OPERAÇÃO
   ↓
ARQUITETURA
   ↓
ENGENHARIA DE RESILIÊNCIA

38. Easter Egg: Kubernetes e o número 42

No Guia do Mochileiro das Galáxias, a resposta para a Grande Questão da Vida, do Universo e Tudo Mais é:

42

Depois descobriram que ninguém sabia exatamente qual era a pergunta.

Kubernetes possui uma versão corporativa disso.

O arquiteto pergunta:

— Quantas réplicas precisamos?

Consultor:

— Três.

— Por quê?

— Alta disponibilidade.

— Baseado em qual cálculo?

— ...

— Tráfego?

— ...

— SLO?

— ...

— capacidade?

— ...

— histórico de falhas?

— ...

— teste de carga?

— ...

Três virou o 42 da arquitetura cloud-native.

😆

A lição é excelente:

uma resposta tecnicamente plausível sem a pergunta correta continua sendo apenas uma resposta procurando uma justificativa.


39. Outra curiosidade: Kubernetes significa timoneiro

O nome vem do grego e remete à ideia de timoneiro/piloto.

Daí também o famoso leme no logotipo.

E isso é poeticamente perfeito.

Kubernetes não é o navio.

Não é a carga.

Não é o oceano.

Ele ajuda a conduzir a embarcação.

Só existe um detalhe que nenhum tutorial coloca em letras suficientemente grandes:

você ainda precisa saber navegar.

Kubernetes não elimina a necessidade de conhecer Linux, redes, storage, segurança, aplicações e sistemas distribuídos.

Na realidade, em ambientes complexos ele pode exigir que você compreenda um pouco de todos eles simultaneamente.


40. O segredo final do roadmap

A imagem original termina aproximadamente com a ideia:

consistência + prática = especialista Kubernetes.

Eu acrescentaria algumas variáveis:

TEORIA
   +
PRÁTICA
   +
ERRO
   +
OBSERVAÇÃO
   +
TROUBLESHOOTING
   +
DOCUMENTAÇÃO
   +
CURIOSIDADE
   +
INCIDENTES
   +
CAFÉ
   =
EXPERIÊNCIA

Principalmente os erros.

Porque executar:

kubectl get pods

é fácil.

Interpretar:

NAME             READY   STATUS
app-7d98         0/1     CrashLoopBackOff

é outra história.

E descobrir que o Pod não era a causa, que a aplicação estava falhando porque não conseguia alcançar uma dependência, que a dependência estava inacessível por causa de uma alteração de rede introduzida no deploy anterior...

Aí temos engenharia.


☕ Epílogo — O COBOLzeiro pega sua toalha

Nosso programador começou a viagem olhando para um roadmap colorido e pensando:

“Pod? Helm? Ingress? CRD? Operator? Eu só queria aprender Kubernetes.”

Agora ele sabe que Kubernetes não é uma coleção de palavras estranhas.

É uma resposta moderna para um conjunto de problemas profundamente antigos:

executar, distribuir, controlar, proteger, observar, recuperar e evoluir software.

O mainframe resolveu muitos desses problemas dentro de seu próprio universo durante décadas.

Unix resolveu outros.

Cloud resolveu outros.

Containers mudaram novamente a unidade de distribuição.

Kubernetes apareceu para coordenar esse novo zoológico.

E talvez essa seja a maior lição para um programador COBOL entrando no mundo cloud-native:

não jogue fora aquilo que você aprendeu.

Traduza.

Quando encontrar RBAC, lembre-se das perguntas que RACF ensinou a fazer.

Quando encontrar requests e limits, pense nas questões que WLM levanta.

Quando encontrar Jobs, recorde o mundo batch.

Quando encontrar observabilidade, pense em RMF, SMF, logs e diagnóstico.

Quando encontrar Operators, pense no velho runbook do especialista que sabia exatamente o que fazer quando determinada luz vermelha acendia.

Não porque essas tecnologias sejam iguais.

Mas porque a história da computação é cheia de novas respostas para perguntas antigas.

E algum dia, provavelmente às 03:17 da manhã, você encontrará isto:

CrashLoopBackOff

O jovem aprendiz perguntará:

— Mestre, qual comando resolve isso?

Você tomará um gole de café, olhará calmamente para o terminal e responderá:

— Nenhum. Primeiro precisamos descobrir o que aconteceu.

Nesse instante terá ocorrido algo muito mais importante que aprender Kubernetes.

Você terá aprendido a pensar como alguém de produção.

E, como diria o Guia do Mochileiro das Galáxias, enquanto o cluster inteiro estiver pegando fogo:

+---------------------------------------+
|                                       |
|          NÃO ENTRE EM PÂNICO          |
|                                       |
|      kubectl get events               |
|                                       |
|          E LEVE UMA TOALHA            |
|                                       |
+---------------------------------------+

☕🚀

Bem-vindo ao Kubernetes, COBOLzeiro.

A galáxia continua distribuída, eventualmente consistente, estranhamente documentada e, por algum motivo que ninguém conseguiu explicar satisfatoriamente, ainda depende de DNS.

sábado, 9 de setembro de 2023

Kubernetes, COBOL e a Viagem ao Fundo do Cluster: quando o programador entrou no Seaview procurando um JCL e encontrou Pods nadando entre Nodes

 

Bellacosa Mainframe e o kubernetes no cobol uma viagem ao fundo do cluster

☕ Um Café no Bellacosa Mainframe

Kubernetes, COBOL e a Viagem ao Fundo do Cluster: quando o programador entrou no Seaview procurando um JCL e encontrou Pods nadando entre Nodes

🌊 Containers, Pods, Deployments, Services, Scheduler, Control Plane, YAML, autoscaling, storage, observabilidade e a estranha descoberta de que administrar Kubernetes às vezes parece comandar um submarino nuclear onde metade da tripulação fala YAML

Imagine a cena.

O jovem programador COBOL entra no CPD numa segunda-feira, café na mão, perfeitamente confortável com aquele universo conhecido:

JOB
JCL
JES2
COBOL
CICS
Db2
VSAM
SDSF

Tudo possui nome.

Tudo possui finalidade.

Tudo possui, em algum lugar, um manual de 2.700 páginas que ninguém leu inteiro, mas algum sysprog aposentado sabe exatamente em qual capítulo está a informação necessária.

Então alguém da arquitetura aparece.

— Precisamos colocar a nova aplicação em Kubernetes.

O COBOLzeiro olha para ele.

— Em quê?

— Kubernetes.

— Isso é banco de dados?

— Não.

— Linguagem?

— Não.

— Sistema operacional?

— Não exatamente.

— Middleware?

— Também não.

— Scheduler?

— Mais ou menos.

— Docker?

— Não.

Silêncio.

O jovem COBOLzeiro bebe café.

— Então vocês inventaram uma coisa que não dá para explicar em uma palavra.

Bem-vindo ao século XXI.

E é nesse momento que nossa viagem começa.

Não a bordo da Enterprise.

Nem da TARDIS.

Hoje descemos centenas de metros abaixo da superfície, entrando num submarino tecnológico imaginário chamado:

USS KUBERNETES

Um enorme navio submersível cheio de containers, workloads, redes, volumes, APIs e operadores correndo pelos corredores gritando:

— CAPITÃO! PERDEMOS UM POD!

E o capitão responde:

— Quantas réplicas estavam declaradas?

— TRÊS!

— Quantas temos?

— DUAS!

— Então pare de gritar. O controller já está criando outra.

E o COBOLzeiro, olhando pela escotilha:

— Que tipo de feitiçaria é essa?

Pegue o café.

Vamos ao fundo do cluster.


🌊 Capítulo 1 — Kubernetes não é Docker

Antes de descermos aos níveis mais profundos precisamos matar um dos monstros marinhos mais resistentes da informática moderna:

“Kubernetes substituiu Docker.”

Não.

O problema começa porque vários conceitos acabaram historicamente misturados.

Docker popularizou containers.

Kubernetes popularizou a orquestração de containers.

E durante algum tempo existiu uma disputa mais direta entre:

Docker Swarm
        versus
Kubernetes

Isso fazia sentido porque ambos tratavam de orquestração.

Mas Docker e Kubernetes não ocupam exatamente a mesma camada.

Pense desta forma:

Aplicação
   |
   v
Imagem
   |
   v
Container
   |
   v
Runtime
   |
   v
Pod
   |
   v
Kubernetes
   |
   v
Cluster

Docker ajudou a tornar simples construir, distribuir e executar containers.

Kubernetes pergunta outra coisa:

“Muito bem. Agora você possui 4.000 desses bichos. Quem administra?”

Essa pergunta muda tudo.


⚓ Capítulo 2 — O que diabos é um container?

O COBOLzeiro geralmente conhece um mundo bastante previsível.

Você compila:

PROGRAMA.CBL
       |
       v
 compilador
       |
       v
 load module

Depois executa num ambiente definido.

No mundo moderno surgiu um problema recorrente.

O programador dizia:

— Funciona na minha máquina.

Produção respondia:

— Pois aqui não funciona.

Então começava a investigação arqueológica:

versão diferente da biblioteca
variável de ambiente ausente
pacote não instalado
configuração divergente
runtime diferente
permissão diferente

O container tenta encapsular boa parte desse ambiente.

Imagine uma caixa contendo:

Aplicação
Bibliotecas
Dependências
Runtime
Configuração básica

Essa caixa pode ser reproduzida em diferentes ambientes.

Mas cuidado.

Container não é simplesmente uma VM pequena.

Uma máquina virtual tradicional possui algo parecido com:

HARDWARE
   |
HYPERVISOR
   |
   +---- VM A
   |      |
   |   Guest OS
   |
   +---- VM B
          |
       Guest OS

Já containers normalmente compartilham o kernel do host:

HARDWARE
   |
HOST OS
   |
KERNEL
   |
   +---- Container A
   +---- Container B
   +---- Container C

O isolamento utiliza mecanismos do sistema operacional, especialmente recursos como:

namespaces
cgroups
filesystem isolation
network isolation

Portanto containers costumam ser muito mais leves que VMs completas.

Não existe um sistema operacional inteiro sendo inicializado dentro de cada container da mesma forma que numa VM tradicional.


🐋 Curiosidade do sonar — Docker não inventou isolamento

A ideia de isolamento de processos é muito anterior ao Docker.

Unix já possuía conceitos relacionados.

Depois vieram tecnologias como:

chroot
FreeBSD Jails
Solaris Zones
Linux namespaces
cgroups
LXC

Docker acertou magistralmente numa coisa:

experiência de uso.

Ele tornou relativamente simples construir uma imagem e executar:

docker run

Em tecnologia, muitas revoluções acontecem não quando algo é inventado, mas quando alguém torna aquilo utilizável por gente normal.


🌊 Capítulo 3 — Três containers não precisam de um almirante

Imagine que temos:

Container A
Container B
Container C

Você pode executá-los manualmente.

Talvez Docker Compose resolva perfeitamente.

Agora aumente:

30 containers
300 containers
3.000 containers

Distribuídos entre:

Node 01
Node 02
Node 03
...
Node 200

Então começam as perguntas.

Onde colocar cada aplicação?

Quem reinicia algo que morreu?

Quem percebe que uma máquina caiu?

Quem encontra capacidade disponível?

Quem faz atualização sem interromper o serviço?

Quem distribui tráfego?

Quem escala?

Quem controla configuração?

Quem mantém o estado desejado?

Essa é a missão do Kubernetes.


🧭 Capítulo 4 — O conceito mais importante: estado desejado

Aqui está o segredo que transforma Kubernetes de “montanha de YAML” em algo compreensível.

O modelo é declarativo.

Você diz:

QUERO 3 RÉPLICAS

Não precisa escrever um script detalhando:

crie processo 1
crie processo 2
crie processo 3
verifique processo 1
se morrer reinicie
verifique processo 2
...

Você declara:

replicas: 3

Agora imagine o sonar:

ESTADO DESEJADO

Pod A
Pod B
Pod C

Mas o Kubernetes observa:

ESTADO REAL

Pod A
Pod B

Alguma coisa está errada.

Desejado:

3

Atual:

2

Diferença:

1

O Kubernetes tenta corrigir.

cria novo Pod

Depois observa novamente.

Essa ideia recebe um nome fundamental:

reconciliation loop.


🔁 O coração mecânico do submarino

Imagine um oficial andando eternamente pelos corredores do USS Kubernetes perguntando:

O que deveria existir?
        |
        v
O que existe agora?
        |
        v
São iguais?
   /        \
 NÃO        SIM
  |          |
corrigir   continuar
  |
observar novamente

Esse processo ocorre continuamente.

É uma diferença filosófica enorme.

Você não está apenas executando uma sequência de comandos.

Você está declarando uma condição que deseja manter verdadeira.


☕ O COBOLzeiro começa a desconfiar

Nesse momento o veterano de mainframe encosta na cadeira.

— Espera.

— Sim?

— Então existe um sistema que observa workloads, recursos, prioridades, falhas e tenta manter um estado operacional desejado?

Sim.

— Isso está começando a parecer menos alienígena.

Exatamente.

Mainframe e Kubernetes são arquiteturas profundamente diferentes.

Mas os problemas fundamentais de computação continuam aparecendo com roupas novas.


🏗️ Capítulo 5 — O cluster Kubernetes

Um ambiente Kubernetes é organizado num cluster.

Simplificando:

                CLUSTER

           CONTROL PLANE
                |
      +---------+---------+
      |         |         |
    NODE 1    NODE 2    NODE 3
      |         |         |
    Pods      Pods      Pods

Temos duas grandes categorias:

Control Plane
Worker Nodes

O Control Plane coordena.

Os Nodes executam os workloads.

Pense no submarino.

Existe a ponte de comando:

CONTROL PLANE

e existem as áreas onde o trabalho realmente acontece:

NODES

🎛️ Capítulo 6 — kube-apiserver: a sala de rádio

Quando você escreve:

kubectl apply -f deployment.yaml

você não está entrando diretamente num servidor e mandando iniciar alguma coisa.

Você está interagindo com a API do Kubernetes.

O kube-apiserver é uma peça central dessa arquitetura.

É através dele que grande parte das interações ocorre.

Conceitualmente:

kubectl
   |
   v
API SERVER
   |
   +--> autenticação
   +--> autorização
   +--> validação
   +--> objetos Kubernetes

Para quem vem de mainframe, pense nisso como uma grande interface controlada entre operadores, automações e o sistema.


🧠 Capítulo 7 — etcd: a memória do navio

O Kubernetes precisa guardar informações fundamentais sobre seu estado.

Para isso existe o etcd.

É um armazenamento distribuído chave-valor.

Ele contém dados críticos relacionados aos objetos e estado do cluster.

Imagine o diário de bordo:

Deployment A deseja 3 réplicas
Service B existe
ConfigMap C contém configuração
Namespace D está configurado

Se estivéssemos numa série submarina antiga, alguém inevitavelmente entraria correndo:

— CAPITÃO! O COMPUTADOR CENTRAL PERDEU A MEMÓRIA!

E todos fariam cara dramática.

No mundo Kubernetes, proteger o estado do etcd é assunto sério.

Backup e recuperação são fundamentais principalmente quando você administra o Control Plane por conta própria.


⚙️ Capítulo 8 — Scheduler: JES2 encontrou Poseidon

Um Pod precisa executar em algum Node.

Mas onde?

Suponha:

Node A
Node B
Node C
Node D

O Pod precisa de:

CPU: 500m
RAM: 512Mi

Talvez:

Node A -> sem recurso
Node B -> possível
Node C -> restrição de afinidade
Node D -> possível

O scheduler analisa as possibilidades e seleciona um Node adequado.

O COBOLzeiro arregala os olhos.

— Temos um componente escolhendo onde colocar workload considerando recursos?

Sim.

— Eu conheço essa música.

Calma.

Não diga:

Kubernetes Scheduler = JES2

Isso estaria tecnicamente errado.

Mas como mapa mental, existe uma familiaridade interessante.

Schedulers são uma obsessão antiga da computação.

Quando temos muitos trabalhos e recursos limitados, alguém precisa decidir:

quem
onde
quando
com quanto

Muda a arquitetura.

A pergunta permanece.


🫧 Capítulo 9 — Pod não é container

Agora encontramos uma criatura que confunde praticamente todo iniciante:

POD

Kubernetes não trabalha primariamente com containers isolados.

Sua menor unidade de execução e scheduling é normalmente o Pod.

Um Pod pode conter:

Pod
 |
 +---- Container A

ou:

Pod
 |
 +---- Container principal
 |
 +---- Container auxiliar

Os containers dentro de um Pod estão fortemente relacionados e compartilham certas características, particularmente contexto de rede.

Uma analogia razoável seria:

Pod = cápsula operacional
Container = ocupante da cápsula

Não confunda isso com host.

O Pod não é simplesmente uma VM.

Ele é uma abstração do Kubernetes.


🐙 Easter egg — o nome Kubernetes

“Kubernetes” vem do grego e está relacionado à ideia de:

timoneiro, piloto, navegador.

Da mesma raiz linguística surgiram palavras relacionadas a governo e cibernética.

Ou seja, aquele logo com um leme não foi escolhido por acaso.

☸

O símbolo do Kubernetes é literalmente um timão naval.

Para nosso submarino, portanto, não poderíamos ter escolhido tema melhor.


🚢 Capítulo 10 — Não crie Pods na unha

Você pode definir diretamente um Pod.

Mas normalmente não é isso que deseja em produção.

Imagine:

Pod A

Ele morre.

Fim.

Por isso usamos objetos controladores como:

Deployment

Você diz:

Quero 3 réplicas.

O Deployment trabalha junto com ReplicaSets para manter essa condição.

Deployment
     |
     v
ReplicaSet
     |
     +--> Pod
     +--> Pod
     +--> Pod

Se um desaparece:

3 desejados
2 existentes

O sistema tenta criar outro.


🩹 Capítulo 11 — Self-healing não é milagre

Essa capacidade é frequentemente chamada de:

self-healing.

Mas existe um perigo de marketing.

Kubernetes não conserta automaticamente seu software.

Suponha que seu container faça:

START
 |
 v
BUG
 |
 v
CRASH

O Kubernetes reinicia.

Resultado:

START
 |
 v
BUG
 |
 v
CRASH
 |
 v
RESTART
 |
 v
BUG
 |
 v
CRASH

Em algum momento você pode encontrar:

CrashLoopBackOff

Kubernetes consegue dizer:

“Esse processo deveria estar funcionando.”

Ele não consegue dizer:

“Seu programador esqueceu de inicializar WS-CONTADOR.”

O S0C7 continua sendo problema seu.

😆


🚨 Capítulo 12 — Perdemos um Node!

Agora começa o episódio dramático.

Node A desapareceu.

NODE A
  X

Pod 1
Pod 2

Silêncio na ponte.

O sonar dispara.

O Control Plane percebe que workloads deixaram de estar disponíveis.

Dependendo das condições e políticas, substitutos podem ser criados em Nodes saudáveis.

NODE B          NODE C
  |               |
Pod 3          novo Pod 1
Pod 4          novo Pod 2

Esse é um dos motivos fundamentais pelos quais Kubernetes existe.

Em vez de depender de um humano perceber às três da manhã:

“Servidor XPTO caiu.”

o sistema possui mecanismos automáticos para reagir.


📡 Capítulo 13 — Mas se Pod muda de IP, como encontro a aplicação?

Excelente pergunta.

Pods são relativamente efêmeros.

Hoje:

10.10.4.31

Amanhã:

10.10.7.88

Você não quer configurar clientes apontando diretamente para cada Pod.

É aí que entra o:

Service

Conceitualmente:

CLIENTE
   |
   v
SERVICE
   |
   +---- Pod A
   +---- Pod B
   +---- Pod C

O Service fornece uma forma estável de alcançar um conjunto de Pods.

Isso desacopla:

quem chama

de:

qual instância específica está viva neste momento

🌐 Capítulo 14 — Load balancing

O Kubernetes oferece mecanismos para distribuir tráfego entre workloads.

Mas não caia numa simplificação perigosa.

Existem várias camadas possíveis:

Internet
   |
Load Balancer externo
   |
Ingress / Gateway
   |
Service
   |
Pods

Cada ambiente pode montar essa arquitetura de forma diferente.

Cloud providers também adicionam componentes próprios.

Portanto dizer:

“Kubernetes possui load balancing”

é correto.

Mas é apenas o começo da história.


📈 Capítulo 15 — O submarino precisa acelerar

Imagine uma aplicação com:

3 Pods

De repente chega uma carga enorme.

CPU sobe.

Requests crescem.

Com mecanismos como Horizontal Pod Autoscaler, podemos aumentar o número de réplicas.

3
|
5
|
8
|
12 Pods

Quando a carga desaparece:

12
 |
 8
 |
 5
 |
 3

Esse é o conceito de autoscaling horizontal.

Mas existe uma pegadinha.

Criar mais Pods exige capacidade física ou virtual.

Se todos os Nodes estiverem cheios:

Kubernetes:
"Preciso criar mais 10 Pods."

Cluster:
"Excelente ideia."

Kubernetes:
"Onde estão os recursos?"

Cluster:
"..."

Pods podem ficar:

Pending

Por isso escalabilidade de workloads e escalabilidade da infraestrutura são problemas relacionados, mas não idênticos.


📦 Capítulo 16 — CPU e memória não aparecem por magia

Você pode declarar requests e limits.

Por exemplo:

resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"

requests ajudam o scheduler a entender o que o workload precisa.

limits estabelecem limites operacionais.

Aqui o programador COBOL familiarizado com WLM começa novamente a reconhecer um tema antigo:

recursos não são infinitos.

Todo sistema operacional sério acaba lidando com:

prioridade
capacidade
contenção
limites
planejamento

❤️ Capítulo 17 — Liveness, Readiness e Startup

Esses três conceitos merecem atenção.

Liveness Probe

Pergunta aproximadamente:

“Essa aplicação continua saudável?”

Se falhar repetidamente, pode levar ao reinício do container.

Readiness Probe

Pergunta:

“Está pronta para receber tráfego?”

Talvez a aplicação esteja viva.

Mas:

banco ainda conectando
cache carregando
dependência inicializando

Então:

VIVO? SIM
PRONTO? NÃO

É perfeitamente possível.

Startup Probe

É útil para aplicações que demoram para inicializar.

Durante o startup, você não quer que uma liveness agressiva mate a aplicação antes de ela terminar de subir.


🩺 Diagnóstico submarino

Imagine:

Paciente respirando?

Liveness.

Paciente consegue trabalhar?

Readiness.

Paciente acabou de acordar da anestesia?

Startup.

É simplificado, mas ajuda muito.


🔐 Capítulo 18 — ConfigMap e Secret

Imagine uma configuração:

API_URL
LOG_LEVEL
TIMEOUT

Você não precisa colocar tudo dentro da imagem.

Kubernetes oferece:

ConfigMap

para configurações.

Para dados sensíveis existe:

Secret

Mas atenção.

A palavra “Secret” não significa automaticamente:

Ninguém jamais conseguirá ler isso.

Segurança real exige arquitetura.

Inclui coisas como:

RBAC
criptografia
controle de acesso
secret managers
gestão de chaves
auditoria
políticas

Nunca confunda nome de objeto com garantia criptográfica.


🗄️ Capítulo 19 — E os dados?

Pods podem desaparecer.

Mas seu banco de dados talvez não possa.

Imagine:

Pod
 |
 X

Tudo que estava exclusivamente no filesystem efêmero daquele Pod pode sumir junto com ele.

Para persistência entram conceitos como:

PersistentVolume
PersistentVolumeClaim
StorageClass
CSI

Uma visão extremamente simplificada:

POD
 |
PVC
 |
PV
 |
STORAGE

A aplicação pode morrer.

Outra pode nascer.

Os dados continuam.

Pelo menos essa é a intenção.

Storage em Kubernetes é um dos pontos onde o mergulho deixa de ser piscina infantil e vira Fossa das Marianas.


📊 Capítulo 20 — Kubernetes não é Prometheus

Outro mito:

“Kubernetes já monitora tudo.”

Não exatamente.

Kubernetes possui informações operacionais fundamentais.

Mas observabilidade completa geralmente envolve ecossistemas adicionais.

Podemos querer:

Métricas
Logs
Traces
Alertas
Dashboards

É comum encontrar tecnologias como:

Prometheus
Grafana
OpenTelemetry

e soluções comerciais.

Lembre:

Kubernetes administra workloads.

Isso não significa:

Kubernetes substitui sua estratégia inteira de observabilidade.

🧾 Capítulo 21 — YAML: o JCL que bebeu chá de cogumelo?

O primeiro contato do COBOLzeiro com Kubernetes geralmente é:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cafe
spec:
  replicas: 3

Ele olha aquilo.

Olha novamente.

— Então é isso?

Não.

YAML é apenas uma forma comum de representar objetos que serão enviados à API Kubernetes.

O fluxo real é mais interessante:

YAML
 |
 v
API SERVER
 |
 v
OBJETO
 |
 v
ESTADO DESEJADO
 |
 v
CONTROLLERS
 |
 v
ESTADO REAL

Portanto Kubernetes não é YAML.

Assim como:

z/OS não é JCL

apesar de alguém poder conhecer z/OS inicialmente através de JCL.


🧠 Capítulo 22 — JCL e Kubernetes: parentes distantes

Existe uma analogia interessante.

Em JCL declaramos:

programa
datasets
parâmetros
condições
recursos

E entregamos o job.

No Kubernetes declaramos:

imagem
réplicas
volumes
rede
recursos
configuração

E entregamos o objeto ao cluster.

Mas existe uma diferença essencial.

O JCL tradicional está fortemente ligado a uma execução.

Kubernetes frequentemente declara:

“Quero que isso continue verdadeiro.”

Exemplo:

replicas = 5

Isso não significa:

“Crie cinco processos uma vez.”

Significa aproximadamente:

“Mantenha cinco instâncias enquanto essa configuração permanecer.”

Essa persistência do estado desejado é fundamental.


🧙 Capítulo 23 — WLM aparece no periscópio

Agora o COBOLzeiro veterano começa a sorrir.

O WLM no z/OS lida com questões como:

objetivos
prioridades
recursos
classes de serviço
competição entre workloads

Kubernetes possui mecanismos diferentes, mas também precisa responder:

Onde executar?
Quanto recurso reservar?
Quem pode consumir?
Qual workload tem prioridade?
O que acontece quando falta capacidade?

Repita comigo:

Kubernetes NÃO é WLM.

Mas ambos pertencem a uma longa tradição de sistemas tentando administrar cargas computacionais automaticamente.

O problema é antigo.

As soluções mudam.


🧩 Capítulo 24 — Kubernetes e COBOL podem conviver

Agora chegamos a um ponto importantíssimo.

Quando alguém diz:

“Estamos modernizando com Kubernetes.”

alguns COBOLzeiros imaginam imediatamente:

COBOL
 |
 v
LIXO

Não.

Uma arquitetura perfeitamente possível seria:

                Internet
                   |
                   v
            Kubernetes
             /    |    \
          API   API    API
            \    |    /
             API Gateway
                   |
                   v
             z/OS Connect
                   |
          +--------+--------+
          |                 |
        CICS               IMS
          |                 |
        COBOL             COBOL
          |
         Db2

Kubernetes pode hospedar:

APIs
microservices
frontends
integrações
processamento auxiliar
componentes de IA

enquanto o core transacional continua no mainframe.

Modernização não é sinônimo de:

jogar COBOL fora.

Muitas vezes significa:

envolver o legado com novas interfaces.

🏛️ Capítulo 25 — O mainframe não precisa morar dentro do Kubernetes

Isso parece óbvio.

Mas precisa ser dito.

Existe uma tendência na indústria de imaginar que qualquer tecnologia nova precisa substituir a anterior.

Não funciona assim.

Você pode ter:

IBM Z
 +
Kubernetes
 +
cloud
 +
SaaS
 +
APIs

Tudo coexistindo.

Empresas grandes são fósseis vivos tecnológicos.

Possuem camadas acumuladas durante décadas.

E isso não é necessariamente ruim.

O problema não é idade.

O problema é incapacidade de evolução.


💸 Capítulo 26 — Kubernetes custa dinheiro

Agora chega o financeiro à ponte do submarino.

— Quanto custa?

O arquiteto responde:

— O cluster custa X.

Errado.

O cluster custa:

compute
storage
network
load balancers

Mas o Kubernetes organizacional custa também:

treinamento
SRE
DevOps
observabilidade
CI/CD
segurança
networking
upgrades
backup
disaster recovery
GitOps
governança
troubleshooting

Uma pequena empresa pode descobrir que transformou:

5 aplicações

num ambiente que exige:

especialista Kubernetes
especialista cloud
especialista networking
especialista segurança
especialista observabilidade

Parabéns.

Você resolveu um problema que talvez não tivesse.


🛶 Capítulo 27 — Quando NÃO usar Kubernetes

Suponha:

Aplicações: 3
Equipe: 4 pessoas
Deploy: mensal
Tráfego: previsível
Disponibilidade: normal

Você realmente precisa de Kubernetes?

Talvez não.

Às vezes:

VM
Docker Compose
serviço gerenciado
PaaS
container service

resolvem.

Tecnologia boa é a tecnologia proporcional ao problema.

Usar Kubernetes para tudo é como comprar o USS Seaview para atravessar uma piscina.

Funciona.

Mas talvez uma boia bastasse.


🚢 Capítulo 28 — Quando Kubernetes começa a fazer sentido

Kubernetes tende a ficar atraente quando começam a aparecer vários fatores simultaneamente:

  • grande quantidade de serviços;

  • necessidade de automação operacional;

  • múltiplas equipes;

  • alta disponibilidade;

  • atualizações frequentes;

  • escalabilidade dinâmica;

  • infraestrutura heterogênea;

  • necessidade de padronização;

  • automação via API;

  • ambientes híbridos;

  • práticas DevOps e GitOps maduras.

A palavra fundamental é:

complexidade.

Kubernetes não elimina complexidade.

Ele tenta organizar complexidade inevitável.

Essa diferença é enorme.


⚓ Capítulo 29 — Kubernetes gerenciado

Se administrar tudo manualmente parece assustador, existem serviços gerenciados.

Exemplos conhecidos incluem:

Amazon EKS
Azure AKS
Google GKE

O provedor assume parte da operação.

Isso pode reduzir bastante o peso do Control Plane.

Mas não elimina responsabilidades.

Você ainda precisa entender:

workloads
rede
segurança
IAM
RBAC
storage
observabilidade
custos
deployments
capacity planning

Managed Kubernetes não significa:

“Agora ninguém precisa saber Kubernetes.”

Significa:

“Algumas partes dolorosas possuem outro responsável.”


🐳 Capítulo 30 — containerd e o fantasma do Docker

Existe ainda uma curiosidade que confunde iniciantes.

Antigamente era comum associar diretamente Kubernetes ao Docker runtime.

Depois Kubernetes removeu o componente conhecido como dockershim.

Hoje runtimes compatíveis com CRI, especialmente:

containerd
CRI-O

são comuns.

Mas isso não significa que imagens criadas com Docker deixaram de funcionar.

A distinção importante é:

Docker como ferramenta/ecossistema de construção

≠

Docker Engine obrigatório dentro do Kubernetes

Esse detalhe costuma render algumas discussões de bar extremamente desnecessárias.


👻 Easter egg — Pods são descartáveis, dados não

Uma filosofia cloud-native bastante importante diz:

Não se apaixone pela instância.

Se um Pod morre:

crie outro.

Isso é culturalmente diferente de ambientes tradicionais nos quais um servidor pode receber nome, personalidade e quase CPF.

Quem trabalhou em CPD antigo conhece:

SRVPROD01

quinze anos depois:

NÃO DESLIGAR.
NINGUÉM SABE O QUE TEM AQUI.

Kubernetes tenta incentivar outro modelo:

instâncias são substituíveis
estado importante fica fora delas

É uma mudança arquitetural gigantesca.


🔄 Capítulo 31 — Rolling Updates

Imagine que temos:

Versão 1

rodando em cinco Pods.

Queremos:

Versão 2

Não precisamos necessariamente destruir tudo simultaneamente.

Kubernetes pode substituir gradualmente:

V1 V1 V1 V1 V1

V2 V1 V1 V1 V1

V2 V2 V1 V1 V1

V2 V2 V2 V1 V1

V2 V2 V2 V2 V1

V2 V2 V2 V2 V2

Esse conceito é associado a rolling updates.

Se algo der errado, estratégias de rollback podem ajudar.

Para quem viveu décadas com janelas de mudança gigantescas:

SÁBADO
23:00
TODO MUNDO NA SALA
PIZZA
BACKOUT PLAN IMPRESSO

isso parece quase ficção científica.

Embora, sejamos sinceros:

em algumas empresas o Kubernetes apenas adicionou YAML à mesma pizza de sábado.


🔍 Capítulo 32 — kubectl: o periscópio

Uma das ferramentas mais usadas para interagir com Kubernetes é:

kubectl

Alguns comandos básicos:

kubectl get pods

Lista Pods.

kubectl get nodes

Lista Nodes.

kubectl describe pod nome

Mostra informações detalhadas.

kubectl logs nome-do-pod

Mostra logs.

kubectl get deployments

Lista Deployments.

Para o COBOLzeiro:

kubectl

eventualmente começa a assumir um papel psicológico semelhante ao:

SDSF

Não tecnicamente.

Mas emocionalmente.

Quando algo quebra:

COBOLzeiro:
SDSF.

Kuberneteszeiro:
kubectl.

😁


🧪 Capítulo 33 — Primeiro laboratório mental

Vamos montar uma aplicação imaginária.

Nome:

cafe-api

Queremos três réplicas.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cafe-api
spec:
  replicas: 3

A intenção é:

Deployment
     |
     +--> Pod 1
     +--> Pod 2
     +--> Pod 3

Agora um Pod quebra.

Estado real:

Pod 1
Pod 2

Kubernetes observa.

Desejado = 3
Atual = 2

Control loop:

Criar outro.

Nasce:

Pod 4

Não precisamos recuperar exatamente o velho Pod 3.

Precisamos restaurar:

quantidade desejada = 3

Essa distinção é maravilhosa.

O sistema não possui sentimentalismo.


🧠 Capítulo 34 — Pets versus cattle

Existe uma velha metáfora de infraestrutura:

Pets
versus
Cattle

Pets recebem nomes.

Você cuida individualmente.

Cattle são tratados como grupo.

No modelo tradicional:

Servidor Hercules

cai.

Todos correm para recuperar Hercules.

No modelo cloud-native:

instância 27

cai.

O sistema cria:

instância 42

O objetivo não é preservar o indivíduo.

É preservar o serviço.

Essa ideia aparece fortemente no Kubernetes.


🧯 Capítulo 35 — Kubernetes não elimina incidentes

Outra ilusão perigosa:

“Com Kubernetes teremos alta disponibilidade e não teremos mais problemas.”

Teremos.

Só mudaremos o catálogo.

Antes:

servidor caiu

Agora:

Pod Pending
CrashLoopBackOff
ImagePullBackOff
OOMKilled
PVC Pending
DNS quebrado
Ingress errado
RBAC negando acesso
certificate expired
node pressure
CNI quebrado

Toda tecnologia que resolve dez problemas geralmente introduz sete completamente novos.

O segredo da engenharia não é eliminar problemas.

É trocar problemas ruins por problemas mais administráveis.


🌊 Capítulo 36 — A grande lição da viagem

Chegamos ao fundo do oceano.

O COBOLzeiro olha pela escotilha.

Ao longe vemos:

Pods
Services
Deployments
Nodes
Volumes
Controllers

nadando tranquilamente pelo cluster.

Depois de toda essa viagem, podemos finalmente definir Kubernetes com alguma precisão.

Não diga apenas:

“Kubernetes é uma ferramenta para containers.”

Melhor:

Kubernetes é uma plataforma de orquestração baseada em APIs e control loops que permite declarar como workloads containerizados deveriam estar funcionando e trabalha continuamente para aproximar o estado real do cluster desse estado desejado.

Essa definição explica quase tudo.


☕ O mapa do COBOLzeiro

Se você está começando, memorize esta sequência:

1. APPLICATION
       |
       v
2. IMAGE
       |
       v
3. CONTAINER
       |
       v
4. POD
       |
       v
5. DEPLOYMENT
       |
       v
6. SERVICE
       |
       v
7. NODE
       |
       v
8. CLUSTER

Depois adicione:

ConfigMap
Secret
Volume
Ingress
HPA
RBAC
Observabilidade

Não tente aprender tudo simultaneamente.


🧭 Roteiro de estudo Bellacosa

Para um COBOLzeiro iniciante eu seguiria esta ordem.

Passo 1 — Aprenda container

Entenda:

imagem
container
registry
Dockerfile
runtime

Passo 2 — Aprenda Pod

Descubra por que Kubernetes trabalha com Pods.

Passo 3 — Deployment

Entenda:

replicas
ReplicaSet
rolling update
self-healing

Passo 4 — Service

Aprenda descoberta e acesso aos Pods.

Passo 5 — Configuração

Estude:

ConfigMap
Secret

Passo 6 — Storage

Depois:

PV
PVC
StorageClass

Passo 7 — Probes

Estude:

startup
readiness
liveness

Passo 8 — Scheduling

Entre em:

requests
limits
affinity
taints
tolerations

Passo 9 — Segurança

Não pule:

RBAC
ServiceAccount
NetworkPolicy
Secrets

Passo 10 — Observabilidade

Finalmente:

logs
metrics
traces
alerts

Só depois disso mergulhe alegremente no abismo chamado:

Helm
Operators
GitOps
Service Mesh
CRDs
Admission Controllers

Porque depois desse ponto o submarino já está a 11 mil metros.


🧙‍♂️ Dica do velho operador

Quando um Kubernetes parecer complicado demais, não tente memorizar todos os nomes.

Faça sempre cinco perguntas:

1. O que deveria existir?

2. O que existe realmente?

3. Quem observa essa diferença?

4. Quem deveria corrigi-la?

5. Por que não conseguiu?

Essa técnica resolve uma quantidade surpreendente de investigações.

E curiosamente é quase a mesma forma de pensar usada há décadas para diagnosticar ambientes de produção.


🐙 O monstro final: complexidade

No último episódio de nossa expedição aparece diante do submarino uma criatura colossal.

Não é Docker.

Não é YAML.

Não é networking.

É:

COMPLEXIDADE

Kubernetes nasceu porque sistemas distribuídos modernos ficaram complexos demais para administração manual.

Mas existe um paradoxo.

Para controlar complexidade, Kubernetes introduz sua própria complexidade.

Então a decisão madura nunca é:

Kubernetes é bom?

A pergunta correta é:

“O problema que tenho justifica a complexidade operacional que Kubernetes introduzirá?”

Se sim, ele pode ser extraordinário.

Se não, talvez você esteja usando um submarino nuclear para entregar pizza.


🌅 Epílogo — Emergindo do cluster

O USS Kubernetes finalmente retorna à superfície.

O jovem COBOLzeiro sai pela escotilha.

No início da viagem ele conhecia:

JCL
COBOL
CICS
Db2
JES2

Agora carrega um caderno com:

Container
Pod
Deployment
Service
Node
Cluster
Control Plane
Scheduler
etcd
ConfigMap
Secret
PVC
HPA
Probe

Ele olha para o arquiteto.

— Acho que entendi Kubernetes.

— Excelente!

— É um sistema enorme que recebe uma descrição do estado que queremos, observa continuamente o estado que existe e tenta corrigir as diferenças automaticamente.

O arquiteto sorri.

— Perfeito.

O COBOLzeiro toma o último gole do café.

— Então passamos cinquenta anos distribuindo computação para depois construir um negócio gigantesco para coordenar tudo novamente.

Silêncio na sala.

O sysprog veterano, sentado no canto, finalmente levanta os olhos do terminal.

— Eu estava esperando alguém perceber.

☕

E talvez esse seja o maior easter egg de toda a história.

A tecnologia muda.

Os nomes mudam.

Os logos ficam mais bonitos.

O YAML substitui cartões perfurados.

O container substitui parte da configuração artesanal.

O cluster substitui fileiras de servidores administrados individualmente.

Mas a pergunta original continua ecoando pelos corredores do CPD, pelo datacenter, pela cloud e agora pelas profundezas do nosso submarino:

“Temos um monte de programas, recursos limitados, máquinas que quebram e usuários que não querem saber de nada disso. Quem vai administrar essa porra toda?”

No mainframe, construímos respostas.

No Unix, construímos outras.

Na virtualização, outras.

Na cloud, outras.

E no universo containerizado, uma das grandes respostas recebeu um nome grego, um timão como logotipo e a missão quase naval de manter milhares de pequenas embarcações seguindo o curso declarado:

Kubernetes.

Ou, para os íntimos do Bellacosa Mainframe:

//KUBEJOB JOB ...
//STEP01 EXEC PGM=KEEP-EVERYTHING-ALIVE
//SYSOUT DD SYSOUT=*
//COFFEE DD DISP=SHR,DSN=BELLACOSA.CAFE.FORTE

RC=0000.

Esperamos. ☕☸️🌊

terça-feira, 3 de janeiro de 2023

🕵️‍♂️ Tintin na Terra dos Containers — O Mistério de Docker & Kubernetes

 

Bellacosa Mainframe e os containers dockers e kubernetes

☕ Um Café no Bellacosa Mainframe

🕵️‍♂️ Tintin na Terra dos Containers — O Mistério de Docker & Kubernetes

Uma investigação entre imagens, containers, Pods, Deployments e clusters — porque até Tintin descobriria que colocar uma aplicação em produção é muito mais complicado do que embarcar no Sirius.

Caso nº 03:17 — Arquivo confidencial do Bellacosa Mainframe
Destino: Produção
Suspeitos: Docker, Kubernetes e algumas dezenas de arquivos YAML
Situação: aparentemente simples. Portanto, extremamente suspeita.

Tintin estava acostumado a situações complicadas.

Já havia enfrentado falsificadores, contrabandistas, sociedades secretas, ditadores, traficantes, cientistas excêntricos e até viajado à Lua.

Mas naquela manhã encontrou algo muito mais perigoso.

Um desenvolvedor havia pronunciado a frase:

— Na minha máquina funciona.

Milou levantou as orelhas.

Capitão Haddock largou o café.

Professor Girassol continuou mexendo em alguma coisa que provavelmente explodiria antes do almoço.

Tintin abriu seu pequeno caderno.

Novo caso.

Precisávamos descobrir como levar uma aplicação desde o notebook de um programador até produção sem depender da configuração particular daquela máquina.

E nossa investigação começaria com uma criatura chamada container.



📰 1. O estranho caso da aplicação que funcionava ontem

Imagine que nosso jovem programador COBOL decidiu aprender Python e criou uma pequena API usando FastAPI.

No computador dele tudo funciona.

Python instalado.

Bibliotecas instaladas.

Variáveis configuradas.

Banco de dados acessível.

Portas abertas.

Versões corretas.

Ele entrega o programa para Haddock.

Haddock tenta executá-lo.

Nada funciona.

— MIL MILHÕES DE MILHARES DE BIBLIOTECAS INCOMPATÍVEIS!

Eis um problema muito antigo da computação.

O programa não existe sozinho.

Ele depende de um ambiente.

No universo mainframe conhecemos isso muito bem. Um programa COBOL pode depender de determinada versão de runtime, Db2, CICS, arquivos, configurações, parâmetros, bibliotecas e permissões.

No mundo distribuído ocorre exatamente o mesmo fenômeno.

Docker ataca justamente esse problema.

Em vez de entregar apenas:

minha-aplicacao.py

tentamos empacotar:

APLICAÇÃO
   +
RUNTIME
   +
BIBLIOTECAS
   +
DEPENDÊNCIAS
   +
CONFIGURAÇÃO NECESSÁRIA

dentro de uma unidade reproduzível.

Tintin anotaria:

Pista nº 1: não transporte apenas o programa. Transporte uma descrição reproduzível de seu ambiente.



📦 2. Surge a primeira testemunha: Docker

Docker popularizou uma maneira extremamente prática de construir, distribuir e executar aplicações em containers.

Mas precisamos separar duas palavras que frequentemente aparecem misturadas:

IMAGE e CONTAINER.

Uma imagem é o artefato preparado.

Um container é uma instância executando aquela imagem.

Podemos imaginar:

Dockerfile
    │
    ▼
docker build
    │
    ▼
┌─────────────────┐
│      IMAGE      │
│ app:v1          │
└─────────────────┘
       │
       │ docker run
       ▼
┌─────────────────┐
│    CONTAINER    │
│ aplicação viva  │
└─────────────────┘

Para quem vem do mainframe, existe uma analogia didática interessante.

Imagem lembra um artefato executável versionado. Container lembra uma execução desse artefato.

Não interprete isso literalmente como LOAD MODULE = IMAGE, porque arquiteturalmente são coisas diferentes.

Mas como ponte mental funciona muito bem.

O detalhe importante é:

uma única imagem pode originar muitos containers.

Temos:

IMAGE: bellacard-api:v7

        │
        ├── Container A
        ├── Container B
        ├── Container C
        └── Container D

Agora Tintin já tinha uma pista importante.

O artefato poderia ser reproduzido.


🧾 3. O bilhete encontrado no bolso do suspeito: Dockerfile

Toda boa investigação tem um documento comprometedor.

No nosso caso:

FROM python:3.13-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["python", "app.py"]

Esse arquivo é o Dockerfile.

Ele descreve como construir nossa imagem.

Tintin examina cada linha com a lupa.

FROM determina a imagem-base.

WORKDIR estabelece o diretório de trabalho.

COPY coloca arquivos dentro da imagem.

RUN executa comandos durante sua construção.

ENV pode definir variáveis de ambiente.

CMD estabelece o comando normalmente executado quando o container começa.

E então aparece:

EXPOSE 8000

Haddock imediatamente conclui:

— Então a porta 8000 está publicada!

Não.

EXPOSE não publica automaticamente uma porta no host.

É informação sobre a porta esperada pela aplicação. A publicação efetiva pode ser feita, por exemplo:

docker run -p 8080:8000 bellacard-api

Temos então:

HOST                  CONTAINER

localhost:8080  ───►  :8000

Essa diferença pequena é exatamente o tipo de detalhe que transforma uma explicação introdutória em conhecimento operacional.



🌐 4. O mistério das portas

Tintin agora encontra três containers.

frontend
backend
database

Cada um possui seu próprio contexto de rede.

E aqui surge outra mudança mental importante.

Não devemos construir sistemas distribuídos supondo que cada container terá eternamente determinado endereço IP.

Containers aparecem.

Containers desaparecem.

Podem ser recriados.

É muito melhor trabalhar com nomes e mecanismos de descoberta de serviços.

Em um ambiente Docker Compose poderíamos ter:

frontend
    │
    ▼
backend:8000
    │
    ▼
postgres:5432

Isso começa a revelar algo importante.

Containerização não significa simplesmente:

“pegamos uma VM e diminuímos.”

O modelo operacional é diferente.

Containers tendem a ser descartáveis.

A aplicação precisa ser projetada levando isso em consideração.



💾 5. Milou encontra o banco de dados

Milou começa a latir para um container.

Tintin abre o container.

Encontra PostgreSQL.

Haddock reinicia a máquina.

O banco desaparece.

— BOMBARDEIOS E BACKUPS INEXISTENTES!

Tintin identifica imediatamente o problema.

Persistência.

O filesystem interno de um container não deve ser tratado ingenuamente como o lugar permanente dos dados importantes.

Precisamos separar:

COMPUTE                  DATA

container              volume/storage
 descartável            persistente

Docker oferece mecanismos como volumes e bind mounts.

Essa separação torna-se ainda mais importante quando chegarmos ao Kubernetes.

Uma aplicação pode morrer.

O Pod pode desaparecer.

O container pode ser substituído.

Mas determinados dados precisam continuar existindo.

Para quem vem de mainframe isso não deveria parecer revolucionário.

Há décadas aprendemos a separar processamento de dados persistentes.

A novidade está nas abstrações utilizadas.



🗝️ 6. O envelope secreto

Girassol encontra isto:

DB_PASSWORD=Tintin123
API_KEY=abc123

E sugere colocar tudo no GitHub.

Tintin quase derruba o café.

Variáveis de ambiente são excelentes para retirar determinadas configurações do código.

Podemos ter:

APP_ENV=production
DB_HOST=database
DB_PORT=5432

Arquivos .env também são muito convenientes durante desenvolvimento.

Mas existe uma armadilha:

tirar uma senha do código não significa que ela automaticamente ficou segura.

Um .env contendo credenciais continua sendo um arquivo contendo credenciais.

Precisa ser protegido.

Não deve simplesmente parar no repositório.

E esse problema reaparecerá no Kubernetes com os Secrets.


🧩 7. O caso ficou grande demais: Docker Compose

Tintin agora possui cinco containers:

frontend
API
agent
database
redis

Executá-los manualmente começa a parecer uma operação militar.

Então entra Docker Compose.

Podemos declarar um conjunto de serviços em um arquivo compose.yaml.

Algo conceitualmente semelhante a:

services:

  api:
    build: .
    ports:
      - "8000:8000"

  database:
    image: postgres

  redis:
    image: redis

Agora descrevemos uma pequena aplicação multi-container declarativamente.

Essa é uma das grandes virtudes do Compose.

Em vez de Haddock precisar decorar quinze comandos, declaramos como o ambiente deve ser.

Um detalhe merece atualização nos materiais mais antigos: no Compose moderno, aquele tradicional:

version: "3.8"

não é mais necessário. A documentação do Docker classifica a propriedade superior version como obsoleta e meramente informativa; o Compose moderno trabalha com a Compose Specification. (Docker Documentation)

É um belo exemplo de por que bons cursos técnicos precisam ser revisados continuamente.


🚢 8. Finalmente embarcamos a imagem

Construímos nossa aplicação:

docker build -t bellacard:v1 .

Temos uma imagem local.

Mas queremos executá-la em outro lugar.

Entram os container registries.

O fluxo conceitual torna-se:

SOURCE CODE
     │
     ▼
DOCKERFILE
     │
     ▼
BUILD
     │
     ▼
IMAGE
     │
     ▼
REGISTRY
     │
     ▼
PULL
     │
     ▼
EXECUTION

É aqui que começa uma ideia extremamente poderosa:

o artefato produzido pelo pipeline deve ser exatamente aquilo que promovemos entre ambientes.

Não queremos recompilar misteriosamente produção de maneira diferente de homologação.

Queremos artefatos versionados, rastreáveis e reproduzíveis.

O velho programador mainframe sentado no fundo da sala provavelmente começa a sorrir.

Ele já ouviu essa música antes.


🌊 9. De repente aparecem 500 containers

E aqui nossa aventura muda completamente.

Docker resolveu muito bem vários problemas relacionados a construção e execução de containers.

Mas suponha que nossa aplicação tenha:

300 containers
40 servidores
12 serviços
6 versões
3 ambientes
milhares de requisições

Quem decide onde cada workload executará?

Quem percebe que um deles morreu?

Quem cria outro?

Quem mantém determinada quantidade de réplicas?

Quem distribui tráfego?

Quem atualiza gradualmente uma versão?

Quem associa armazenamento?

Quem controla configuração?

Quem escala a aplicação?

Tintin escreve uma única palavra no caderno:

KUBERNETES


☸️ 10. Entramos no território Kubernetes

Kubernetes não é simplesmente um “Docker maior”.

Essa distinção é fundamental.

Ele é uma plataforma de orquestração de workloads containerizados.

Seu grande truque filosófico está no conceito de estado desejado.

Nós declaramos algo como:

QUERO 3 RÉPLICAS DESTA APLICAÇÃO.

O sistema observa:

DESEJADO = 3
ATUAL = 3

Tudo certo.

Um Pod desaparece:

DESEJADO = 3
ATUAL = 2

Existe divergência.

Os controladores trabalham para retornar ao estado desejado:

DESEJADO = 3
ATUAL = 3

Isso é extraordinariamente importante.

O operador deixa de pensar apenas:

“execute este comando.”

e passa também a pensar:

“este é o estado que quero manter.”

Quem conhece automação operacional, WLM e políticas em ambientes corporativos provavelmente já começou a enxergar pontes conceituais.


🏰 11. Tintin entra no cluster

Um cluster Kubernetes possui componentes de controle e nós onde workloads são executados.

De forma simplificada:

              KUBERNETES CLUSTER

        ┌─────────────────────────┐
        │      CONTROL PLANE      │
        │                         │
        │ API Server              │
        │ Scheduler               │
        │ Controller Manager      │
        │ etcd                    │
        └────────────┬────────────┘
                     │
          ───────────┼───────────
                     │
       ┌─────────────┴─────────────┐

   WORKER NODE                 WORKER NODE
   ┌──────────────┐           ┌──────────────┐
   │ kubelet      │           │ kubelet      │
   │ runtime      │           │ runtime      │
   │              │           │              │
   │ Pod Pod Pod  │           │ Pod Pod Pod  │
   └──────────────┘           └──────────────┘

O API Server é uma peça central da interface de controle.

O scheduler ajuda a decidir onde Pods serão colocados.

Os controllers observam o estado e trabalham para reconciliá-lo.

O etcd mantém dados importantes do estado do cluster.

E nos workers temos, entre outros componentes, o kubelet e um runtime de containers.


🐳 12. Haddock encontra uma pista desatualizada

Em algum velho mapa Tintin encontra:

Kubernetes → Docker

— Caso encerrado! — grita Haddock.

Não tão depressa.

Aqui existe uma atualização histórica importantíssima.

Kubernetes removeu seu dockershim integrado a partir da versão 1.24. Kubernetes moderno trabalha através da Container Runtime Interface — CRI, com runtimes compatíveis, como containerd e CRI-O; Docker Engine ainda pode ser integrado por um adaptador como cri-dockerd. (Kubernetes)

Isso não significa que imagens construídas com Docker deixaram de funcionar no Kubernetes. A própria documentação explica que usar Docker para construir imagens não cria uma dependência de Docker como runtime do cluster. (Kubernetes)

Portanto nosso mapa mental moderno é melhor representado assim:

              KUBERNETES

                 kubelet
                    │
                    ▼
                   CRI
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
     containerd             CRI-O

E Docker continua extremamente útil no workflow de desenvolvimento e construção de imagens.

Pista nº 12: Docker não morreu no Kubernetes. Mudou a relação arquitetural entre eles.


📦 13. O menor quarto do hotel: Pod

Chegamos agora a uma das palavras mais importantes de Kubernetes:

Pod.

Pod é a menor unidade implantável de computação que Kubernetes gerencia.

Normalmente encontramos um container principal dentro dele, embora um Pod possa conter mais de um container quando esses processos precisam compartilhar estreitamente recursos e ciclo de vida.

Podemos imaginar:

POD
┌────────────────────────────┐
│                            │
│   Application Container    │
│                            │
│   shared networking        │
│   shared volumes/context   │
│                            │
└────────────────────────────┘

Mas existe algo fundamental:

não se apaixone pelo Pod.

Pods são substituíveis.

Podem desaparecer e serem recriados.

E por isso normalmente não administramos aplicações complexas criando Pods soltos manualmente.

Entra outra testemunha.


🧬 14. Deployment → ReplicaSet → Pods

Para uma aplicação típica, podemos declarar um Deployment.

Por exemplo:

replicas: 3

Conceitualmente:

Deployment
     │
     ▼
ReplicaSet
     │
 ┌───┼───┐
 ▼   ▼   ▼
Pod Pod Pod

Se um desaparece:

Pod ✖

o sistema trabalha para restaurar o estado desejado.

Isso também permite realizar rolling updates.

Em vez de:

VERSÃO 1
   ↓
DESLIGA TUDO
   ↓
VERSÃO 2

podemos substituir progressivamente instâncias antigas por novas.

E, quando necessário, trabalhar com mecanismos de rollback.

Haddock começa a gostar da história.

Produção sem uma gigantesca janela de “desliga tudo e reza” realmente parece civilização.


📞 15. Mas como encontramos esses Pods?

Temos outro problema.

Pods são efêmeros.

Se ficarmos distribuindo seus endereços diretamente, criamos dependências frágeis.

Entra o objeto Service.

Imagine:

CLIENTE
   │
   ▼
SERVICE
   │
 ┌─┼───────────┐
 ▼ ▼           ▼
POD A        POD B        POD C

O Service fornece uma abstração estável para alcançar determinado conjunto de Pods.

Essa é uma mudança mental importantíssima:

não procure indivíduos; procure o serviço.

Para um programador mainframe acostumado com um endpoint lógico de uma aplicação transacional, a ideia começa a soar curiosamente familiar.


🗺️ 16. ConfigMap e o documento que não deveria conter a senha

Nossa aplicação precisa saber:

LOG_LEVEL=INFO
LANGUAGE=pt_BR
FEATURE_X=true

Esses valores podem estar em um ConfigMap.

Mas temos também:

PASSWORD
TOKEN
API_KEY
CERTIFICATE

Aí entramos no território dos Secrets.

Contudo, há uma pegadinha digna dos irmãos Dupond e Dupont:

— Está em Base64, portanto está criptografado!

— Exatamente! E eu diria ainda mais: está criptografado porque está em Base64!

Errado duas vezes.

A documentação oficial é explícita: Base64 não é criptografia. Kubernetes Secrets podem ser armazenados sem criptografia por padrão; ambientes sérios precisam considerar controles como RBAC, restrição de acesso, criptografia em repouso e soluções apropriadas de gerenciamento de segredos. (Kubernetes)

Portanto:

ConfigMap
    ↓
configuração não confidencial

Secret
    ↓
informação confidencial
    ↓
+ controle de acesso
+ proteção apropriada
+ encryption at rest quando aplicável
+ gestão segura do ciclo de vida

Esse é um ponto que merece enorme atenção em qualquer treinamento.


🗄️ 17. O banco não pode desaparecer novamente

Voltamos ao problema de persistência.

No Kubernetes encontramos conceitos como:

PersistentVolume — PV

e

PersistentVolumeClaim — PVC

Didaticamente:

POD
 │
 ▼
PVC
 │
 ▼
PV
 │
 ▼
STORAGE

O PVC representa a solicitação de armazenamento feita pelo workload.

O PV representa o recurso persistente disponibilizado ao cluster, dependendo do modelo e provisionamento utilizado.

Em ambientes modernos existe ainda toda uma camada envolvendo StorageClass, provisionamento dinâmico e CSI.

Mas para nossa primeira investigação basta guardar:

Pod é descartável; dado importante não pode depender da sobrevivência daquele Pod.


🩺 18. Professor Girassol inventa três estetoscópios

Agora precisamos saber se a aplicação está saudável.

Kubernetes trabalha com probes que respondem perguntas diferentes.

Startup probe:

Você conseguiu iniciar?

Liveness probe:

Você continua vivo?

Readiness probe:

Você está pronto para receber tráfego?

Essas perguntas parecem semelhantes.

Não são.

Imagine uma aplicação Java que demora bastante para iniciar.

Ela pode estar viva, mas ainda não pronta para atender.

Ou uma aplicação pode continuar com processo existente, mas ter entrado em um estado do qual não consegue se recuperar adequadamente.

Misturar esses conceitos pode produzir exatamente o tipo de incidente que começa às...

03:17.

Pronto.

Easter egg encontrado. ☕😎


🚪 19. Tintin chega ao portão: Ingress

Agora temos serviços funcionando dentro do cluster.

Mas usuários precisam chegar até eles.

Tradicionalmente, Kubernetes utiliza Ingress para definir roteamento HTTP/HTTPS externo, associado a uma implementação/controlador.

Conceitualmente:

INTERNET
   │
   ▼
INGRESS
   │
   ├── /api ─────► Service API
   │                    │
   │                  Pods
   │
   └── /web ─────► Service WEB
                        │
                      Pods

Ingress continua sendo um conceito importante porque existem enormes ambientes usando-o.

Porém nosso curso de 2026 precisa colocar uma anotação vermelha no caderno de Tintin:

⚠️ EXISTE UM NOVO CAPÍTULO

O ecossistema Kubernetes está avançando para Gateway API como abordagem moderna e mais expressiva para networking. Em agosto de 2026, o projeto anunciou Gateway API v1.6, incluindo TCPRoute e UDPRoute no canal Standard. (Kubernetes)

Há inclusive tooling oficial para ajudar migrações de Ingress para Gateway API. (Kubernetes)

Portanto um curso atualizado deveria ensinar:

Ingress
   │
   ├── importantíssimo para ambientes existentes
   │
   └── API congelada para novos recursos
             │
             ▼
         Gateway API
        caminho moderno

Esse pequeno detalhe separa uma apostila histórica de uma formação preparada para os próximos anos.


📈 20. De repente chegam dez mil usuários

Haddock finalmente publica seu sistema.

Um usuário acessa.

Tudo funciona.

Dez acessam.

Tudo funciona.

Mil acessam.

Haddock começa a suar.

Dez mil acessam.

— ESCALABILIDADE DOS SETE MARES!

Kubernetes oferece mecanismos de escalabilidade, entre eles o Horizontal Pod Autoscaler — HPA.

Podemos pensar:

TRÁFEGO ↑
CPU ↑
MÉTRICA ↑

       │
       ▼

HPA observa
       │
       ▼

replicas: 3
       │
       ▼
replicas: 7

Quando a demanda diminui, a quantidade pode ser reduzida segundo a configuração e comportamento do autoscaler.

CPU e memória são excelentes exemplos introdutórios, embora arquiteturas reais possam utilizar outras métricas conforme a infraestrutura de métricas disponível.

Aqui encontramos uma ponte interessante com o universo mainframe.

Um profissional de WLM imediatamente perguntaria:

Qual é a política? Qual a prioridade? Qual o recurso disponível? Qual a métrica? Qual o objetivo de serviço?

Excelente.

Essa é exatamente a mentalidade que queremos preservar.

A tecnologia muda.

As boas perguntas sobrevivem.


🧠 21. Tintin monta o quadro completo

Depois de centenas de pistas espalhadas pela mesa, finalmente conseguimos enxergar nossa arquitetura.

                    INTERNET
                        │
                        ▼
              ┌──────────────────┐
              │ GATEWAY/INGRESS  │
              └────────┬─────────┘
                       │
                       ▼
                  ┌─────────┐
                  │ SERVICE │
                  └────┬────┘
                       │
              ┌────────┼────────┐
              ▼        ▼        ▼
             POD      POD      POD
              ▲        ▲        ▲
              └────────┼────────┘
                       │
                  ReplicaSet
                       ▲
                       │
                  Deployment
                       │
             desired replicas = 3


       CONFIGURAÇÃO                DADOS

        ConfigMap                   PVC
        Secrets                      │
                                     ▼
                                     PV
                                     │
                                     ▼
                                  STORAGE

E por trás disso existe o cluster:

CONTROL PLANE
      │
      ├── API Server
      ├── Scheduler
      ├── Controllers
      └── etcd
             │
             ▼
        WORKER NODES
             │
             ▼
           kubelet
             │
             ▼
             CRI
             │
       container runtime
             │
             ▼
            Pods

Finalmente o mistério começa a fazer sentido.


🏦 22. E onde entra o mainframe nessa aventura?

Aqui está talvez a parte mais interessante para quem está entrando nesse mundo vindo de COBOL, CICS, Db2 e z/OS.

Você não precisa apagar quarenta anos de conhecimento para aprender containers.

Muito pelo contrário.

Quem passou anos pensando em disponibilidade, processamento transacional, controle de acesso, recuperação, armazenamento, capacidade, versionamento e produção já possui uma enorme bagagem conceitual.

O segredo é não procurar equivalências literais.

Não diga:

CICS = Kubernetes
JES2 = Kubernetes
WLM = HPA
RACF = RBAC

Não são.

Mas use essas tecnologias como pontes cognitivas.

Você conhece a pergunta:

Quem pode executar isto?

Ótimo. Vamos conversar sobre RBAC.

Você conhece:

Onde os dados sobrevivem?

Excelente. Vamos falar de persistent storage.

Você pergunta:

O que acontece se esta execução morrer?

Bem-vindo ao desired state e reconciliation.

Você pergunta:

Como distribuir capacidade?

Vamos estudar scheduler, requests, limits e autoscaling.

Você pergunta:

Como colocar uma nova versão sem explodir produção?

Deployment, rolling updates, probes, observabilidade e estratégias de rollout estão esperando por você.

O veterano não chega vazio a Kubernetes.

Chega carregando décadas de perguntas extremamente úteis.


🚂 23. A viagem completa

Agora podemos reconstruir toda nossa investigação em uma única linha narrativa.

Tintin recebe:

SOURCE CODE

Cria:

Dockerfile

Produz:

IMAGE

Publica:

REGISTRY

Kubernetes referencia essa imagem.

Um:

Deployment

define o workload desejado.

Ele administra ReplicaSets que mantêm:

Pods

Esses Pods são alcançados por:

Service

Configuração chega através de mecanismos como:

ConfigMap
Secret

Dados persistentes podem utilizar:

PVC → PV → Storage

Saúde pode ser acompanhada com:

startup
readiness
liveness

Tráfego externo pode chegar através de:

Gateway API / Ingress

E escalabilidade horizontal pode envolver:

HPA

Isso já não parece uma coleção aleatória de palavras.

Parece uma arquitetura.


🔎 24. O que as excelentes ilustrações escondem

Os infográficos que iniciaram nossa investigação são ótimos para aquilo que considero a primeira passagem pelo território.

Você olha.

Reconhece os nomes.

Entende as relações.

Executa alguns comandos.

Constrói uma imagem.

Executa containers.

Cria um Compose.

Publica uma imagem.

Cria Pod.

Deployment.

Service.

PVC.

Ingress.

HPA.

Excelente.

Mas existe uma segunda passagem.

É nela que começamos a perguntar:

“Como isso funciona em produção?”

Então surgem novos personagens:

Namespaces
RBAC
ServiceAccounts
NetworkPolicy
requests/limits
taints
tolerations
affinity
anti-affinity
PodDisruptionBudget
StorageClass
CSI
Helm
Kustomize
observability
metrics
logging
tracing
GitOps
CI/CD
supply-chain security
image scanning
policy enforcement
Gateway API

E existe uma terceira passagem ainda mais interessante para nós:

Kubernetes + IBM Z + LinuxONE + OpenShift + z/OS

Aí a história deixa de ser simplesmente:

“mainframe versus cloud.”

Passa a ser:

“qual workload deve executar onde?”

Esse é um problema arquitetural muito mais adulto.


🚀 25. Bellacosa Containers 101 → 201 → 301

Eu transformaria todo esse material em uma trilha em três atos.

101 — Tintin descobre os containers: Linux essencial, Docker, imagens, containers, Dockerfile, registry, networking, volumes, environment variables, secrets e Compose.

201 — Tintin encontra Kubernetes: cluster, control plane, worker, kubectl, Pod, Deployment, ReplicaSet, Service, ConfigMap, Secret, PV/PVC, probes, requests/limits, Ingress, Gateway API e HPA.

301 — Tintin entra em produção: RBAC, namespaces, NetworkPolicy, CSI, Helm/Kustomize, observabilidade, segurança, CI/CD, GitOps, supply chain, OpenShift, LinuxONE/IBM Z e integração de workloads containerizados com serviços corporativos e z/OS.

O aluno poderia começar com:

docker run hello-world

e terminar compreendendo algo como:

Internet
   │
Gateway
   │
OpenShift/Kubernetes
   │
Containerized API
   │
MQ / REST
   │
z/OS Connect
   │
CICS
   │
COBOL
   │
Db2

Agora estamos falando a língua do Bellacosa Mainframe.


🏁 Epílogo — Tintin fecha o caderno

Depois de horas investigando containers, imagens, registries, Pods, Deployments, Services, Secrets e clusters, Capitão Haddock finalmente perguntou:

— Então Kubernetes substitui o mainframe?

Tintin fechou o caderno.

Milou olhou para Haddock.

Professor Girassol fingiu não ouvir.

E um velho programador COBOL sentado no canto começou a rir.

Porque essa era a pergunta errada.

Mainframes resolvem determinados problemas extraordinariamente bem.

Containers resolvem outros.

Kubernetes resolve um problema importantíssimo de orquestração e gerenciamento de workloads containerizados em escala.

E arquiteturas modernas podem combinar esses mundos.

A verdadeira habilidade do arquiteto não é escolher uma tecnologia para vencer uma guerra imaginária.

É saber onde cada workload pertence, como conectá-lo aos demais e como operar o conjunto com segurança, disponibilidade e previsibilidade.

Tintin guardou a lupa.

Haddock terminou o café.

Milou finalmente encontrou o container desaparecido.

E o veterano COBOL abriu um terminal e digitou:

kubectl get pods

Havia três.

bellacard-7f84c      Running
bellacard-2b17d      Running
bellacard-91a2e      Running

Deployment desejava três.

Produção tinha três.

Por alguns preciosos minutos, o universo estava em equilíbrio.

Até o telefone tocar.

Eram 03:17.

— Tintin... caiu produção.

Ele pegou o sobretudo.

— Milou, estamos diante de um novo caso.

☕ Bellacosa Mainframe — porque a tecnologia muda, mas produção continua encontrando maneiras criativas de acordar alguém de madrugada.




Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...