Mais recentes

Conteúdo técnico, ferramentas e experiências práticas da IceNex.

segunda-feira, 26 de outubro de 2026

“WARNING: connection is not using a post-quantum key exchange”: o aviso novo do SSH


Computadores quânticos capazes de quebrar criptografia ainda não existem. Mas o SSH já começou a avisar quando a sua conexão não está protegida contra eles. Entenda por quê.

Fala pessoal, tudo bem?

No post "SSH sem dor de cabeça" configuramos chaves e atalhos para conectar nos nossos nodes. Se você atualizou o cliente SSH recentemente, pode ter dado de cara com isto:

** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.
** The server may need to be upgraded. See https://openssh.com/pq.html

Calma, ninguém invadiu o seu servidor. Mas o aviso merece atenção.

"Guarde agora, decifre depois"

A ideia por trás do aviso é simples e um pouco assustadora:

Hoje Atacante grava sua sessão SSH cifrada Anos depois Surge computador quântico capaz de quebrar a troca Resultado Senhas, segredos e comandos expostos O risco não é o atacante de hoje. É o tráfego de hoje nas mãos do atacante de amanhã.

Por isso a proteção precisa começar antes de o computador quântico existir. Um segredo que vale para os próximos 10 anos já está em risco hoje.

O que o OpenSSH mudou

  • OpenSSH 9.0 (2022): passou a usar por padrão uma troca de chaves híbrida pós-quântica (sntrup761x25519).
  • OpenSSH 10.0 (abril de 2025): o padrão virou mlkem768x25519-sha256, baseado no ML-KEM, padronizado pelo NIST.
  • OpenSSH 10.1: o cliente passou a avisar quando a conexão não usa nenhum algoritmo pós-quântico.
"Híbrido" é a palavra-chave: o algoritmo combina o clássico X25519 com o pós-quântico ML-KEM. Se um dos dois tiver alguma fraqueza descoberta no futuro, o outro continua protegendo.

Como verificar a sua conexão

# versão do seu cliente
$ ssh -V

# algoritmos de troca de chave que o cliente conhece
$ ssh -Q kex | grep -E "mlkem|sntrup"

# qual algoritmo foi negociado com o servidor
$ ssh -v kub-node1 exit 2>&1 | grep "kex: algorithm"
debug1: kex: algorithm: mlkem768x25519-sha256

No servidor, confira se a configuração não está bloqueando os algoritmos novos:

# versão e algoritmos efetivamente ativos no sshd
$ sudo sshd -V
$ sudo sshd -T | grep -i kexalgorithms
⚠️ Armadilha comum: guias antigos de "hardening de SSH" mandam fixar uma lista de KexAlgorithms no sshd_config. Essa lista, feita anos atrás, provavelmente exclui os algoritmos pós-quânticos. Revise antes de culpar a versão.

E se o servidor não puder ser atualizado?

Switch, appliance, equipamento legado... acontece. Nesse caso dá para silenciar o aviso só para aquele host, assumindo o risco de forma consciente, no seu ~/.ssh/config:

Match host switch-legado.lab
    WarnWeakCrypto no-pq-kex
💡 Dica: nunca desligue o aviso globalmente. Ele é exatamente o que vai te lembrar de que aquele equipamento precisa sair da rede um dia.

Considerações Finais

A transição para criptografia pós-quântica é uma daquelas mudanças que acontecem em silêncio, por baixo das ferramentas que usamos todo dia. No SSH, a parte difícil já foi feita: basta estar atualizado e não atrapalhar com configuração antiga.

O aviso no terminal não é um problema. É um inventário gratuito dos servidores que ficaram para trás.

Abs e até a próxima!!!

:wq!

sexta-feira, 23 de outubro de 2026

Kubernetes 1.37 “Garhwal”: o que vale prestar atenção (e a versão de que você precisa sair agora)


O Kubernetes lança uma versão a cada quatro meses. Não dá para acompanhar tudo, mas dá para saber o que importa e quando a sua versão vai ficar sem suporte.

Fala pessoal, tudo bem?

O Kubernetes 1.37, codinome "Garhwal", saiu no final de agosto e já está na 1.37.1. Foram 67 melhorias: 16 viraram estáveis, 23 chegaram ao beta e 27 entraram como alpha.

Ninguém precisa ler as 67. Vou separar o que chama atenção para quem opera cluster no dia a dia. E, mais importante, falar de suporte, que é onde muita gente se complica.

Destaques que valem um olhar

  • Metrics API estável (GA): a API que alimenta o kubectl top e o HPA finalmente é considerada estável.
  • HPA com scale to zero (beta): o autoscaler pode levar um deployment a zero réplicas. Ótimo para ambientes de teste e workloads que ficam ociosos.
  • Kubelet em modo rootless (beta): o kubelet rodando dentro de um user namespace, reduzindo o estrago caso algo escape do container.
  • Memory QoS (beta): proteção de memória em camadas usando cgroups v2.
  • PVC "last used time" (beta): saber quando um volume foi usado pela última vez. Quem já caçou disco órfão na cloud sabe o valor disso.
  • Pod Certificates: certificados emitidos para pods, facilitando mTLS entre serviços.
