oci-prd · namespace iam · context-csyhqbid7pq

Keycloak oci-prd

Recursos, capacidade e operação do mobiis-iam-admin — o Keycloak que autentica o WMS em produção. Retrato colhido do cluster em 19/08/2026, 17:53 UTC, logo após a triplicação dos limites.

Keycloak 26.0.8 Quarkus 3.15.1 imagem mobiis-iam-admin:0.10.0 host iam.mobiis.com.br QoS Burstable generation 10
Pod
1/1 Running
6c4447b756-wnf49 · 0 restarts
Endpoint SSO
HTTP 200
0,134 s · /.well-known
ArgoCD
Sync Unknown
quebrado desde 13/05/2026
Probes
Ausentes
sem liveness nem readiness
Memória em uso
795 MiB
26% do limite — era 86%
CPU em uso
15 m
1% do request de 1500m
Folga de memória
2277 MiB
antes eram 140 MiB
Réplicas
1 / máx 1
HPA travado — sem HA

Consumo contra os novos limites

kubectl top pod -n iam

A barra é o consumo real do pod. As marcas fixas são o request (o que o agendador reserva) e o limit (onde o kernel mata o processo). A escala vai de zero até o limite.

Memória 795 MiB usados · request 2304 MiB · limit 3072 MiB
CPU 15 m usados · request 1500 m · limit 1800 m
consumo medido request / limit configurados

O pico de CPU medido foi 652 m, durante os ~8 s de augmentation do Quarkus no start. Em regime, o Keycloak fica em 15–18 m. O request de 1500 m reserva 100× o consumo ocioso.

O que mudou em 19/08

generation 9 → 10

Quatro valores triplicados, mais uma troca de estratégia de rollout para que a subida não derrubasse o login. Cada par mostra o valor antigo em tom claro e o novo em tom escuro.

request CPU
500m
1500m
limit CPU
600m
1800m
request memória
768Mi
2304Mi
limit memória
1024Mi
3072Mi
antes de 19/08 agora
CampoAntesAgoraFatorEfeito
requests.cpu500m1500m3,0×Reserva no agendador
limits.cpu600m1800m3,0×Teto antes do throttling
requests.memory768Mi2304Mi3,0×Reserva no agendador
limits.memory1024Mi3072Mi3,0×Teto antes do OOMKill
maxUnavailable10Rollout sem derrubar o login
maxSurge25% (implícito)1Pod novo sobe antes do antigo sair

Onde esse pod ainda cabe

requests.cpu = 1500m

O efeito colateral menos óbvio de triplicar o request: ele restringe onde o agendador pode colocar o pod. As barras mostram a CPU livre de cada node contra os 1500 m que o pod agora exige.

10.0.10.144
E3.Flex · 1830m
1025m livres
✕ não cabe
10.0.10.160
E3.Flex · 1830m
996m livres
✕ não cabe
10.0.10.230
E3.Flex · 7803m
6466m livres
✓ cabe
10.0.10.45
virtual node
elástico — pod está aqui
✓ cabe
CPU livre suficiente CPU livre insuficiente linha dos 1500m exigidos

Com o request antigo de 500 m o pod cabia em todos os nodes. Hoje ele só cabe no .230 e nos virtual nodes — e os virtual nodes não têm taint, então nada garante que ele fique lá. Se o .230 encher e os virtual nodes ficarem indisponíveis, o pod entra em Pending.

Planejador de recursos

gera o patch pronto

Ajuste os quatro valores e o painel recalcula a folga sobre o consumo medido, checa em quais nodes o pod caberia e escreve o comando exato. Nada aqui toca o cluster — o comando é gerado para você conferir e rodar.

1500m
1800m
2304Mi
3072Mi
Folga sobre o uso medido
Uso atual vs limite
Classe de QoS
Alvo do HPA (85%)
Patch — aplica direto (ArgoCD do iam está parado)

      
Manifesto — oci-prd/iam/mobiis-iam-admin/deployment.yaml

      

Rode o patch com --dry-run=server antes do apply de verdade: o API server valida o objeto inteiro e devolve o resultado sem gravar nada.

Operação do dia a dia

context-csyhqbid7pq

Os comandos que resolvem 90% do que se faz nesse deployment. Todos já vêm com o contexto e o namespace corretos — o cluster de produção não é o contexto padrão da sua máquina.

Ver o estado agora

leitura

Pod, recursos configurados e consumo real numa passada só.

kubectl --context=context-csyhqbid7pq -n iam get pod,deploy,hpa -o wide && kubectl --context=context-csyhqbid7pq -n iam top pod

Acompanhar um rollout

leitura

Com maxUnavailable: 0, o pod novo precisa ficar Ready antes do antigo morrer. Se travar aqui, é o pod novo que não subiu.

