Translate

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

sábado, 24 de maio de 2025

Kubernetes Services Muito Além do ClusterIP

 

Bellacosa Mainframe e os kubernetes

☕ Um Café no Bellacosa Mainframe

Kubernetes Services Muito Além do ClusterIP

O Que Todo Programador COBOL Padawan Precisa Saber Sobre ClusterIP, NodePort, LoadBalancer, ExternalName, DNS, Balanceamento, Alta Disponibilidade e Como os Grandes Bancos Mantêm Milhares de Microsserviços Funcionando Sem Que Ninguém Perceba

"Um bom programador conhece um endereço IP. Um excelente engenheiro cria sistemas onde ninguém precisa conhecer endereço algum."


Introdução

Durante décadas, nós, profissionais de Mainframe, aprendemos que estabilidade era uma virtude.

No IBM Z, dificilmente pensamos no endereço físico de uma aplicação.

Quando um operador acessa uma transação CICS, ele não precisa saber em qual LPAR ela está executando.

Quando um lote conversa com o DB2, ele não sabe onde está o buffer pool.

Quando um terminal 3270 executa uma transação, ele não precisa conhecer qual região AOR irá atendê-lo.

Existe uma camada de abstração.

Essa camada protege o usuário da complexidade.

Curiosamente, quase cinquenta anos depois, o Kubernetes resolveu exatamente o mesmo problema.

Só que agora para milhares de containers distribuídos em centenas de servidores Linux.

Se você é um Programador COBOL Padawan entrando no universo DevOps, Kubernetes pode parecer um mundo completamente diferente.

Mas não é.

Na verdade, muitos dos conceitos já existem no Mainframe há décadas.

Neste artigo vamos descobrir por que os Kubernetes Services talvez sejam um dos recursos mais importantes de toda a plataforma.


Antes de falar de Services...

Precisamos entender um conceito fundamental.

Tudo no Kubernetes é temporário.

Isso assusta quem vem do Mainframe.

No IBM Z pensamos assim:

"Meu programa está naquela máquina."

No Kubernetes pensamos diferente.

"Meu programa está em algum lugar do cluster."

Essa pequena mudança de mentalidade muda tudo.

Imagine uma aplicação simples.

Internet

↓

Frontend

↓

Backend

↓

Banco

Agora imagine que o Backend roda em três Pods.

Pod A

Pod B

Pod C

Cada Pod possui um endereço IP.

10.244.1.3

10.244.8.15

10.244.2.9

Até aqui parece simples.

O problema aparece quando um Pod morre.


Pods nascem e morrem o tempo todo

Ao contrário de um servidor tradicional, Pods são descartáveis.

Podem desaparecer por diversos motivos.

  • atualização

  • falha

  • manutenção

  • escalabilidade

  • reinício do Node

  • Rolling Update

  • Auto Scaling

Imagine:

Pod B

10.244.8.15

Foi destruído.

Kubernetes cria outro.

Pod D

10.244.19.44

Novo IP.

Novo identificador.

Nova localização.

Se todas as aplicações utilizassem o IP antigo, tudo quebraria.

É exatamente aqui que nasce o Kubernetes Service.


Afinal, o que é um Kubernetes Service?

A definição oficial diz:

Um Service fornece um endpoint de rede estável para acessar um conjunto de Pods.

Na prática podemos traduzir para:

Um Service é um endereço permanente que representa vários Pods temporários.

Observe.

Sem Service.

Cliente

↓

Pod A

10.244.1.7

Quando o Pod muda...

Tudo quebra.

Com Service.

Cliente

↓

backend-service

↓

Pod A

Pod B

Pod C

Agora o cliente nunca mais conversa diretamente com os Pods.

Essa é uma das ideias mais elegantes do Kubernetes.


A analogia perfeita para quem conhece Mainframe

Imagine um ambiente CICS.

Você possui:

  • TOR

  • AOR

  • FOR

  • WLM

  • Sysplex

  • VIPA

Quando um usuário acessa uma aplicação, ele normalmente não conhece qual AOR irá executar sua transação.

Existe uma infraestrutura inteligente fazendo esse trabalho.

No Kubernetes acontece exatamente a mesma coisa.

Cliente

↓

Service

↓

Pod 1

Pod 2

Pod 3

O Service é uma espécie de endereço lógico.

Assim como um VIPA.


Por que Services existem?

Existem cinco motivos principais.

1. Endereço permanente

Mesmo que todos os Pods sejam recriados.

O endereço continua igual.


2. DNS automático

Todo Service recebe automaticamente um nome DNS.

Exemplo.

backend-service

Ou

backend-service.default.svc.cluster.local

Isso elimina IPs fixos no código.


3. Balanceamento

Se existem quatro Pods...

Pod1

Pod2

Pod3

Pod4

O Service distribui as requisições.

Nenhum Pod fica sobrecarregado.


4. Descoberta de serviços