Repare no padrão: boa parte das novidades é sobre segurança (rootless, certificados) e eficiência (scale to zero, memória, volumes esquecidos). O Kubernetes está ficando mais maduro, não mais complicado.

Alpha, beta e GA: o que isso significa para você

Estágio Ligado por padrão? Usar em produção?
AlphaNãoNão. Pode mudar ou sumir.
BetaDepende da featureCom cuidado e teste.
GA (stable)SimSim. A API não quebra mais.

A parte que ninguém gosta: ciclo de suporte

Cada versão menor do Kubernetes recebe correções por cerca de 14 meses. Depois disso, você está por conta própria. Veja a situação hoje:

Até quando cada versão recebe correções de segurança out/26 jan/27 abr/27 jul/27 out/27 1.34 acaba em 27/out/2026 1.35 fev/2027 1.36 jun/2027 1.37 out/2027
🚨 Se você está na 1.34: as correções de segurança terminam em 27 de outubro de 2026, daqui a poucos dias. A 1.33 e anteriores já estão sem suporte nenhum. Se você usa um serviço gerenciado (EKS, AKS, GKE), confira o calendário do provedor, que pode ser diferente.

Antes de atualizar: o mínimo que você deve checar

# versão do cliente e do cluster
$ kubectl version

# versão do kubelet em cada node
$ kubectl get nodes -o wide

# APIs depreciadas que ainda estão sendo chamadas
$ kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis
💡 Regra prática: o Kubernetes só permite subir uma versão menor por vez no control plane (1.35 → 1.36 → 1.37). Quem fica muito para trás transforma uma atualização simples em um projeto de semanas.

Considerações Finais

Acompanhar o Kubernetes não é ler todo changelog. É ter duas informações sempre à mão: o que de novo resolve um problema seu, e quando a versão que você roda deixa de receber correções.

A primeira é opcional. A segunda, não.

Abs e até a próxima!!!

:wq!

quarta-feira, 21 de outubro de 2026

O Ingress NGINX foi aposentado. E agora?

Fala pessoal, tudo bem?

"O controlador mais usado para expor aplicações no Kubernetes parou de receber atualizações em março de 2026. Se ele ainda está no seu cluster, você está sem patches de segurança."

Em novembro de 2025 o projeto Kubernetes anunciou algo que pegou muita gente de surpresa: o Ingress NGINX seria aposentado em março de 2026. Esse prazo já passou.

Estamos falando de um componente usado em cerca de metade dos ambientes cloud native, segundo o próprio comunicado do Kubernetes. E o motivo não foi técnico: foi falta de mantenedores.

🚨 O que significa na prática: sem novas versões, sem correção de bug e sem patch de segurança. O controlador continua rodando, mas qualquer vulnerabilidade nova fica aberta para sempre.

Obs: estamos falando do projeto comunitário kubernetes/ingress-nginx. O controlador mantido pela F5/NGINX é outro projeto.

Como saber se você usa

# quais IngressClasses existem no cluster
$ kubectl get ingressclass

# procurando o controlador comunitário em qualquer namespace
$ kubectl get pods -A -l app.kubernetes.io/name=ingress-nginx

# quantos Ingress dependem dele
$ kubectl get ingress -A

Se apareceu algo, o assunto é com você. Rode isso em todos os clusters, inclusive aquele de homologação esquecido.

A lição maior: infraestrutura crítica sem dono

Antes da parte técnica, vale a reflexão. Um componente que está na frente de metade das aplicações do mundo foi mantido por pouquíssimas pessoas, muitas no tempo livre. Quase ninguém que usava contribuía.

Isso não é exclusivo do Ingress NGINX. Pergunte-se: quantas peças do seu ambiente dependem de projetos que você nunca olhou quem mantém?

Para onde ir: Gateway API

A recomendação oficial é migrar para a Gateway API (ou para outro controlador Ingress mantido). A Gateway API é o sucessor do Ingress, e a maior mudança é a separação de responsabilidades:

Cada recurso tem um dono GatewayClass qual implementação usar Provedor de infraestrutura Gateway porta, TLS, quem pode se ligar Time de plataforma / operação HTTPRoute host, path, para qual Service Time da aplicação

No Ingress, tudo isso ficava num único objeto, cheio de annotations específicas do controlador. Na Gateway API, cada time mexe só no que é seu.

Exemplo: o mesmo roteamento, antes e depois

# ANTES: Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: loja
spec:
  ingressClassName: nginx
  rules:
    - host: loja.exemplo.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: loja-web
                port:
                  number: 80
# DEPOIS: HTTPRoute (o Gateway "publico" é do time de plataforma)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: loja
spec:
  parentRefs:
    - name: publico
      namespace: infra-gateway
  hostnames:
    - loja.exemplo.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: loja-web
          port: 80
