Gestão eficiente do GKE com Terraform & Kustomize
Gerenciar clusters GKE (k8s) e as aplicações que rodam neles virou uma batalha sem fim para muita gente. Cuidar com precisão de atributos como node-pools, add-ons, ingress controllers, gerenciador de certificados SSL, rollout de aplicações e suas configurações associadas se tornou trabalhoso. E isso ficou ainda mais comum com a ascensão dos microsserviços e das arquiteturas orientadas a eventos, que envolvem muitos componentes.
Gerenciando clusters GKE (K8S)
Configurar um cluster GKE / K8S é um processo complicado. Uma boa abordagem é automatizar a criação como um artefato de IaC. Neste artigo, vamos usar o Terraform como ferramenta de IaC.
Configuração de IaC
Criar módulos com parâmetros e atributos para cada recurso é fundamental para manter a consistência (paridade) entre ambientes. Teremos 3 módulos no nosso repositório: 1. Módulo de cluster GKE com dois node pools. 2. Módulo do nginx ingress controller usando o provisionador de helm chart. 3. Módulo do kcert, provedor de certificados SSL Let's Encrypt para seus endpoints públicos.
O código de todos os módulos abaixo está disponível no nosso repositório em : https://github.com/agileguru/gke_nginx_kcert_quick_start
- Provisionando o cluster GKE com múltiplos node-pools
Neste módulo, temos main.tf, variables.tf e outputs.tf, responsáveis por provisionamento, parametrização e metadados reutilizáveis de um cluster GKE, respectivamente.

Captura de tela do módulo de IaC do GKE em Terraform
- Instalação do nginx ingress controller Neste módulo, temos main.tf, variables.tf e um outputs.tf opcional (vazio), responsáveis por provisionar e parametrizar o nginx controller, respectivamente.

Captura de tela do main.tf do provisionador de IaC do NGINX em Terraform
- Instalação do gerenciador SSL kcert Let's Encrypt Neste módulo, temos main.tf, variables.tf e um outputs.tf opcional (vazio), responsáveis por provisionar e parametrizar o controlador SSL kcert, respectivamente.

Captura de tela do main.tf do provisionador de IaC do Kcert em Terraform
- Orquestrando tudo
Depois de finalizar os 3 módulos, vamos criar um ambiente k8s "devops" por meio do módulo "devops", chamado a partir do main / root, que amarra tudo.

Captura de tela do módulo de ambiente k8s Devops

Captura de tela do root orquestrando a criação do módulo Devops
- Provisionando o cluster e os controladores com Terraform\* Altere os nomes de project, region e zone em variables.tf
\* Altere o nome do bucket em backend.tf depois de criá-lo no console do GCP
\* Execute os comandos a seguir
terraform init
terraform plan -var-file=sample.tfvars (altere sample.tfvars se necessário)
terraform apply -var-file=sample.tfvars (altere sample.tfvars se necessário)

- Depois de executar os comandos do Terraform, você terá o endereço IP do LoadBalancer para registrar o domínio.
- Você pode obter a config do kubectl com o comando…
gcloud container clusters get-credentials <nome do cluster> — zone <zona do cluster> — project <id do projeto que contém o cluster>
Gerenciando deployments com Kustomize
O cluster já está pronto para o deployment de workloads. Vamos usar o plugin Kustomize para facilitar essa gestão, partindo de um caso de uso simples neste artigo.
- Temos 2 apps, api-1 e api-2, baseadas na imagem tutum/hello-world.
- Temos também 2 namespaces no k8s, correspondentes aos ambientes DEV e SIT.
- Precisamos fazer o deployment do serviço e expô-lo via https (ssl), com as respectivas configurações, deployment, service e mapeamento de ingress.
- Precisamos guardar tudo isso em um repositório. Para a demo, está no nosso repositório em https://github.com/agileguru/kustomize_quickstart_demo
Passo 1: criar a estrutura de pastas

Pastas base de componentes e configurações
Passo 2: customizar cada ambiente com overlays

Pastas de overlays para os ambientes, usando patch / merge config via kustomize.yaml
Passo 3: alterar o mapeamento de hostname do Ingress
Altere o hostname em dev-ingress-patch.json e sit-ingress-patch.json para um host ou domínio válido. O resultado fica parecido com o código abaixo…
[\
{\
"op": "replace",\
"path": "/spec/rules/0/host",\
"value": "dev.agileguru.org"\
},\
{\
"op": "replace",\
"path": "/spec/tls/0/hosts/0",\
"value": "dev.agileguru.org"\
}\
]
[\
{\
"op": "replace",\
"path": "/spec/rules/0/host",\
"value": "sit.agileguru.org"\
},\
{\
"op": "replace",\
"path": "/spec/tls/0/hosts/0",\
"value": "sit.agileguru.org"\
}\
]
Passo 4: fazer o deployment das suas aplicações
$ kubectl apply -k overlays/dev
namespace/dev created
configmap/config-map-api-1 created
configmap/config-map-api-2 created
service/api-1-service created
service/api-2-service created
deployment.apps/api-1-deployment created
deployment.apps/api-2-deployment created
Passo 5: remover o deployment das suas aplicações
$ kubectl delete -k overlays/dev
namespace "dev" deleted
configmap "config-map-api-1" deleted
configmap "config-map-api-2" deleted
service "api-1-service" deleted
service "api-2-service" deleted
deployment.apps "api-1-deployment" deleted
deployment.apps "api-2-deployment" deleted
ingress.networking.k8s.io "app-ingress" deleted
Boas práticas com Kustomize
O que você deve fazer
— Mantenha o Replica Count em 0 na configuração base
— Sempre especifique o Namespace no kustomization.yaml do overlay
— Sempre rode um Dry Run com saída em yaml para garantir a precisão
— Adote boas convenções de nomenclatura para pastas e arquivos de manifest
— Mantenha o mapeamento de Ingress em uma pasta própria
— Sempre tenha um override.yaml para cada componente. 2. O que você não deve fazer
— _Hard-coding de namespace nas configurações base_
— Misturar configurações e código da aplicação na mesma pasta
— Usar branches do Git para configuração de ambientes (o famoso parity drift)
Recursos
- Repositório de introdução do GKE Nginx Kcert: https://github.com/agileguru/gke_nginx_kcert_quick_start
- Repositório Quick Start do Kustomize: https://github.com/agileguru/kustomize_quickstart_demo
- Documentação do Kustomize: https://kustomize.io/
- GitHub do Kcert: https://github.com/nabsul/kcert
- Nginx Controller: https://kubernetes.github.io/ingress-nginx/
- Let's Encrypt: https://letsencrypt.org/
Depois de concluir os passos acima, temos: 1. um k8s fácil de gerenciar e atualizar, com nginx e gerenciador de certificados SSL kcert, sem precisar se preocupar nunca mais com seus certificados SSL nos endpoints públicos; 2. um mecanismo/framework para gerenciar seus endpoints web seguros seguindo os princípios de IaC, DevOps e DRY.