Imagine um cluster com:

  • PIX

  • Conta Corrente

  • Cartão

  • Investimentos

  • Fraude

  • Autenticação

Como um microsserviço encontra o outro?

Através do Service.


5. Desacoplamento

Aplicações deixam de depender da infraestrutura.

Mudamos Pods.

Mudamos Nodes.

Mudamos Cluster.

Nada muda para o cliente.


Como um Service funciona internamente?

Muita gente imagina que existe um processo rodando como um proxy.

Na maioria dos casos não.

O fluxo real é aproximadamente este.

Cliente

↓

DNS

↓

Service

↓

EndpointSlice

↓

kube-proxy

↓

iptables/IPVS/eBPF

↓

Pod

O kube-proxy cria regras dentro do próprio Kernel Linux.

O encaminhamento acontece praticamente sem intervenção de processos em espaço de usuário.


Endpoint e EndpointSlice

Quando criamos um Service, ele precisa descobrir quais Pods pertencem à aplicação.

Isso acontece através dos Labels.

Pod.

labels:
  app: backend

Service.

selector:
  app: backend

O Kubernetes encontra automaticamente todos os Pods.

Esses Pods são armazenados em objetos chamados EndpointSlices.

Nos clusters antigos existiam apenas Endpoints.

Hoje o EndpointSlice melhora muito a escalabilidade.


Os quatro tipos clássicos de Services

Agora chegamos ao coração do assunto.


ClusterIP

Este é o padrão.

Sempre que você cria um Service sem especificar o tipo, ele será ClusterIP.

type: ClusterIP

Ele cria um IP virtual acessível apenas dentro do cluster.

Arquitetura.

Frontend

↓

ClusterIP

↓

Backend

É o tipo mais utilizado.

Por quê?

Porque a maioria dos microsserviços nunca deve ficar pública.

Imagine um banco.

Você possui.

  • Serviço PIX

  • Serviço Cartão

  • Serviço Conta

  • Serviço Investimentos

  • Serviço Fraude

Nenhum deles precisa ser acessado pela Internet.

Todos usam ClusterIP.


Casos de uso

  • APIs internas

  • Banco de Dados

  • Redis

  • RabbitMQ

  • Kafka

  • Elasticsearch

  • MongoDB


NodePort

Agora a história muda.

NodePort abre uma porta fixa em todos os servidores do cluster.

Exemplo.

Node1

30080
Node2

30080
Node3

30080

Qualquer um responde.

Mesmo que o Pod esteja em outro servidor.

O acesso acontece assim.

192.168.1.50:30080

Muito útil para laboratório.

Pouco utilizado em produção.


Limitações

  • portas limitadas

  • pouca segurança

  • difícil gerenciamento

  • IP dos Nodes exposto

Por isso normalmente é utilizado apenas para desenvolvimento.


LoadBalancer

Quando trabalhamos em Cloud, LoadBalancer torna-se extremamente importante.

Criamos.

type: LoadBalancer

O Kubernetes conversa automaticamente com o provedor.

AWS cria um ELB.

Azure cria um Azure Load Balancer.

Google cria um Cloud Load Balancer.

IBM Cloud cria um IBM Cloud Load Balancer.

Tudo automaticamente.

Arquitetura.

Internet

↓

Cloud Load Balancer

↓

Service

↓

Pods

Essa automação impressiona quem vem do mundo tradicional.

Em poucos segundos uma infraestrutura completa aparece pronta.


ExternalName

Este tipo é diferente de todos os outros.

Ele não cria IP.

Não cria balanceamento.

Não cria Endpoint.

Não cria Proxy.

Ele apenas responde um nome DNS.

Exemplo.

externalName:
   api.bcb.gov.br

Agora qualquer aplicação utiliza.

banco-central

Mesmo que o endereço verdadeiro mude.

Isso facilita migrações.


O quinto tipo que poucos lembram

Embora muitos materiais apresentem apenas quatro tipos, existe outro extremamente importante.

Headless Service.

clusterIP: None

Nesse caso não existe IP virtual.

O DNS devolve diretamente todos os Pods.

Muito utilizado em StatefulSets.

Exemplo.

  • Kafka

  • Cassandra

  • MongoDB

  • Elasticsearch

  • ZooKeeper


O papel do DNS

Uma das maiores mágicas do Kubernetes.

Criamos.

name: backend-service

Automaticamente nasce.

backend-service.default.svc.cluster.local

Nenhuma configuração adicional.

Isso é fornecido pelo CoreDNS.

Assim os desenvolvedores nunca precisam decorar IPs.


Como acontece o balanceamento?

Imagine.

Pod1

Pod2

Pod3

Chegam 900 requisições.

O Service distribui.

300

300

300

Na prática depende do mecanismo utilizado.

  • iptables

  • IPVS

  • eBPF

Mas a ideia continua sendo a mesma.

Distribuir carga.


O que acontece quando um Pod morre?

Suponha.

Pod2

Falhou.

Kubernetes percebe.