💡 Atalho útil: o projeto ingress2gateway (kubernetes-sigs) converte Ingress existentes em recursos da Gateway API. Use como ponto de partida e revise o resultado. Annotations específicas do NGINX nem sempre têm equivalente direto.

Plano de migração em 4 passos

  1. Inventário: liste todos os Ingress e, principalmente, as annotations usadas (rewrite, auth, rate limit).
  2. Escolha a implementação da Gateway API e suba em paralelo, sem tirar o NGINX.
  3. Migre por aplicação, começando pela menos crítica. Teste apontando DNS ou peso de tráfego.
  4. Desligue o antigo só quando nenhum Ingress depender dele.

Considerações Finais

A aposentadoria do Ingress NGINX é um lembrete duro: open source é gratuito para usar, mas não é gratuito para manter. Alguém paga essa conta, e às vezes ninguém está pagando.

Se o seu cluster ainda depende dele, a migração não é mais "algum dia". É agora.

Abs e até a próxima!!!

:wq!

segunda-feira, 19 de outubro de 2026

A chegada do Ubuntu 26.10 "Stonking Stingray"


O Ubuntu 26.10 saiu em 15 de outubro com uma mudança silenciosa e histórica: os utilitários básicos do sistema agora vêm de uma implementação em Rust.

Fala pessoal, tudo bem?

O Ubuntu 26.10 "Stonking Stingray" chegou na semana passada. Tem kernel Linux 7.3, GNOME 51, systemd 261 e OpenSSL 4.0. Mas a novidade que mais me chamou atenção não aparece em print de desktop: a migração dos coreutils para Rust foi concluída.

Ou seja: ls, cp, mv, rm, cat... aquelas ferramentas que usamos centenas de vezes por dia agora vêm do projeto uutils, e não mais do GNU coreutils que acompanha o Linux há mais de 30 anos.

Por que isso importa: não é sobre a linguagem da moda. É sobre segurança de memória em ferramentas que rodam como root, em scripts, em pipelines e em todo servidor do planeta.

O que mudou no 26.10 (o essencial)

Componente No 26.10
KernelLinux 7.3
Coreutilsuutils (Rust), migração concluída
Barramento do sistemadbus-broker no lugar do dbus-daemon
Basesystemd 261, OpenSSL 4.0, Python 3.14, Rust 1.97
Suporte9 meses (até julho de 2027)

Por que reescrever algo que funciona?

Boa parte das vulnerabilidades graves em software de sistema vem de erros de memória: buffer overflow, use-after-free, ponteiro inválido. Em C, evitar isso depende da atenção do programador. Em Rust, uma grande parte desses erros nem compila.

O caminho começou antes: o Ubuntu 25.10 já tinha trocado o sudo pelo sudo-rs. Agora é a vez dos utilitários básicos. É uma tendência que vai além do Ubuntu: Rust já está no próprio kernel Linux.

Rust chegando nas camadas do sistema Kernel suporte a drivers em Rust Ubuntu 25.10 sudo-rs como sudo padrão Ubuntu 26.10 coreutils (ls, cp, mv, rm) em Rust

Como saber o que está rodando aí

Se você já está no 26.10, dá para conferir de onde vem cada ferramenta:

# versão do sistema e do kernel
$ lsb_release -a
$ uname -r

# a primeira linha mostra qual implementação responde
$ ls --version | head -1
$ sudo --version | head -1

# para onde o binário aponta de verdade
$ readlink -f "$(which ls)"
⚠️ Atenção com scripts antigos: a meta do uutils é ser compatível com o GNU, mas detalhes de saída, mensagens de erro e opções raras podem variar. Se você tem scripts que fazem grep na saída de ls ou df, teste antes de subir para o 26.10 em produção.

Devo atualizar meus servidores?

Para servidor, a resposta curta continua sendo: fique na LTS (26.04). O 26.10 é uma versão interina, com 9 meses de suporte. Ela serve para testar o que vem na próxima LTS.

💡 Dica de laboratório: suba uma VM com o 26.10 e rode seus scripts de rotina nela (backup, deploy, limpeza). É o jeito mais barato de descobrir hoje o que vai quebrar na 28.04 LTS.

Considerações Finais

Trocar o ls parece pequeno. Mas é o tipo de mudança que mostra para onde o Linux está indo: menos confiança na atenção humana, mais garantia vinda da ferramenta.

Para quem administra sistemas, o recado é simples: as ferramentas de sempre continuam com o mesmo nome, mas não são mais exatamente as mesmas. Vale testar.

Abs e até a próxima!!!

:wq!

Kubernetes do Zero - Parte 4: Pods e Limites de recursos



Fala galera, td bem?

Retomando nossa sequência sobre kubernetes do zero, hoje falamos falar sobre Pods e Limites de Recursos.

PODs

Quando falamos de qualquer componente do kubernetes, o Pod é a menor unidade que podemos ter dentro do nosso cluster.

Dentro do kubernetes, o Pod é o objeto que pode conter um ou mais containers, compartilhando os mesmos recursos como IP, namespace, volume e para resumir, tudo que for relacionado a este Pod.

