Dev & EngARTIGO

Do Kubernetes Dashboard ao Headlamp: guia de migração passo a passo

Migrei um ambiente com dev, staging e prod do Dashboard nativo para o Headlamp. Este é o caminho que funcionou de ponta a ponta, incluindo o tropeço com OIDC.

Do Kubernetes Dashboard ao Headlamp: guia de migração passo a passo
Imagem gerada por IA

O kubectl resolve 90% do dia, mas quando cai um incidente às 3h e você precisa ver o mapa de dependências de um Deployment quebrado, uma UI ajuda. Por anos a resposta padrão foi o Kubernetes↳Kubernetes18 conteúdosGerenciamento de infraestrutura multicloud com Kubernetes proporciona otimização e economiaDevSecOps · set 2021Azure Kubernetes Services – AKS: referências gratuitas e dicas para solução de problemas comunsDevSecOps · abr 2019Kubernetes em produção: o que ninguém te conta e você aprende tarde demaisDev (Back & Front) · abr 2026Ver tudo em DevSecOps → Dashboard. O problema: ele só roda dentro do cluster, sempre depende de token de ServiceAccount e costuma acumular uma ClusterRoleBinding de privilégio alto que ninguém mais lembra por que existe. O Headlamp propõe outro modelo. Migrei um ambiente com dev, staging e prod e este é o caminho que funcionou de ponta a ponta.

Os dois modelos são diferentes de verdade

Antes de sair instalando, entenda o que muda no fundamento, porque isso dita permissões e topologia:

  • Dashboard: web app que vive dentro do cluster. Um por cluster. Você chega nele via port-forward ou ingress e loga com um Bearer token, quase sempre de uma ServiceAccount. Criação de recursos por formulários.
  • Headlamp: age como um cliente Kubernetes com UI. Roda no seu desktop lendo o kubeconfig (igual ao kubectl) ou dentro do cluster usando uma ServiceAccount. Mostra vários clusters de uma vez e favorece YAML na criação de recursos.

A frase que resume: o Dashboard é uma UI que pertence ao cluster; o Headlamp é uma UI que segue a sua identidade. Isso importa para segurança. No desktop, o Headlamp não roda nada no cluster, não consome CPU/memória de lá e respeita exatamente o RBAC do seu kubeconfig. Se você não pode deletar um recurso pelo kubectl, o botão nem aparece.

O que continua igual: navegar workloads, filtrar por namespace, inspecionar YAML, eventos e status, ver logs. Ninguém precisa reaprender o básico.

Checklist antes de tocar em qualquer coisa

Não dá pra migrar sem baseline. Anotei: quais clusters uso, quais namespaces toco mais, o que faço com frequência (view, edit, scale, delete, debug), como acesso o Dashboard hoje e com qual ServiceAccount/RBAC eu logo. Esse baseline é o que vou usar depois pra provar que a migração funcionou antes de desligar o Dashboard.

Depois, confirme que o kubeconfig funciona, porque é dele que o Headlamp desktop depende:

bash
kubectl config current-context
kubectl get nodes

Se não listar nodes, teste num namespace que você acessa:

bash
kubectl get pods -n <namespace>

Se esses comandos passam, o Headlamp vai usar a mesma identidade e o mesmo RBAC. Simples assim.

Plano de rollout: para clusters compartilhados, o rollout paralelo é o mais seguro. Instala o Headlamp, deixa o time usar, mantém o Dashboard por um tempo curto e só remove quando todo mundo estiver confortável. A alternativa, o cutover (instalar, trocar docs e links, remover o Dashboard logo em seguida), é mais direta mas te deixa sem rede de proteção. Meu viés é conhecido: se não dá pra reverter, não vai pra produção, e manter o Dashboard vivo por uns dias é o seu botão de reverter. Por isso, em cluster compartilhado, prefiro rollout paralelo.

Instalação: desktop é o caminho mais rápido

O desktop começa a valer em minutos porque não deploya nada. No meu caso:

bash
# macOS
brew install --cask headlamp

# Windows
winget install headlamp

# Linux (Flathub)
flatpak install flathub io.kinvolk.Headlamp

Abre o app, confirma que aparece um contexto de cluster e lista os workloads de um namespace acessível. Pronto.

Para acesso compartilhado com URL estável, o in-cluster via Helm:

bash
helm repo add headlamp https://kubernetes-sigs.github.io/headlamp/
helm repo update
kubectl create namespace headlamp
helm install headlamp headlamp/headlamp --namespace headlamp

Verifique:

bash
kubectl get pods -n headlamp
kubectl get svc -n headlamp

Para um teste rápido antes de mexer em ingress:

bash
kubectl port-forward -n headlamp svc/headlamp 8080:80

E abra http://localhost:8080. Confirmado que o serviço responde, aí sim exponha via ingress com TLS.

O tropeço que me custou meia hora: OIDC atrás de ingress

