Problema#
Este é um laboratório de aprendizado, não experiência profissional em Kubernetes. A API (car_api) e a parte de DevOps (Kubernetes, Helm e GitOps) vêm do treinamento da pycodebr, com a parte de DevOps de Mateus Muller. O objetivo foi seguir o treinamento e reproduzir a infraestrutura e o pipeline, com os ajustes listados abaixo.
Arquitetura do projeto#
- Local (kind): cluster kind com um control-plane e dois workers. O Kong recebe as requisições por Ingress e encaminha para o Service do car-api. O PostgreSQL roda no cluster como StatefulSet.
- AWS (EKS): cluster EKS na versão 1.34, com um node group de instâncias t4g.small. O Ingress usa o ALB do AWS Load Balancer Controller. O banco é um RDS PostgreSQL 17.6 nas subnets privadas.
- Entrega: o pipeline gera as imagens e o chart Helm, publica no ECR e atualiza a versão no repositório GitOps. O Flux reconcilia o HelmRelease no cluster.
Decisões técnicas e o motivo#
- Ingress no caminho ativo, Gateway API fora dele: os values de cada ambiente ativam o Ingress:
kongno local ealbna AWS. O HTTPRoute do chart fica desligado. Existe um manifest de Gateway API no diretório local, mas ele não está no caminho dos values. - Segredos pelo External Secrets: na AWS,
DATABASE_URLeJWT_SECRET_KEYvêm de parâmetros do SSM, por meio de um ClusterSecretStore. O chart cria o Secret a partir deles. Assim, as credenciais ficam fora do chart. - GitOps com Flux: o pipeline não aplica manifests no cluster. Ele atualiza a versão do HelmRelease no repositório GitOps, e o Flux reconcilia. O estado do cluster fica versionado num repositório separado.
- Terraform da AWS: VPC com três AZs, subnets públicas e privadas e um NAT gateway. EKS com CoreDNS, kube-proxy, VPC CNI e pod identity agent. RDS na subnet privada, role OIDC para a CI e add-ons de Load Balancer Controller, Cluster Autoscaler, metrics server e External Secrets.
- Ajustes em relação ao treinamento: três réplicas do car-api no kind (a referência usa uma); o external-dns desligado no Terraform; busca de carros por cor e filtro por proprietário no código da API. Dos arquivos presentes nos dois repositórios, 40 são idênticos ao oficial. Os demais diferem em versões, nomes e configuração.
Desafios reais#
- Race do webhook do Load Balancer Controller: o Terraform desativa
enableServiceMutatorWebhook. O webhook do Service é registrado antes de os pods do controller terem endpoints, e isso atrapalhava outros releases Helm no mesmo apply. O comentário no código documenta o motivo.
O que eu faria diferente#
- Um repositório para código e pipeline: o
.gitlab-ci.ymlroda no repositório car_api. A cópia dentro de project-03 é idêntica, mas nessa pasta ela não roda, porque o repositório de labs não tem CI na raiz. - Versão da imagem: o job de build usa a tag fixa
1.0.0. A variávelVERSIONé calculada, mas não é usada. - Valores de teste no GitOps: o HelmRelease tem credenciais de teste em texto puro. Eu moveria tudo para o SSM e tiraria esses valores do repositório.
- Exposição: o Ingress do ALB está habilitado, mas com host de exemplo e sem TLS no HelmRelease. Eu só exporia o serviço com domínio e certificado configurados.
Tecnologias#
FastAPI, SQLAlchemy, Alembic, PostgreSQL, Docker, Kubernetes (kind e EKS), Helm, Flux, External Secrets, Kong, AWS (EKS, RDS, ECR, SSM, ALB), Terraform, GitLab CI, MkDocs.