kubectl --context=context-csyhqbid7pq -n iam rollout status deploy/mobiis-iam-admin --timeout=180s

Logs do Keycloak

leitura

O start completo leva ~8 s de augmentation do Quarkus e mais ~8 s de boot.

kubectl --context=context-csyhqbid7pq -n iam logs -f deploy/mobiis-iam-admin --tail=100

Testar o SSO de fora

leitura

Vale mais que o status do pod: confirma que Caddy, DNS e Keycloak estão respondendo de ponta a ponta.

curl -s -o /dev/null -w "HTTP %{http_code} em %{time_total}s\n" https://iam.mobiis.com.br/realms/master/.well-known/openid-configuration

Reiniciar sem derrubar o login

escrita

Seguro por causa do maxSurge: 1 / maxUnavailable: 0. As sessões em memória do Infinispan se perdem de qualquer forma — quem estiver logado segue logado pelo token, mas o cache de sessão zera.

kubectl --context=context-csyhqbid7pq -n iam rollout restart deploy/mobiis-iam-admin

Voltar atrás

escrita

Desfaz o último rollout. Como o ArgoCD do iam está parado, ninguém vai sobrescrever a reversão.

kubectl --context=context-csyhqbid7pq -n iam rollout undo deploy/mobiis-iam-admin

Conferir se o GitOps voltou

leitura

Enquanto o sync não voltar a Synced, commit no repositório não altera nada neste namespace.

kubectl --context=context-csyhqbid7pq -n shared-services get application iam -o custom-columns='SYNC:.status.sync.status,HEALTH:.status.health.status,REPO:.spec.source.repoURL'

Pendências abertas

7 itens

Tudo abaixo foi observado no cluster em 19/08. Nenhum item é consequência da mudança de recursos — são condições que já existiam e continuam valendo.

▲ crítico

Keycloak rodando em modo de desenvolvimento

O log de boot diz literalmente Profile dev activated e Running the server in development mode. DO NOT use this configuration in production. O container sobe com start-dev.

Em dev mode o Keycloak relaxa exigências de HTTPS, não habilita cache distribuído e usa configuração pensada para desenvolvimento local — num IdP que autentica o WMS inteiro.

▲ crítico

Segredos em texto plano no repositório

O configmap.yaml carrega senha do Postgres, senha do admin do Keycloak e senha do Redis commitadas — contra a regra escrita no próprio CLAUDE.md do gitops, que manda usar Secrets via secretRef.

Os valores não estão reproduzidos neste painel de propósito. São 22 chaves no ConfigMap, 4 delas sensíveis.

▲ crítico

ArgoCD do iam parado há três meses

O Application iam ainda aponta para git@bitbucket.org por SSH e falha com error creating SSH agent: SSH_AUTH_SOCK not-specified desde 13/05/2026. Os apps wms e base-de-precos já migraram para o remote do Azure DevOps.

Consequência prática: commit no gitops não aplica nada no iam. Religar exige janela controlada — o sync está com prune: true depois de três meses sem convergir. Em 19/08 não havia drift entre o cluster e o git, o que torna a religada mais previsível.

● atenção

Sem liveness nem readiness probe

O container não declara nenhuma das duas. Sem readinessProbe, "Ready" significa apenas que o processo iniciou — o maxUnavailable: 0 protege menos do que aparenta, porque o Kubernetes considera o pod novo pronto antes do Keycloak terminar de subir.

O Keycloak 26 expõe /health/ready e /health/live quando KC_HEALTH_ENABLED=true.

● atenção

Uma réplica, HPA travado em 1

minReplicas: 1 e maxReplicas: 1 — o autoscaler existe mas não pode escalar. Qualquer perda do pod é indisponibilidade total do SSO até ele voltar, e o ganho de CPU não vira capacidade de atender mais login concorrente.

● atenção

Request de CPU muito acima do consumo

O aumento de memória resolveu um problema real: o pod vivia a 86% do limite. Já o request de CPU foi de 500 m para 1500 m enquanto o consumo em regime é de 15 m e o pico de start foi de 652 m.

O custo disso é concreto: o pod deixou de caber em dois dos três nodes VM, e em virtual node a OCI cobra pelo request. Manter o limit alto dá folga para picos sem esse custo — é o que o cenário "Sugerido" do planejador modela.

■ informativo

Configuração de hostname legada

O boot avisa: Hostname v1 options [hostname-admin-url, hostname-url, proxy, hostname-strict-https] are still in use. São opções da v1 depreciadas no Keycloak 26 — funcionam hoje, quebram numa atualização maior. Há também um JDBC resources leaked: 3 ResultSet(s) no start.