Cliente: Teste5
Assinatura: sub_zx7fdtz40b8is2gk
Plano: (nao informado)
Realm: athleticmap-9
Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
Pedi get/list em namespaces para a etapa ARGO_SINCRONIZADO provar que o
Argo aplicou. NAO FUNCIONA: o ClusterRole e ligado a conta por
RoleBinding POR TENANT, e RoleBinding so concede DENTRO do seu
namespace. `namespaces` e recurso de cluster, entao a resposta continua
negada -- e o que resolveria e um ClusterRoleBinding, porta bem mais
larga do que a pergunta.
A etapa passou a provar pelo Secret db-credentials do tenant, que
responde a mesma coisa e um pouco mais: para ele ser legivel o Argo teve
de criar namespace, Role, RoleBinding e SealedSecret, e o controlador
teve de abri-lo. Permissao que ninguem usa nao se pede.
A etapa ARGO_SINCRONIZADO concluia no `git push`, que e outra coisa:
entre empurrar e aplicar esta o ciclo do gerador de diretorio do
ApplicationSet. A etapa seguinte encontrava o namespace inexistente e
recebia 403 -- sem permissao dentro dele, a API nao diz "nao existe",
diz "nao pode" -- e queimava tentativas esperando por algo que nao era
trabalho dela.
get e list, so em namespaces. O que isto revela e o NOME dos namespaces,
para um servico que e justamente quem os cria.
Cliente: Zico 0
Assinatura: sub_dgoho9lkia9wfaqp
Plano: (nao informado)
Realm: athleticmap-8
Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
Os dois tenants pagos estavam presos em `1.1-demo` desde 24/09 23:43,
sem conseguir ir para `1.2-auditoria`. O ArgoCD dizia Synced: o
Deployment batia com o git. O que nao acontecia era o rollout.
Em repouso os cinco Deployments somam 2944Mi. O maxSurge de 25% sobre
uma replica arredonda para cima e pede um pod inteiro a mais: 768Mi,
quando o que troca e um runtime. 2944 + 768 = 3712, contra 3584.
O cabecalho do arquivo ja tinha essa licao escrita -- para `pods`, que
derrubou o provisionamento do plataforma em 17/09. A memoria nao ganhou
o mesmo tratamento. Agora a regra esta escrita uma vez, para todos os
tetos, e o paragrafo velho que ainda dizia `pods: 8` saiu.
So limits.memory travava: medido hoje, requests.memory tinha 560Mi
livres (a troca pede 400), requests.cpu 1100m (pede 100), limits.cpu
1300m (pede 1000) e pods 5 de 10.
O script de rotacao usou `bash -s` com o roteiro E a senha no mesmo stdin: o
`read` consumiu linha do proprio roteiro, e o Secret foi selado com lixo (54
caracteres). O pod nao tinha reiniciado, entao o e-mail continuava funcionando
pela variavel ja carregada — mas o proximo restart quebraria.
Volta ao selo que funciona. A senha nova sera aplicada pelo script corrigido.
A prova de ponta a ponta terminou. Com o bloco no ar, /planos devolvia bronze
mensal 5,00 contra anual 1.870,00 — e a landing page mostraria os dois lado a
lado.
A contratacao pela landing page. Aqui nao ha catch-all: caminho que nao esta
escrito nao existe — o endpoint respondeu vazio com a imagem ja no ar porque o
servico tinha a rota e o Ingress nao.
internationalizationEnabled vem FALSE por padrao no Keycloak, e ai ele cai no
en — o e-mail sairia em ingles mesmo com o emailTheme certo. defaultLocale
pt-BR e supportedLocales so pt-BR: uma opcao so nao mostra seletor de idioma na
tela de login.
Minha insercao anterior casou por substring e caiu no objeto do cliente spa,
onde loginTheme e emailTheme nao querem dizer nada — entao um tenant novo
continuava nascendo com a tela de fabrica, e o commit anterior dizia o
contrario.
Refeito carregando o JSON, tirando as chaves de onde nao pertenciam e provando
que o resto do documento e identico antes de gravar.
O nginx roteia /bff e /api com proxy_pass de variavel, e ai resolve por
requisicao usando a diretiva resolver. O resolver do nginx nao le os dominios
de busca do /etc/resolv.conf: pergunta o nome cru ao CoreDNS, que responde
NXDOMAIN para servico-bff.
O sintoma engana: 502 com could not be resolved no log do nginx, enquanto
getent hosts servico-bff dentro do MESMO pod resolve — porque o getent usa o
search e o nginx nao. E por isso que o escolinha sempre usou FQDN aqui.
O tenant provisionado subia com a tela de login de fabrica e o sistema vazio.
Quatro mudancas, medidas contra o escolinha que e o que funciona:
- 90-servico-bff.yaml: o quinto Deployment. A SPA chama o BFF para quase tudo;
sem ele /bff devolve 502. As URLs apontam para os RUNTIMES, e nao para os
treze servicos — e a diferenca deste molde para o do escolinha.
- a cota sobe para 10 pods e 2Gi: com quatro Deployments o tenant ja usava
1232Mi de 1536Mi, e o BFF pede 256Mi. Caberia em repouso e estouraria no
primeiro rollout.
- loginTheme athleticmap-v2 no realm, com o tema montado no Keycloak
compartilhado.
- imagens alinhadas: frontend 2.67-csp-script e os runtimes 1.2-auditoria.
O que NAO mudou, e por que: ATM_API_URL continua no runtime-operacao e o
Ingress continua com uma rota. Os dois estao certos — o nginx da SPA roteia
/bff e /api por conta propria, e ATM_API_URL e o destino do que nao pertence a
grupo nenhum, hoje o webhook em /api/public. O cabecalho do molde ja dizia.
Vale para TODO tenant provisionado: eles nao tem Keycloak proprio, usam este,
um realm cada. O tema vem por ConfigMap e nao por imagem porque o login.ftl traz
as imagens em data URI — o ConfigMap e montado read-only sobre o diretorio e nao
sobra resources/ para o Keycloak servir.
Sem ele o Keycloak monta os links e o iss com o KC_HOSTNAME global
(auth-plataforma), e os runtimes do tenant validam contra ATM_ISSUER, que o
molde define como auth.athleticmap.com. Os dois tem de bater.
Nao da para resolver so no KC_HOSTNAME porque ele e um so e a plataforma
depende do valor antigo. Dai o frontendUrl por realm, que e para isto.
O molde do tenant ja apontava para ca — a SPA em ATM_KC_URL e os tres runtimes
em ATM_ISSUER — e o host nao existia. O navegador batia em
ERR_CERT_AUTHORITY_INVALID e, passando por cima, em 404 do Traefik.
Nao e auth-plataforma para o cliente: o endereco aparece na barra dele durante
o login, e o nome do nosso tenant interno nao tem o que fazer ali.
A etapa BANCO_CRIADO reinicia o PgBouncer e espera ele voltar. Com 5, o backoff
da 155s — menos do que o pod novo levou nas tres medicoes de hoje, e os dois
clientes pagos precisaram de retomada a mao. Com 8 da 515s, dentro da janela.
So o hostname faz o Keycloak resolver esquema e porta a partir da requisicao.
O provisionamento chama a Admin API por dentro (http://keycloak:8080), e o link
do convite saiu http://auth-plataforma.athleticmap.com:8080 — o cliente clicava
e dava ERR_CONNECTION_TIMED_OUT.
O deny-cross-tenant libera 443 para a internet e nada mais. O Keycloak batia em
Network is unreachable na 587, e o erro que chegava ao provisionamento era
Failed to send execute actions email — que manda procurar no SMTP, nao na rede.
db-credentials (a senha do papel) e <tenant>-tls (so a existencia, que e como a
etapa DNS_PUBLICADO sabe que o cert-manager terminou). Por tenant porque o nome
do TLS depende dele e resourceNames nao aceita curinga — e dar get em qualquer
Secret do namespace deixaria o provisionamento ler a chave Asaas DO CLIENTE.