Vamos ver alguns exemplos de como criar um Pod no nosso cluster.

Inicialmente para criarmos um Pod, podemos executar direto pela linha de comando.

kubectl run webapp --image=nginx --port=80
Esse comando faz com que seja criar um Pod chamado webapp com a imagem do nginx expondo o serviço na porta 80.

Dando tudo certo com o comando "run", teremos uma saída informando que o pod foi criado:


Para consultar se ele foi criado de fato e qual o seu STATUS, devemos rodar o comando:
kubectl get pods

Explicando a saúda do "kubectl get pods":

  • Name - o nome que demos para nosso Pod
  • READY - aqui está 0/1 por que o Pod ainda está sendo criado efetivamente (baixando a imagem, aplicando IP, etc). Quando estiver pronto, o Ready ficará 1/1 ... pois foi solicitado apenas 1 Pod, então o esperado é isso 1/1
  • STATUS - será o nosso principal ponto de acompanhamento. Aqui teremos as mensagens iniciais de erro caso seja encontrado algum problema, se ele ainda está sendo criado, se foi criado com sucesso
  • RESTARTS - Muitas vezes podemos ter cenários de problemas/erros que fazem com que o Pod fique reiniciando. Se esse "count" começar a sofrer incrementos é sinal de problema
  • AGE - por quanto tempo o Pod está disponível desde que começou a ser criado.

Passando um curto intervalo de tempo, rodando novamente o "kubectl get pods", devemos ter a saída abaixo:


  • READY - 1/1
  • STATUS - Running

E o melhor de tudo, sem RESTARTS.

Um ponto de atenção...

Muitos clusters kubernetes trabalham com namespaces, então ao rodar o comando "kubectl get pods" fará a busca de recursos no namespace padrão. Aqui no nosso caso, criamos nosso Pod dentro do padrão mesmo, por isso o comando retornou algo.

Veremos o tema namespace mais pra frente.

Mas só para já irmos nos familiarizando, caso seja necessário em um cluster novo que não conhecemos por exemplo, podemos rodar o seguinte comando:

kubectl get pods -A

Veja agora com a opção "-A" a quantidade de Pods que retornou. Mas ali, na primeira coluna temos o detalhe de onde cada Pod está residindo.

Outra forma de ter essa mesma saída é com o comando:
kubectl get pods --all-namespaces
Ou se quisermos diretamente os Pods de um respectivo namespace:
kubectl get pods -n Nome_Do_Namespace
Exemplo, só os Pods do namespace kube-system:

kubectl get pods -n kube-system

Legal... Mas, eu tenho como ver onde o Pod está rodando? Saber em qual node do cluster, se ele pegou um IP e qual IP é esse...

Tem sim.
Para isso, vamos executar o comando:

kubectl get pods -o wide


Nosso Pod webapp está residindo no node "k8s-kind-worker" e tem o IP 10.244.1.6.

Podemos também ter uma saída com informações mais descritivas do nosso Pod, com o seguinte comando:
kubectl describe pods webapp

Ele trás as mesmas informações que os comandos get, porém, podemos ver o ID do container que está em execução dentro deste Pod, a image, ID da imagem, um trecho do log de subida, etc.

Show de bola.

Mas e agora, como eu faço para deletar um Pod?

Pela linha de comando, seria assim:
kubectl delete pods Nome_Do_Pod
No nosso lab, vamos deletar o Pod webapp:
kubectl delete pods webapp

Como podemos confirmar com o comando "kubectl get pods" depois de rodar o delete ... Nosso Pod webapp não existe mais.

A outra forma de criamos Pods no kubernetes é através de manifestos, chamados mais tradicionalmente de arquivos YAML.

