Mais recentes

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

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!

quinta-feira, 15 de outubro de 2026

Kubernetes do Zero - Parte 3: Subindo um "mini cluster" com kind


Fala pessoal, tudo bem?

Na postagem da parte 2, nós criamos um cluster do inicio ao fim, semelhante a forma que criaríamos um cluster kubernetes em um ambiente "corporativo" por assim dizer.

Ambiente virtual, mais de uma máquina, IPs para cada node, instalação de CNI, etc ...

Mas e se não tivermos como subir um ambiente desse porte? Um lugar que possamos apenas usar para estudar boa parte, se não todos, os conceitos do kubernetes?

Pensando nisso, vamos fazer a parte 3 com base nessa possibilidade.

Sem necessidade de hardware parrudo, sem a necessidade de várias máquinas, sem uso de cloud.

Apenas  o nosso notebook (pode ser ele Windows, Linux ou Mac).

Existe uma alternativa muito legal que é o Kind - Kubernetes in Docker.

Ele faz uso do Docker para subir containers que vão simular os nodes do kubernetes.

Site do projeto - https://kind.sigs.k8s.io

A parte legal de olhar sempre o site oficial, é que teremos a documentação atualizada.

Clicando em Quick Start - Installation, temos as instruções para cada tipo de sistema operacional.

O meu é um Debian Linux, então vou seguir o passo a passo do "On Linux".


Essa primeira parte, consiste na verdade em baixar o binário do kind mediante ao seu respectivo host.
Dar permissão de execução ao binário.
Mover para o path default de execução e assim todos os usuários deste computador, terão acesso a rodar o kind.


O próximo passo para testar e ver se tudo deu certo, é executar o comando kind com qualquer usuário.

Obs - no meu caso, eu já baixei e movi o arquivo como root, pois no Debian é um pouco diferente do Ubuntu na questão de usuários. Meu usuário convencional não é adicionado por padrão com permissões sudo. Ele libera diretamente o root.



Primeiro teste executando o kind como root e o segundo com meu usuário convencional.

Até aqui, tudo fácil e mais que lindo/maravilhoso.

Agora, o próximo passo é instalar alguns componentes que o kind vai precisar e nós vamos precisar depois para administrar nosso poderoso cluster kubernetes.

Eu vou fazer por etapas, mas saiba que podemos preparar tudo e depois rodar tudo em uma única instalação. Mas vamos com calma.

Instalando o Docker


# apt install docker.io


Assim que a instalação finalizar, vamos validar se o Docker está em execução:

# systemctl status docker



Por estar usando o Debian, eu tive um passo adicional que foi permitir o meu usuário convencional a ter acesso ao Docker. Para isso, eu adicionei o usuário ao grupo do Docker.
Caso vc também esteja no Debian, basta rodar esse comando como root:

# gpasswd -a joao docker

(tem um modo menos elegante que é dar um vim /etc/group e adicionar o usuário ao final da linha onde contém o nome do grupo do Docker =D ).

Para que seu usuário leia as novas configurações, vc precisará fazer logout e login novamente.

Instalando o kubectl


Para podermos administrar o cluster kubernetes, precisamos do kubectl. Para instalar no Debian:

# apt install kubectl



Agora, temos o nosso ambiente preparado para criarmos o cluster com o kind.

Criando nosso cluster com Kind


Existem duas formas de criamos o cluster:

  1. Rodando diretamente na linha de comando com o kind
  2. Criando um manifesto (arquivo yaml) e pedir ao Kind para ler este arquivo

Vantagem de um para o outro:

  • Direto pelo comando, cria o cluster default mais rápido
  • Pelo manifesto, podemos otimizar e customizar algumas configurações (como quantidade de control-planes, workers, regras de ingress, etc)

Para o nosso lab, vou criar usando o manifesto para garantir que seja criado como eu quero.

Para isso, no linux vamos criar o arquivo conforme abaixo:

$ vi create-kind-cluster.yaml

Dentro dele, teremos o seguinte conteúdo:



kind: Cluster // o tipo de recurso que estamos querendo criar
apiVersion: kind.x-k8s.io/v1alpha4 // a versão da API que vamos usar para isso
name: kind-k8s // o nome que queremos para nosso cluster
nodes: //o bloco onde iremos informar quantos e o tipo de workers que queremos
- role: control-plane // worker do tipo control-plane
- role: worker
- role: worker // tipo worker

Veja que para nosso ambiente, estamos pedindo um recurso do tipo cluster, de nome kind-k8s, 1 node control-plane e 2 nodes worker.

Salve o arquivo.

Agora para podermos iniciar a criação do cluster:

$ kind create cluster --name=create-kind-cluster.yaml


Prontinho!!!
Nosso cluster kubernetes local foi criado.

Vamos conferir?

Temos duas formas...
Uma é a já sugerida pelo kind quando ele termina de criar o cluster:

$ kubectl cluster-info


Podemos usar o comando até o "cluster-info" se tivermos apenas este cluster criado e rodando.
Caso vc tenha mais de um, informar o contexto para o recurso específico.

A outra forma, é ir direto pelo Docker com o comando docker ps, e ver a saída dos containers rodando:

$ docker ps



Exatamente o que pedimos no nosso arquivo yaml

  • 1 control-plane
  • 2 workers

Podemos também rodar:

$ kubectl get nodes



Legal!!!
Mas e agora, como posso testar e ver se ele está pronto para receber meus pods, minhas aplicações para testar?

Vamos subir um pod do nginx para teste...

$ kubectl run nginx --image=nginx --port=80


Para irmos acompanhando se o STATUS do pod muda para Running:

$ kubectl get pods

Dando tudo certo, temos a saída abaixo:



E para testarmos se ele está respondendo:

$ kubectl port-forward pod/nginx 8080:80

Mas o que esse comando faz?

Ele faz o com que nosso pod nginx tenha suporta exposta remotamente na porta localhost:8080.

Abrindo o navegador do nosso computador e acessando http://localhost:8080 veremos a página default do nginx.



Sei lá... tá meio estranho isso! Como vou ter certeza que esse conteúdo é mesmo do pod do nginx que acabamos de subir?

Certo, vamos brincar um pouco dentro do pod.

Para acessar o shell do pod, vamos executar a seguinte linha de comando:

obs - abra uma nova aba do seu terminal para não perdermos o port-forward ...

$ kubectl exec nginx -it -- bash

Esse comando é um exec com o parametro it informando que o comando que queremos executar para este pod é um bash.

Isso nos dará acesso bash direto no pod:


Agora, vamos apagar o conteúdo do arquivo index.html default do nginx:

# echo > /usr/share/nginx/html/index.html

Validar que ele está em branco:

# cat /usr/share/nginx/html/index.html

Agora vamos adicionar um novo conteúdo a ele:

# echo "Site testado no kind-k8s" > /usr/share/nginx/html/index.html


Agora, vamos sair do container com o comando exit

Caso vc tenha parado o port-forward, inicie ele novamente. Caso não, retorne ao navegador e dê um refresh na página http://localhost:8080



Agora vc pode de fato acreditar que subimos nosso cluster kubernetes localmente, ele está funcional, pois conseguimos subir um pod com um nginx, conectar nesse pod, trocar o arquivo html e testar o acesso de fora do cluster.


Por agora é isso.
Temos até aqui, duas opções de lab para testar o que será preparado nas próximas postagens.

Seja no seu cluster com as VMs, CNI, mais de 3 nós ... ou mesmo no nosso kind local com 1 control-plane e 2 workers.

Abs e até o próximo post...
:wq!