Clusters · Web · Pro e Team

Bastion: um jump host dentro do cluster Kubernetes

No navegador não existe a sua máquina para abrir um túnel, então o Bastion leva o terminal para dentro do cluster Kubernetes, como um jump host: um pod temporário e sem privilégios no namespace que você escolher, de onde você usa ssh, curl, nc e afins contra VMs, bancos e serviços que o cluster alcança.

Onde
Web
Planos
Pro e Team
Papel
Só admin

O que faz

  • Cria um pod temporário no namespace escolhido e abre um terminal nele, no painel inferior.
  • A imagem é docker.io/nicolaka/netshoot:v0.16@sha256:b09d9b21381f47a79b3cbcb30da25266dc17186ea00ae65e99fdc51396f48e70 (fixada por digest).
  • Ferramentas da imagem: ssh, scp, sftp, curl, dig, nslookup, host, nc, socat, telnet, nmap (-sT), iperf3, openssl, ip, ss, jq, git e vim.
  • Opcional: uma chave SSH privada, enviada uma vez ao pod e gravada em memória em ~/.ssh/id_kubepier. Ela nunca é guardada no Kubepier nem em log e some com o pod.
  • Na web não há túnel para a sua máquina: para isso existe o Túnel seguro do desktop.

Como o pod do bastion é criado

  • Perfil PodSecurity "restricted": usuário 1000 (não root), sem escalada de privilégio, sem capabilities, seccomp RuntimeDefault e sistema de arquivos raiz só leitura.
  • HOME (16 Mi) e /tmp (64 Mi) ficam em memória.
  • Sem token de ServiceAccount e sem variáveis de Service: o pod não fala com a API do Kubernetes.
  • Pede 50m de CPU e 64 Mi de memória, com limite de 500m e 256 Mi.
  • Sem privilégio não há socket raw: ping, mtr, traceroute e tcpdump não funcionam. Use nc -vz host porta ou curl.

Qual usar?

FerramentaOndeDe onde a conexão parteUse quando
Shell no podWeb e desktopDe dentro de um container da aplicaçãoVocê precisa entrar num container que já roda.
Shell no nóWeb (admin) e desktopDe um pod privilegiado no próprio nóO problema é do nó: kubelet, disco, rede do host.
BastionSó webDe um pod temporário sem privilégios no namespaceVocê quer testar ou acessar, pelo navegador, um host que só o cluster alcança (ssh, curl, nc).
Túnel seguroSó desktopDa sua máquina, passando pelo clusterVocê quer usar os clientes da sua máquina (psql, DBeaver, navegador, ssh) contra um serviço do cluster ou um host da rede dele.

Passo a passo: pré-requisitos

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: kubepier-bastion
  namespace: <namespace>
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create", "get", "delete", "list"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create", "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubepier-bastion
  namespace: <namespace>
subjects:
  - kind: ServiceAccount
    name: kubepier-leitura
    namespace: kubepier
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubepier-bastion
  • Organização no Pro ou no Team, e você com papel de admin.
  • A credencial do cluster precisa de create, get e delete em pods e create em pods/exec no namespace. list em pods é opcional: serve para apagar bastions seus que sobraram. Aplique o Role abaixo, trocando o sujeito pela identidade da credencial do cluster.
  • Rede: o bastion só alcança o que a rede do cluster alcança. NetworkPolicies do namespace valem para ele, e NSGs ou security groups da sub-rede dos nós podem bloquear o destino.

Passo a passo: abrir

  • Abra o cluster e clique em Bastion, no menu lateral.
  • Em Namespace, informe onde o pod vai rodar (letras minúsculas, números e hífen; o padrão é default).
  • Se for usar ssh com chave, cole a chave em Chave SSH privada (opcional), ou use Carregar arquivo. Mostrar e Ocultar alternam a visualização.
  • Clique em Abrir bastion. A tela mostra cada etapa: criando o pod, esperando um node, baixando a imagem, rodando e, se houver, chave gravada em ~/.ssh/id_kubepier.
  • O terminal abre quando o pod fica Running (até 120 segundos).

Passo a passo: usar

Exemplos para copiar no terminal do bastion:

# SSH até uma VM interna (com a chave colada ao abrir)
ssh -i ~/.ssh/id_kubepier ubuntu@10.0.1.20

# A porta do banco responde?
nc -vz db.interno 5432

# Health check de um serviço interno
curl -v http://servico.interno:8080/health

# Resolução de nome dentro do cluster
dig api.interno

# Copiar um arquivo de um host interno para outro, passando pelo bastion
scp -i ~/.ssh/id_kubepier ubuntu@10.0.1.20:/var/log/app.log /tmp/
scp -i ~/.ssh/id_kubepier /tmp/app.log ubuntu@10.0.1.21:/tmp/

HOME e /tmp ficam em memória e somem quando o bastion fecha. Para trazer arquivos para a sua máquina, use o Túnel seguro do desktop.

Passo a passo: fechar

  • Feche o terminal: o pod é apagado na hora.
  • O pod também acaba sozinho em 2 horas, num erro, ou se não ficar Running em 120 segundos.
  • Depois que a sessão termina, Novo bastion abre outro.

O que é aceito

  • Um namespace existente em que a credencial possa criar pods.
  • Uma chave privada no formato BEGIN ... PRIVATE KEY, de até 16 KB.

O que não é aceito

  • Plano Free; membro.
  • Mais de um bastion seu no mesmo cluster.
  • Abrir com 3 terminais já abertos (o bastion conta no limite de shells).
  • Uma chave que não parece chave privada: o terminal abre sem ela.
  • Túnel para a sua máquina (só no desktop).

Limites e tempos

LimiteValor
Espera o pod ficar Running120 segundos
Duração máxima2 horas
Bastions por cluster1 por pessoa
Terminais abertos (shell e bastion)3 por pessoa
Chave SSHaté 16 KB
Recursos do pod50m/64 Mi pedidos, 500m/256 Mi de limite

Auditoria

  • Abertura e fechamento vão para a auditoria da organização (bastion_abrir e bastion_fechar), com quem, quando, cluster, namespace, pod e a duração.
  • Nunca o que é digitado, a saída do terminal nem a chave.

Erros comuns

  • Sem permissão: a credencial precisa de create, get e delete em pods e create em pods/exec no namespace.
  • PodSecurity recusou: o bastion já segue o perfil restricted; confira o rótulo de PodSecurity do namespace.
  • Política de admissão recusou: Kyverno, Gatekeeper ou um webhook exige outra coisa, como imagens do registry interno.
  • Imagem não baixou: os nodes não saem para o Docker Hub: espelhe docker.io/nicolaka/netshoot:v0.16@sha256:b09d9b21381f47a79b3cbcb30da25266dc17186ea00ae65e99fdc51396f48e70 no seu registry.
  • ResourceQuota: o namespace não comporta 50m/64 Mi pedidos e 500m/256 Mi de limite.
  • Não ficou Running em 120 s: o pod foi apagado; confira os eventos do namespace.
  • Namespace não existe: confira o nome.
  • "Too Many Requests": você já tem um bastion neste cluster ou 3 terminais abertos.