Remove o Pod do EndpointSlice.

O Service deixa imediatamente de enviar tráfego para ele.

O usuário nem percebe.

Depois um novo Pod nasce.

Automaticamente entra no balanceamento.

Tudo sem intervenção humana.


O papel das Readiness Probes

Outro conceito fundamental.

Um Pod pode estar vivo.

Mas ainda não pronto.

Imagine um sistema Java iniciando.

O processo já está executando.

Mas ainda carregando centenas de classes.

O Kubernetes espera a Readiness Probe informar.

"Agora estou pronto."

Só então o Service começa a enviar requisições.


Ingress não substitui Service

Esse erro aparece frequentemente em entrevistas.

Ingress faz uma função diferente.

Arquitetura correta.

Internet

↓

Load Balancer

↓

Ingress Controller

↓

ClusterIP

↓

Pods

Ingress trabalha na camada HTTP/HTTPS.

Service trabalha na camada de rede interna.

São tecnologias complementares.


Session Affinity

Por padrão.

Cada requisição pode ir para qualquer Pod.

Mas algumas aplicações antigas dependem de sessão.

Nesse caso.

sessionAffinity:
   ClientIP

O mesmo cliente tende a conversar sempre com o mesmo Pod.

É semelhante ao conceito de Sticky Session.


Erros clássicos

Selector errado

Service.

selector:
   app: api

Pods.

labels:
   app: backend

Resultado.

Zero Endpoints.


TargetPort incorreto

Service.

targetPort: 8080

Container.

9090

Nada funciona.


Pod não Ready

Existe.

Está executando.

Mas ainda não recebe requisições.


NetworkPolicy

O Service funciona.

Mas a política de rede bloqueia o acesso.


O paralelo com o IBM Mainframe

Chegamos à parte mais interessante.

Veja esta comparação.

IBM MainframeKubernetes
Região CICSPod
SysplexCluster
VIPAClusterIP
Sysplex DistributorService
WLMBalanceamento
VTAMRede do Cluster
DNS CorporativoCoreDNS
Health CheckReadiness Probe
Região AORRéplica do Deployment
Balanceador F5LoadBalancer

Perceba que o Kubernetes não inventou todos esses conceitos.

Ele apenas os adaptou para um mundo distribuído baseado em Linux e containers.


Como um banco utiliza tudo isso?

Imagine um Internet Banking.

Internet

↓

Load Balancer

↓

Ingress

↓

Gateway

↓

Conta Corrente

↓

PIX

↓

Cartão

↓

Investimentos

↓

DB2

Cada caixa dessa arquitetura possui seu próprio ClusterIP.

Cada aplicação possui diversas réplicas.

Cada réplica pode estar em um servidor diferente.

Se um Node inteiro falhar.

O Kubernetes recria os Pods em outro Node.

Os Services continuam exatamente iguais.

Os clientes continuam utilizando os mesmos nomes DNS.

Nenhum código precisa ser alterado.

Esse é o verdadeiro poder da abstração.


Conclusão

Quando começamos a estudar Kubernetes, é comum dedicar muita atenção aos Pods, Deployments e Containers. Eles são importantes, mas representam apenas parte da história.

O componente que realmente transforma um conjunto de processos efêmeros em uma plataforma corporativa é o Service.

Ele fornece identidade estável para aplicações que mudam constantemente, esconde a complexidade da infraestrutura, distribui carga, integra-se ao DNS do cluster e permite que atualizações, escalabilidade e recuperação de falhas ocorram de forma transparente.

Para quem vem do universo IBM Mainframe, a ideia não é totalmente nova. Há décadas, tecnologias como VIPA, Sysplex Distributor, WLM e CICS já abstraem a localização física das aplicações e distribuem trabalho entre múltiplas instâncias. O Kubernetes segue a mesma filosofia, adaptando-a ao mundo dos containers, dos microsserviços e da computação em nuvem.

O grande aprendizado para o Programador COBOL Padawan é que o endereço de uma aplicação nunca deve depender da máquina onde ela está executando. Assim como um usuário de um sistema bancário não precisa saber qual região CICS processará sua transação, um consumidor de um microsserviço não deve conhecer o IP de um Pod. Ele deve conhecer apenas um nome lógico — o Service.

No fim das contas, Kubernetes Services representam muito mais do que um recurso de rede. Eles materializam princípios clássicos de engenharia de software: abstração, desacoplamento, alta disponibilidade, balanceamento de carga, resiliência e escalabilidade. São esses princípios que permitem que grandes bancos, seguradoras e empresas globais executem milhões de transações por dia, mantendo seus sistemas disponíveis mesmo quando containers são criados, destruídos e recriados continuamente. Entender esse mecanismo é um passo fundamental para qualquer desenvolvedor COBOL que deseje evoluir do mundo do processamento tradicional para a moderna engenharia de software baseada em DevOps, Cloud Native e IBM Z integrado ao ecossistema Kubernetes.