Um arquivo YAML (YAML Ain't Markup Language) é um documento de texto simples usado para armazenar e organizar dados de forma estruturada, com foco total na legibilidade humana.

Vejamos um exemplo:

apiVersion: v1 # versão da API do Kubernetes
kind: Pod # tipo do objeto que estamos criando
metadata: # metadados do Pod 
  name: webapp # nome do Pod que estamos criando
  labels: # labels do Pod
    run: webapp # label run com o valor webapp
spec: # especificações do Pod
  containers: # containers que estão dentro desse Pod
  - name: webapp # nome do container
    image: nginx # imagem do container
    ports: # portas que estão sendo expostas pelo container
    - containerPort: 80 # porta 80 exposta pelo container
A parte um pouco "chata" do uso dos YAMLs é que ele tem padrão e indentação. Então, quando estamos fazendo as criações de recursos por YAML (que é a forma correta e recomendada), devemos ficar sempre atentos a estrutura ... Com certeza até pegarmos a manha muitos erros vão ocorrer, até conseguirmos acertar tudo e assim os objetos serem criados.

Agora, vamos fazer um teste de criação do nosso pod webapp, usando esse YAML como base das informações.


Salve o conteúdo do arquivo.

Valide se está tudo OK:


Depois de criarmos o arquivo, para executar devemos rodar o comando:

kubectl apply -f create-pod.yaml
Dando tudo certo, a saída será:


E para ver se está tudo OK com o Pod:
kubectl get pods

Para deletá-lo, vale o mesmo comando que usamos de que usamos no nosso primeiro deploy do webapp.
kubectl delete pods webapp
Uma outra forma de fazermos isso, seria usando o delete mas informando o nome do arquivo que usamos para criação do Pod:
kubectl delete -f create-pod.yaml
Vamos ver um exemplo da criação de um Pod com mais de um container?

Vamos criar um arquivo chamado "create-pod-multcontainer.yaml".
O conteúdo dele será:
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    run: webapp
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
  - name: apache
    image: httpd:latest
    ports:
    - containerPort: 8080
    command: ["/bin/sh", "-c"]
    args:
      - |
        sed -i 's/Listen 80/Listen 8080/g' /usr/local/apache2/conf/httpd.conf
        httpd-foreground

Tanto Nginx como Apache HTTPD usam a mesma porta TCP/80, então se tetarmo subir os dois vamos tomar um erro. Por isso ao final, na configuração do container do Apache, vamos durante o processo de subida, já trocar o porta dele para 8080.

kubectl apply -f create-pod-multcontainer.yaml



Olha que top!!!

O STATUS está como Running e no READY vemos 2/2.
Mas como vamos ter a certeza que dentro do webapp temos um container do Nginx e um do Apache?

Com o describe, que aprendemos acima:
kubectl describe pods webapp


Não é muito comum vermos este tipo de cenário onde dentro de um Pod temos dois containers ... Mas dependendo, alguma aplicação pode ter essa necessidade.

E para deletar esse Pod multi-containers?
Mesma coisa que já vimos também. Podemos usar o comando "kubectl delete Nome_Do_Pod" ou "kubectl delete -f arquivo.yaml".

Escolha uma das opções e tente deletar o seu sozinho :)
Mas qualquer problema ou dúvida, é só comentar aqui no post. OK?

Aplicando limites de recursos (CPU e Memória)

Agora que vimos como subir nossos Pods, ou melhor, nossas aplicações ... Um problema muito comum que pode e vai acontecer, é o uso desenfreado de recursos.

Isso mesmo.

O processo de criação que usamos até aqui, não cria nenhum limite de recursos de CPU e memória aos nossos Pods e dependendo do que rode neles conforme for precisando de mais recursos, eles vão consumir e isso pode saturar nosso cluster, provisionar recursos a mais e gerar custos desnecessários. Principalmente quando falamos de recursos em Cloud.

Mas existe uma "mágica" interessante que podemos fazer ... a limitação de recursos.

Podemos e devemos, como parte de sermos bons administradores de kubernetes, limitar recursos dos Pods e irmos ajustando conforme necessidade. Isso nos dará informações para saber se uma determinada aplicação precisa ser melhor desenvolvida, trocar algum parâmetro dentro dela, se precisamos realmente colocar mais recursos em nosso ambiente para acomodá-la, etc.

E agora que sabemos que o correto é criar recursos no kubernetes usando manifestos YAML, vamos fazer isso dessa forma.

Exemplo do arquivo YAML que iremos usar no nosso lab:
apiVersion: v1 # versão da API do Kubernetes
kind: Pod # tipo do objeto que estamos criando
metadata: # metadados do Pod
  name: webapp # nome do Pod que estamos criando
  labels: # labels do Pod
    run: nginx # label run com o valor nginx
spec: # especificação do Pod 
  containers: # containers que estão dentro do Pod 
  - name: nginx # nome do container 
    image: nginx # imagem do container
    ports: # portas que estão sendo expostas pelo container
    - containerPort: 80 # porta 80 exposta pelo container
    resources: # recursos que estão sendo utilizados pelo container
      limits: # limites máximo de recursos que o container pode utilizar
        memory: "192Mi" # limite de memória que está sendo utilizado pelo container, no caso 192 megabytes no máximo 
        cpu: "0.5" # limite máxima de CPU que o container pode utilizar, no caso 50% de uma CPU no máximo
      requests: # recursos garantidos ao container
        memory: "128Mi" # memória garantida ao container, no caso 128 megabytes
        cpu: "0.3" # CPU garantida ao container, no caso 30% de uma CPU

Dentro de "resources" temos:

limitis:
  memory: "valor"
  cpu: "valor"

Aqui temos o máximo de recursos que este determinado Pod pode usar dos recursos do cluster.

requests:
  memory: "valor"
  cpu: "valor"

Da mesma forma que podemos limitar os recursos para que não seja usado tudo que tem no cluster, podemos informar ao kubernetes que uma determinada aplicação precisa garantir uma quantidade "mínima" de recursos obrigatórios para uma determinada aplicação.

Agora vamos subir nossa aplicação com limite de recursos e com a quantidade mínima de recursos que ela precisa.

Crie o arquivo "pod-limites.yaml" e cole o conteúdo de exemplo acima e aplique com o comando:
kubectl apply -f pod-limites.yaml
Vamos validar se os limites foram aplicados?
kubectl describe pods webapp