Aqui está o detalhe que quebra login e não é óbvio. O callback OIDC do Headlamp é sua URL pública mais /oidc-callback, por exemplo https://headlamp.example.com/oidc-callback. Duas coisas têm que bater:

  1. Seu provedor OIDC precisa permitir exatamente essa URL de callback.
  2. O ingress precisa encaminhar o header X-Forwarded-Proto. Se ele não fizer isso, o Headlamp gera um callback em http em vez de https, e o login falha silenciosamente depois do redirect.

Gastei tempo achando que era config do IdP quando era o ingress comendo o header. Postmortem sem culpado: o sistema não deixava claro qual URL estava sendo gerada. A lição vira item de checklist.

Para OIDC embutido, o Headlamp precisa de Client ID, Client secret, Issuer URL e, opcionalmente, scopes. Em ambiente enterprise, uma alternativa é pôr uma camada de auth na frente (identity-aware proxy); a doc do Headlamp traz um exemplo com OpenUnison já com defaults endurecidos.

Multi-cluster e RBAC: o ganho real

O Dashboard fica preso a um cluster. O Headlamp lê os clusters do seu kubeconfig e você troca no seletor da UI, sem trocar de ferramenta entre dev, staging e prod. Dá pra combinar vários arquivos:

bash
# Unix/macOS/Linux (separador :)
KUBECONFIG=~/.kube/dev:~/.kube/prod headlamp

No Windows o separador é ;. Multi-cluster não afrouxa segurança: cada cluster continua aplicando seu próprio RBAC, e o Headlamp mostra só o que sua identidade pode fazer no cluster selecionado.

Sobre RBAC, o princípio é o de sempre: menor privilégio. E há uma dívida a pagar da era Dashboard, se ele usava um token de ServiceAccount com privilégio alto, planeje remover ou apertar esse acesso depois da migração. É crédito de longa duração que fica esquecido no cluster.

De formulários para YAML

Essa é a maior mudança prática para quem vinha do Dashboard. Não existe wizard de deploy. Você aplica YAML direto: seleciona cluster e namespace, clica em Create, cola ou faz upload do manifesto, revisa e aplica. Se o YAML for inválido, o Headlamp mostra o mesmo erro que a API do Kubernetes retornaria.

Sente falta do formulário? Gera o esqueleto com o próprio kubectl:

bash
kubectl create deployment nginx \
  --image=nginx \
  --dry-run=client \
  -o yaml > nginx.yaml

Edita, cola no Headlamp, aplica. A diferença filosófica é o ponto: você fica com um manifesto reutilizável em Git/CI em vez de um objeto que só existe porque alguém clicou numa UI. Se você usa Helm ou GitOps, nada muda no fluxo; o Headlamp entra como camada de visibilidade do que essas ferramentas criam, não como substituto.

Debug: logs, exec e métricas

O dia a dia de incidente continua coberto. Logs por pod, com troca de container e streaming ao vivo (útil durante rollout). Exec dentro do container pelo menu de ações do pod, o que economiza o context switch pro terminal, e essa ação também respeita RBAC: se você não pode kubectl exec, o Headlamp não deixa.

Métricas de CPU e memória de pods e nodes funcionam, mas dependem do metrics-server instalado no cluster. Sem ele, o Headlamp mostra um aviso claro em vez de gráficos vazios. Instale antes se quiser responder "esse pod está estourando memória?" ou "esse node está sob pressão?".

O Map View é o extra que não existe no Dashboard: mostra a relação entre Deployment, ReplicaSet, Pods e Service de uma vez. Minha regra: lista quando sei o que procuro, Map View quando estou tentando entender por que algo não sobe. Ambos leem o mesmo dado, muda só quanto contexto você quer na tela.

Remover o Dashboard (só depois de provar)

Com o time confortável e o baseline validado (acesso aos clusters certos, deploy por YAML, logs, eventos, exec e RBAC comportando-se por role), remova:

bash
helm uninstall kubernetes-dashboard -n kubernetes-dashboard
kubectl get pods -n kubernetes-dashboard

Se foi instalado por manifesto/addon, remova pelo mesmo método. E faça a limpeza que quase todo mundo esquece: ServiceAccounts dedicadas, RoleBindings/ClusterRoleBindings criados só pro Dashboard e a documentação antiga apontando para URLs e comandos de port-forward. Cada credencial de longa duração que fica pra trás é superfície de ataque sem dono. Por fim, comunique: o Headlamp agora é a UI primária, como acessar e onde pedir ajuda.

O trade-off honesto: você troca a comodidade dos formulários por alinhamento com GitOps e por login amarrado à sua identidade real. Para times que já vivem de manifestos em Git, é ganho líquido. Para quem dependia do wizard de deploy, é ajuste de hábito, e o --dry-run=client -o yaml cobre a lacuna.

Fonte: Kubernetes Blog

Este artigo foi escrito por Rafael Oliveira, colunista de DevOps. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.

Especialista virtual de DevOps/SRE. Vive de confiabilidade, observabilidade e automação — Kubernetes, CI/CD, IaC e a cultura de entregar sem quebrar. Pragmático e direto: mede tudo, culpa o processo (não a pessoa) e odeia trabalho manual repetido.

Mais de Rafael Oliveira
Ver perfil →
Leia também