GKE Autopilot: Gerenciamento Automático de Clusters Kubernetes
O Google Kubernetes Engine (GKE) Autopilot é um modo operacional que abstrai completamente a complexidade da gerência de nós Kubernetes. Diferentemente do modo Standard, onde você provisiona e gerencia nós manualmente, o Autopilot remove essa responsabilidade, permitindo que você se concentre apenas na implantação de workloads. O Google gerencia automaticamente o scaling, patches de segurança, atualizações e conformidade com boas práticas.
Quando você cria um cluster Autopilot, o GCP automaticamente configura grupos de nós gerenciados, aplica políticas de segurança, ativa logging e monitoramento, e ajusta recursos conforme a demanda das suas aplicações. Isso significa menos overhead operacional, menos erros de configuração e maior conformidade com padrões de segurança. Para aplicações em produção, especialmente aquelas onde a equipe é pequena ou não possui especialização profunda em Kubernetes, o Autopilot é uma escolha extremamente prática.
Criando um Cluster Autopilot
Para criar um cluster Autopilot via gcloud CLI, execute:
gcloud container clusters create meu-cluster-autopilot \
--region us-central1 \
--enable-autopilot \
--enable-stackdriver-kubernetes \
--addons HttpLoadBalancing,HttpsLoadBalancing
O comando acima cria um cluster gerenciado automaticamente na região us-central1. Os flags --enable-stackdriver-kubernetes e --addons ativam logging/monitoramento e controladores de ingress respectivamente. O Autopilot já vem com segurança em rede, RBAC (Role-Based Access Control) e Pod Security Standards habilitados por padrão.
Diferenças Críticas em Relação ao GKE Standard
No GKE Standard, você deve gerenciar Node Pools manualmente, decidir tipos de máquina, quantidades de nós e políticas de escalabilidade. O Autopilot decide isso automaticamente baseado nos requisitos de recursos dos seus Pods. Se um Pod necessita 2GB de memória e 0.5 CPUs, o Autopilot provisiona nós suficientes para acomodá-lo. Além disso, o Autopilot impõe restrições (como limites de recurso obrigatórios em containers) que forçam boas práticas desde o início.
Workload Identity: Autenticação Segura para Aplicações
O Workload Identity é um mecanismo de segurança que permite que containers rodando no GKE acessem APIs do Google Cloud (como Cloud SQL, Cloud Storage, Pub/Sub) sem armazenar credenciais (chaves JSON) dentro da imagem ou no filesystem do container. Funciona através de um mapeamento de confiança entre uma Service Account do Kubernetes (KSA) e uma Service Account do Google Cloud (GSA), usando tokens JWT gerados automaticamente.
Sem Workload Identity, você seria obrigado a injetar um arquivo de chave JSON na sua aplicação, o que aumenta significativamente o risco de vazamento de credenciais. Com Workload Identity, o controle é granular: você cria uma GSA com permissões específicas, mapeia uma KSA do Kubernetes para ela, e a aplicação automaticamente recebe um token de curta duração (com expiração de aproximadamente 1 hora). Esse modelo é mais seguro, mais fácil de auditar e elimina o risco de credenciais vazarem via repositórios Git.
Configurando Workload Identity Passo a Passo
Primeiro, certifique-se que o cluster tem Workload Identity habilitado. No Autopilot, isso vem ativado por padrão. Para verificar:
gcloud container clusters describe meu-cluster-autopilot \
--region us-central1 \
--format='value(workloadIdentityConfig.workloadPool)'
Você deve ver um output como projeto-id.svc.id.goog. Se não retornar nada, habilite com:
gcloud container clusters update meu-cluster-autopilot \
--region us-central1 \
--workload-pool=SEU-PROJETO-ID.svc.id.goog
Agora, crie uma Service Account do Google Cloud:
gcloud iam service-accounts create minha-app-sa \
--display-name="Service Account da Minha App"
Conceda permissões à GSA. Se sua aplicação precisa ler do Cloud SQL, por exemplo:
gcloud projects add-iam-policy-binding SEU-PROJETO-ID \
--member="serviceAccount:minha-app-sa@SEU-PROJETO-ID.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
Crie uma Service Account do Kubernetes no seu namespace:
kubectl create serviceaccount minha-app-ksa -n meu-namespace
Estabeleça a relação de confiança entre KSA e GSA:
gcloud iam service-accounts add-iam-policy-binding \
minha-app-sa@SEU-PROJETO-ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:SEU-PROJETO-ID.svc.id.goog[meu-namespace/minha-app-ksa]"
Anotate a KSA com a email da GSA:
kubectl annotate serviceaccount minha-app-ksa \
-n meu-namespace \
iam.gke.io/gcp-service-account=minha-app-sa@SEU-PROJETO-ID.iam.gserviceaccount.com
Exemplo Prático: Pod Acessando Cloud Storage
Crie um Deployment que use a KSA anotada:
apiVersion: apps/v1
kind: Deployment
metadata:
name: storage-reader
namespace: meu-namespace
spec:
replicas: 1
selector:
matchLabels:
app: storage-reader
template:
metadata:
labels:
app: storage-reader
spec:
serviceAccountName: minha-app-ksa
containers:
- name: app
image: google/cloud-sdk:latest
command:
- /bin/bash
- -c
- |
gcloud auth application-default print-access-token
gsutil ls gs://meu-bucket
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
Quando esse Pod inicia, o Workload Identity injetor (um webhook do Kubernetes) automaticamente:
1. Monta volumes contendo credenciais ephemeral
2. Configura variáveis de ambiente GOOGLE_APPLICATION_CREDENTIALS apontando para um arquivo de token
3. A aplicação usa gcloud auth application-default ou a biblioteca cliente Google Cloud, que automaticamente lê essas credenciais
O resultado: sua aplicação acessa Cloud Storage sem nenhuma chave JSON armazenada.
Cloud SQL Proxy: Conexão Segura e Simplificada ao Banco de Dados
O Cloud SQL Proxy é um cliente que estabelece uma conexão segura (via SSL/TLS mutuo) com uma instância Cloud SQL, criptografando toda a comunicação. Em vez de sua aplicação conectar diretamente ao IP do banco (potencialmente exposto na rede), o Proxy atua como intermediário, gerenciando autenticação, criptografia e rotação de certificados automaticamente.
Quando executado dentro do GKE com Workload Identity, o Cloud SQL Proxy não necessita de credenciais explícitas. Ele usa o token JWT fornecido pelo Workload Identity para se autenticar com o Cloud SQL API e obter certificados válidos. Isso elimina completamente a necessidade de senhas de banco de dados ou chaves de conexão armazenadas.
Implantando Cloud SQL Proxy no GKE
Você tem duas opções: rodar o Proxy em um sidecar container dentro do Pod, ou usar um proxy gerenciado que o GCP fornece. Demonstrarei o sidecar, que é mais transparente para a aplicação.
Primeiro, certifique-se que sua GSA tem permissão para acessar Cloud SQL:
gcloud projects add-iam-policy-binding SEU-PROJETO-ID \
--member="serviceAccount:minha-app-sa@SEU-PROJETO-ID.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
Agora, modifique o Deployment anterior para incluir o sidecar:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-com-database
namespace: meu-namespace
spec:
replicas: 1
selector:
matchLabels:
app: app-com-database
template:
metadata:
labels:
app: app-com-database
spec:
serviceAccountName: minha-app-ksa
containers:
# Container principal da aplicação
- name: app
image: python:3.11-slim
command:
- /bin/bash
- -c
- |
pip install psycopg2-binary
python -c "
import psycopg2
conn = psycopg2.connect(
host='127.0.0.1',
port=5432,
database='meudb',
user='postgres',
password='sua-senha'
)
cursor = conn.cursor()
cursor.execute('SELECT version();')
print(cursor.fetchone())
cursor.close()
conn.close()
"
env:
- name: PGPASSWORD
value: "sua-senha"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
# Sidecar: Cloud SQL Proxy
- name: cloud-sql-proxy
image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.6.0
args:
- "PROJETO-ID:REGIAO:NOME-INSTANCIA"
- "--port=5432"
- "--max-connections=5"
ports:
- name: postgres
containerPort: 5432
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Neste exemplo, o sidecar Cloud SQL Proxy usa Workload Identity automaticamente (não requer variáveis de ambiente extras) porque o Pod está rodando sob a KSA anotada. O container principal da aplicação conecta em localhost:5432, e toda a criptografia e autenticação é gerenciada pelo Proxy.
Alternativa: Cloud SQL Auth Proxy Gerenciado (Beta)
O GCP oferece um serviço gerenciado (ainda em beta em alguns casos) onde você não precisa incluir um sidecar. Isso simplifica ainda mais o Deployment:
apiVersion: v1
kind: Pod
metadata:
name: app-simples
namespace: meu-namespace
spec:
serviceAccountName: minha-app-ksa
containers:
- name: app
image: python:3.11-slim
command:
- python
- -c
- |
import os
print(f"Conectando via: {os.getenv('CLOUD_SQL_CONNECTION_NAME')}")
env:
- name: CLOUD_SQL_CONNECTION_NAME
value: "PROJETO-ID:REGIAO:NOME-INSTANCIA"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
automountServiceAccountToken: true
Com o serviço gerenciado, você ainda precisa configurar a conexão, mas o overhead operacional é menor.
Monitorando Conexões e Debugging
Para verificar se o Proxy está funcionando corretamente, acesse os logs:
kubectl logs -n meu-namespace deployment/app-com-database -c cloud-sql-proxy
Se a autenticação via Workload Identity falhar, você verá erros como "failed to retrieve token" ou "permission denied". Nesse caso, verifique:
- Se a GSA realmente tem role
roles/cloudsql.client - Se a anotação na KSA está correta
- Se o mapeamento de confiança foi criado com
gcloud iam service-accounts add-iam-policy-binding
Para testar a conectividade manualmente dentro do Pod:
kubectl exec -it POD-NAME -c app -n meu-namespace -- /bin/bash
# Dentro do container
curl -v telnet://localhost:5432
Integrando os Três Componentes: Exemplo Completo
Agora vamos unir tudo em um exemplo real: um aplicativo Python que roda no GKE Autopilot, usa Workload Identity para autenticar no Cloud SQL, e se comunica com um banco de dados PostgreSQL através do Cloud SQL Proxy.
Pré-requisitos
- Um projeto GCP ativo
- Um cluster GKE Autopilot já criado (vimos como criar acima)
- Uma instância Cloud SQL PostgreSQL (crie com
gcloud sql instances create)
Passo 1: Criar a Instância Cloud SQL
gcloud sql instances create meudb \
--database-version=POSTGRES_15 \
--tier=db-f1-micro \
--region=us-central1 \
--no-backup
Crie um banco de dados e um usuário:
gcloud sql databases create meudb --instance=meudb
gcloud sql users create app_user --instance=meudb --password=MinhaSenhaSegura123
Passo 2: Configurar Service Accounts e Workload Identity
# Criar GSA
gcloud iam service-accounts create gke-app-sa \
--display-name="GKE App Service Account"
# Conceder permissões
gcloud projects add-iam-policy-binding SEU-PROJETO-ID \
--member="serviceAccount:gke-app-sa@SEU-PROJETO-ID.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
# Criar namespace
kubectl create namespace producao
# Criar KSA
kubectl create serviceaccount app-ksa -n producao
# Mapear KSA para GSA
gcloud iam service-accounts add-iam-policy-binding \
gke-app-sa@SEU-PROJETO-ID.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:SEU-PROJETO-ID.svc.id.goog[producao/app-ksa]"
# Anotar KSA
kubectl annotate serviceaccount app-ksa \
-n producao \
iam.gke.io/gcp-service-account=gke-app-sa@SEU-PROJETO-ID.iam.gserviceaccount.com
Passo 3: Criar a Aplicação
Crie um arquivo app.py:
import os
import psycopg2
from psycopg2.extras import RealDictCursor
import json
def get_connection():
"""Conecta ao Cloud SQL via localhost (Cloud SQL Proxy cuida da criptografia)"""
conn = psycopg2.connect(
host='127.0.0.1',
port=5432,
database='meudb',
user='app_user',
password=os.getenv('DB_PASSWORD', 'MinhaSenhaSegura123')
)
return conn
def create_table():
"""Cria tabela de exemplo se não existir"""
try:
conn = get_connection()
with conn.cursor() as cur:
cur.execute('''
CREATE TABLE IF NOT EXISTS usuarios (
id SERIAL PRIMARY KEY,
nome VARCHAR(100),
email VARCHAR(100)
)
''')
conn.commit()
print("Tabela criada ou já existe")
conn.close()
except Exception as e:
print(f"Erro ao criar tabela: {e}")
def inserir_usuario(nome, email):
"""Insere um usuário"""
try:
conn = get_connection()
with conn.cursor() as cur:
cur.execute(
'INSERT INTO usuarios (nome, email) VALUES (%s, %s) RETURNING id',
(nome, email)
)
user_id = cur.fetchone()[0]
conn.commit()
print(f"Usuário inserido com ID: {user_id}")
conn.close()
return user_id
except Exception as e:
print(f"Erro ao inserir usuário: {e}")
return None
def listar_usuarios():
"""Lista todos os usuários"""
try:
conn = get_connection()
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute('SELECT * FROM usuarios')
usuarios = cur.fetchall()
conn.close()
return usuarios
except Exception as e:
print(f"Erro ao listar usuários: {e}")
return []
if __name__ == '__main__':
print("Iniciando aplicação...")
create_table()
# Insere dois usuários
inserir_usuario('João Silva', 'joao@example.com')
inserir_usuario('Maria Santos', 'maria@example.com')
# Lista usuários
usuarios = listar_usuarios()
print("Usuários no banco:")
for user in usuarios:
print(f" - {user['nome']} ({user['email']})")
Crie um Dockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
Crie requirements.txt:
psycopg2-binary==2.9.9
Passo 4: Buildar e Fazer Push da Imagem
docker build -t gcr.io/SEU-PROJETO-ID/minha-app:1.0 .
docker push gcr.io/SEU-PROJETO-ID/minha-app:1.0
Passo 5: Criar o Deployment Completo
Salve como deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-db
namespace: producao
spec:
replicas: 1
selector:
matchLabels:
app: app-db
template:
metadata:
labels:
app: app-db
spec:
serviceAccountName: app-ksa
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: app
image: gcr.io/SEU-PROJETO-ID/minha-app:1.0
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
- name: cloud-sql-proxy
image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.6.0
args:
- "SEU-PROJETO-ID:us-central1:meudb"
- "--port=5432"
- "--max-connections=5"
ports:
- name: postgres
containerPort: 5432
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Passo 6: Criar Secret com Credenciais
kubectl create secret generic db-credentials \
-n producao \
--from-literal=password='MinhaSenhaSegura123'
Passo 7: Deploy e Verificação
kubectl apply -f deployment.yaml
# Aguarde alguns segundos
kubectl get pods -n producao
# Veja os logs
kubectl logs -n producao deployment/app-db -c app
Você deve ver um output mostrando que os usuários foram inseridos e listados com sucesso. Isso prova que a autenticação via Workload Identity, o Cloud SQL Proxy, e a aplicação estão todos funcionando juntos perfeitamente.
Para verificar os logs do Proxy especificamente:
kubectl logs -n producao deployment/app-db -c cloud-sql-proxy
Você verá mensagens confirmando que a autenticação foi bem-sucedida e as conexões estão abertas.
Conclusão
Neste artigo, cobrimos três componentes fundamentais para um deployment seguro e robusto no GCP:
-
GKE Autopilot simplifica radicalmente a operação de Kubernetes ao gerenciar nós, scaling, patches e conformidade de segurança automaticamente. Você escreve Deployments, o Autopilot cuida do resto. Para times pequenos ou que querem focar em aplicação, não em infraestrutura, é a escolha ideal.
-
Workload Identity elimina credenciais armazenadas, substituindo chaves JSON por tokens de curta duração gerenciados automaticamente. O mapeamento KSA→GSA é fino e auditável, tornando o ambiente significativamente mais seguro sem sacrificar a facilidade de uso.
-
Cloud SQL Proxy, integrado com Workload Identity, fornece criptografia fim-a-fim transparente para o banco de dados. A aplicação conecta em localhost sem saber que há criptografia TLS mútuo, rotação de certificados e autenticação automática acontecendo nos bastidores.
Quando usados em conjunto — GKE Autopilot + Workload Identity + Cloud SQL Proxy — você obtém um stack extremamente seguro, altamente gerenciado e com overhead operacional mínimo. Nenhuma chave vaza em repositórios, nenhuma credencial precisa ser rodada manualmente, e nenhuma porta de banco fica exposta na rede.