Rapaiiizzzz... e "num" é que deu certo =) ... Isso é lindo demais!!!

Agora, o legal é vc ir testando e aplicando tudo que aprendemos no seu lab. Tente subir um Pod com menos recursos como necessário e veja se ele sobe, tente subir vários Pods cada um com uma quantidade de recursos e veja como fica o comportamento do seu cluster ... a mágica agora é ir testando.

Se ficou alguma dúvida é só deixar aqui nos comentários.

Abs e até a próxima postagem.
:wq!

domingo, 18 de outubro de 2026

Quem vai formar o próximo sênior? Aprender infraestrutura na era da IA

Se a IA faz o trabalho que formava os juniores, como eles vão virar seniores?

Fala pessoal, tudo bem?

Quem tem alguns anos de infraestrutura aprendeu do mesmo jeito: quebrando coisa. Servidor que não subia, rede que não pingava, horas de log até achar a linha que explicava tudo.

Hoje, boa parte disso a IA faz em segundos. Você descreve, recebe o manifesto pronto. Cola o erro, recebe a explicação. Ótimo para quem já sabe. Mas levanta uma pergunta que pouca gente faz em voz alta.

As tarefas "chatas" que iam para quem estava começando eram, na verdade, a escola. E são justamente as primeiras que a IA automatiza.

De onde vem a "intuição de sênior"

Aquele colega que olha um gráfico e diz "isso é vazamento de memória" antes de qualquer análise não tem um dom. Tem um ciclo repetido centenas de vezes:

Intuição de sênior 1. Errar 2. Investigar 3. Entender 4. Repetir

Quando a IA entrega a resposta pronta, ela pula as etapas 1 e 2. E sem elas a etapa 3 fica rasa.

O risco de entender pela metade

O perigo não é a IA errar. É ela acertar sem que você saiba por quê.

O manifesto funciona, o pod sobe. Mas você sabe por que aquele securityContext está ali? O que acontece sem o readinessProbe? Se não, você não aprendeu Kubernetes. Aprendeu a pedir manifesto de Kubernetes.

⚠️ O risco real: formar profissionais que operam sistemas que não entendem, e que só descobrem isso no pior momento: no meio de um incidente. Quanto mais fluente a resposta da IA, mais difícil desconfiar dela.

Exemplo: o mesmo pedido, dois resultados

❌ Pedido que só entrega

"Me dá um Deployment do nginx com 3 réplicas."
Você recebe o YAML, aplica, funciona. Amanhã, num problema parecido, pede de novo.
✅ Pedido que ensina

"Escrevi este Deployment. Me explica cada campo, o que quebra se eu tirar cada um e o que faltou para produção."
Você recebe o YAML e o modelo mental. Amanhã, resolve sozinho.

Usando a IA para aprender, não para pular o aprendizado

  • Tente primeiro, pergunte depois. Mesmo sem chegar lá, você entende muito melhor a resposta.
  • Quebre de propósito. Tire um campo do manifesto, derrube um node. É para isso que serve o lab da série Kubernetes do Zero.
  • Explique de volta. Se não consegue explicar com suas palavras, ainda não entendeu.
  • Confira na fonte. Trate a IA como um colega esperto, não infalível. A documentação oficial tem a palavra final.
  • Escreva sobre o que aprendeu. Um blog, um repositório, um caderno.

Um exemplo de "quebrar de propósito" no seu lab com kind:

# o que acontece com os pods quando um worker some?

$ kubectl get pods -o wide

$ docker stop kind-k8s-worker

# observe por alguns minutos e tente explicar o que viu

$ kubectl get nodes -w

$ kubectl get pods -o wide -w

# depois, traga o node de volta

$ docker start kind-k8s-worker
💡 Um teste simples: se a internet caísse agora e você precisasse resolver aquele problema sem a IA, você saberia por onde começar? Não precisa ser rápido. Só precisa saber o caminho.

E quem já é sênior?

Se as tarefas que formavam juniores estão sumindo, alguém precisa criar novas formas de aprender:

  • Revisão comentada: quando chegar algo gerado pela IA, pergunte "por que isso está aqui?".
  • Incidentes como aula: chame quem está começando para o postmortem, nem que seja para ouvir.
  • Game days: simule falhas e deixe o time investigar.
  • Pareamento: meia hora pensando em voz alta ensina mais que qualquer documentação.

Considerações Finais

A IA não acabou com a necessidade de entender infraestrutura. Acabou com a necessidade de digitá-la.

Quem usa a IA para pular o entendimento fica rápido nas tarefas simples e perdido nas difíceis. Quem usa para acelerar o entendimento aprende em meses o que muitos de nós levamos anos. A ferramenta é a mesma; muda a pergunta que você faz.

E para quem já está há mais tempo na área: o próximo sênior não vai se formar sozinho. Ele precisa de alguém que pergunte "por quê?" na hora certa.

Abs e até a próxima!!!

:wq!

Engenharia de plataforma: por que tantas plataformas internas viram só mais uma fila de tickets

O que separa uma plataforma interna que o time adora de uma que todo mundo tenta contornar. Spoiler: quase nunca é a ferramenta.

Fala pessoal, tudo bem?

Você provavelmente já viu esse roteiro. A empresa cresce, cada time sobe seus serviços de um jeito, e nasce o time de plataforma. Ferramentas escolhidas, cluster montado, portal bonito no ar.

Seis meses depois, metade dos desenvolvedores não usa, a outra metade usa reclamando, e o time de plataforma passa o dia respondendo "preciso de um namespace" e "como eu crio um banco?".

A plataforma virou exatamente o que deveria eliminar: mais uma fila.

O problema que ela tenta resolver

Para subir um serviço simples hoje, um dev pode precisar entender Dockerfile, manifesto, Helm, pipeline, segredos, rede, certificado, observabilidade e custo de cloud. Cada item é razoável. Juntos, viram uma carga cognitiva que tira o foco do produto.

Engenharia de plataforma é oferecer essas capacidades prontas, para que os times entreguem sem virar especialistas em infraestrutura.

O erro clássico: o portal que só esconde o ticket

A maioria das plataformas que fracassam foi desenhada pelo ponto de vista de quem opera, não de quem usa. O sintoma mais claro é este:

Portal que esconde o ticket Dev pede banco Formulário Fila do time de plataforma Alguém cria na mão Tempo: dias. A interface ficou bonita, o processo é o mesmo. Self-service de verdade Dev pede banco Template + pipeline (automático) Banco pronto, com backup, métricas e segredo no cofre Tempo: minutos. O time de plataforma cuida do molde, não de cada pedido. Se uma operação rotineira precisa de um humano no meio, ainda não é plataforma.

Plataforma como produto

A virada de chave é tratar a plataforma como produto e os desenvolvedores como clientes. Na prática:

  • Converse antes de construir. Onde os times perdem horas? O que copiam do projeto vizinho?
  • Roadmap baseado em dor, não na ferramenta que o time de plataforma quer testar.
  • Meça adoção. Se ninguém usa, não importa o quão bem feito está.
  • Aceite o "não quero". É informação, não insubordinação.

Caminhos pavimentados, não muros

O caminho pavimentado (golden path) é um jeito padrão e bem suportado de fazer o que é comum. Quem segue ganha segurança, observabilidade e deploy prontos. Quem precisa de algo diferente pode sair, mas assume o que construiu fora do padrão.

Um exemplo de primeiro produto de plataforma, sem portal nenhum: um template de repositório que já nasce pronto.

template-servico-api/

├── Dockerfile                 # imagem base aprovada, usuário não-root

├── .github/workflows/

│   └── ci-cd.yaml             # build, testes, scan e deploy por ambiente

├── deploy/

│   ├── base/                  # Deployment, Service, HPA, probes

│   └── overlays/

│       ├── hml/

│       └── prd/

├── observability/

│   ├── dashboard.json         # painel com os sinais de ouro

│   └── alerts.yaml            # alertas por SLO, não por CPU

├── docs/

│   └── runbook.md             # como diagnosticar e fazer rollback

└── README.md                  # "do clone à produção em 1 tarde"
💡 Em uma frase: o objetivo não é obrigar ninguém a usar a plataforma. É fazer com que ela seja, de longe, o jeito mais fácil de trabalhar. Se as pessoas fogem do caminho pavimentado em massa, o problema é o caminho.

Como saber se está funcionando

Pergunta Sinal de que vai bem
Quanto tempo um dev novo leva para pôr o 1º serviço no ar? Uma tarde, não semanas
Quantos tickets chegam por operações rotineiras? Caindo mês a mês
Quantos serviços seguem o caminho pavimentado? A maioria, por escolha
Frequência de deploy e tempo de recuperação Melhorando depois da adoção

Comece pequeno (e saiba quando não vale)

Escolha uma dor, a mais comum e mais chata. Resolva bem, com um ou dois times parceiros. Depois vá para a próxima. Um ano construindo antes de entregar é receita para descobrir que metade não resolve o problema de ninguém.

⚠️ Com dois ou três times de desenvolvimento, uma plataforma interna completa é construir um produto para um mercado de cinco clientes. Boas convenções e um bom template já resolvem.

Considerações Finais

Engenharia de plataforma não é sobre o melhor portal ou orquestrador. É sobre empatia com quem está do outro lado: entender onde o dev perde tempo e construir, aos poucos, um caminho mais simples.

A melhor plataforma é aquela que quase ninguém percebe. A pior é aquela que todo mundo conhece pelo nome do formulário.

Abs e até a próxima!!!

:wq!

sábado, 17 de outubro de 2026

IA no plantão: autonomia, confiança e quem responde quando o agente erra


Agentes de IA já executam ações em produção. A pergunta mais importante não é "ele consegue?", mas "o que acontece quando ele errar?".

Fala pessoal, tudo bem?

Hoje o post não tem passo a passo. É uma conversa sobre algo que está chegando rápido nos times de infraestrutura: agentes de IA que não só sugerem, mas executam.

Eles leem o alerta, consultam métricas, escrevem o patch, rodam o kubectl e fecham o incidente. Às vezes antes de alguém acordar. Parece o sonho de todo plantonista, e em parte é mesmo.

A ideia central do post: autonomia de um agente não é questão de capacidade. É questão de risco: quanto ele pode fazer sozinho, até onde vai o estrago se errar e quem responde depois.

Por que é diferente do autoscaler

Automação em produção não é novidade. Autoscaler, failover, pipeline de deploy. A diferença é que essas automações são determinísticas: mesma entrada, mesma ação.

Um agente de IA interpreta. Pode acertar um diagnóstico difícil e, no incidente seguinte, concluir com toda a convicção que o problema é o DNS quando era um certificado expirado. Essa flexibilidade é justamente o que o torna útil e imprevisível.

Autonomia é um dial, não um interruptor

Em vez de "deixa a IA mexer" contra "IA longe de produção", pense em níveis:

Níveis de autonomia de um agente 1. Observa e explica Lê alertas e logs, resume. Não muda nada. 2. Sugere e prepara Monta o PR. Humano aprova. 3. Executa ações reversíveis Restart, scale, rollback. 4. Autonomia ampla Migração, rede, delete. Quanto maior a barra, maior o raio de impacto de um erro.

O erro mais comum é pular do nível 1 para o 4 porque a demonstração foi impressionante. Demonstração é o caminho feliz. Produção é o resto.

A pergunta certa: qual é o raio de impacto?

Um restart de pod errado custa segundos. Um terraform destroy no workspace errado custa um final de semana. Um DELETE sem WHERE custa uma carreira.

💡 Regra prática: dê autonomia ao agente só para ações que você desfaz com um único comando. Tudo que for irreversível passa por aprovação humana, sem exceção.

Exemplo: limitando o agente com RBAC

A mesma lógica de permissão mínima que usamos com pessoas vale para o agente. Ele ganha uma ServiceAccount própria, que só consegue reiniciar e escalar deployments em um namespace, e nada mais:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: agente-ia-nivel3
  namespace: app-pagamentos
rules:
  # pode ler o estado para diagnosticar
  - apiGroups: ["", "apps"]
    resources: ["pods", "pods/log", "deployments", "events"]
    verbs: ["get", "list", "watch"]
  # pode reiniciar (rollout restart) e escalar
  - apiGroups: ["apps"]
    resources: ["deployments", "deployments/scale"]
    verbs: ["patch"]
  # NÃO tem create/delete, secrets, nem acesso a outros namespaces
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: agente-ia-nivel3
  namespace: app-pagamentos
subjects:
  - kind: ServiceAccount
    name: agente-ia
    namespace: app-pagamentos
roleRef:
  kind: Role
  name: agente-ia-nivel3
  apiGroup: rbac.authorization.k8s.io

Para conferir o que ele pode ou não fazer:

$ kubectl auth can-i patch deployments -n app-pagamentos \
    --as=system:serviceaccount:app-pagamentos:agente-ia
yes

$ kubectl auth can-i delete pods -n app-pagamentos \
    --as=system:serviceaccount:app-pagamentos:agente-ia
no

Guardrails que valem para gente e para máquina

  • Permissão mínima: identidade própria, nada de reaproveitar o kubeconfig de admin.
  • Caminho oficial: se o time muda via PR e pipeline, o agente também.
  • Ambientes separados: agente de homologação não tem credencial de produção.
  • Auditoria: cada ação registra o quê, por quê e quem aprovou.
  • Limite de velocidade: um humano errado apaga um recurso; um agente em loop apaga duzentos.
  • Botão de parar: uma forma simples, conhecida por todos, de desligar o agente.
⚠️ Atenção: o agente lê logs, tickets e commits. Qualquer um desses textos pode conter instruções escritas por alguém mal-intencionado. Trate tudo o que ele lê como dado, nunca como ordem.

E quando der errado, quem responde?

Culpar "a IA" não ajuda ninguém. Ela não vai à reunião de postmortem. O agente é uma ferramenta; a responsabilidade é de quem definiu o que ela podia fazer. As perguntas do postmortem continuam as mesmas:

  • Por que ele tinha permissão para isso?
  • Por que essa ação não passou por aprovação?
  • Por que ninguém percebeu que o raio de impacto era tão grande?

Nenhuma delas é sobre o modelo. Todas são sobre o sistema em volta dele.

Considerações Finais

Agentes de IA vão fazer parte da operação, assim como a pipeline e o autoscaler. Bem usados, tiram muito trabalho repetitivo e muita madrugada mal dormida do caminho.

Comece pelo nível mais baixo, meça e aumente a autonomia conforme o histórico justificar. No fim do dia, alguém precisa explicar por que aquela ação aconteceu em produção.

E esse alguém ainda é você.

Abs e até a próxima!!!

:wq!