Pipeline de CD: deploy automático
1. Introdução à Entrega Contínua (CD) no Contexto DevOps
A Entrega Contínua (CD) é o estágio do pipeline DevOps que automatiza a implantação de aplicações em ambientes de produção ou staging. Enquanto a Integração Contínua (CI) foca em compilar, testar e validar o código, a CD leva o artefato final — uma imagem Docker — diretamente para o cluster Kubernetes, eliminando intervenções manuais.
A diferença fundamental entre CI e CD está no destino: a CI termina com um artefato pronto (imagem no registry), enquanto a CD inicia a partir desse artefato e o implanta em um cluster. Com Docker e Kubernetes, o deploy automático ganha consistência (mesma imagem em todos os ambientes) e escalabilidade (orquestração nativa de containers).
O fluxo completo é: código commitado → trigger do pipeline → build da imagem Docker → push para registry → atualização do deployment no Kubernetes → validação pós-deploy.
2. Preparando o Ambiente para Deploy Automático
Antes de configurar o pipeline, é necessário ter um cluster Kubernetes acessível. Para desenvolvimento local, use Minikube:
minikube start --cpus 4 --memory 8192
Para ambientes cloud, crie um cluster EKS (AWS), GKE (GCP) ou AKS (Azure). Instale o kubectl e configure a autenticação no runner do GitHub Actions. Crie um namespace dedicado:
kubectl create namespace production
O kubeconfig do cluster deve ser armazenado como secret no GitHub para uso no pipeline.
3. Construindo e Publicando a Imagem Docker no Pipeline
O build da imagem deve usar Dockerfile multi-stage para reduzir o tamanho final. Exemplo para uma aplicação Node.js:
# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Runtime
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]
A tag da imagem deve combinar versão semântica com o SHA do commit para rastreabilidade:
docker build -t myapp:1.2.3-${GITHUB_SHA::7} .
docker tag myapp:1.2.3-${GITHUB_SHA::7} registry.example.com/myapp:1.2.3-${GITHUB_SHA::7}
docker push registry.example.com/myapp:1.2.3-${GITHUB_SHA::7}
4. Gerenciando Secrets e Configurações para Deploy
No GitHub Actions, armazene secrets como DOCKER_PASSWORD, KUBE_CONFIG e REGISTRY_URL. Para injetar configurações no Kubernetes, use ConfigMaps e Secrets:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
NODE_ENV: "production"
API_URL: "https://api.example.com"
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
namespace: production
type: Opaque
data:
DB_PASSWORD: <base64-encoded-password>
Para ambientes mais avançados, integre com External Secrets Operator (AWS Secrets Manager, Google Secret Manager).
5. Estratégias de Deploy no Kubernetes
Rolling Update (padrão)
Atualiza pods gradualmente com zero downtime:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: production
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
spec:
containers:
- name: myapp
image: registry.example.com/myapp:latest
Blue/Green Deploy
Usa dois Deployments (blue e green) e um Service que aponta para o ativo:
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
version: blue # ou green
ports:
- port: 80
targetPort: 3000
Canary Deploy
Distribui tráfego gradualmente entre versões usando Service Mesh como Istio:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp.example.com
http:
- match:
- headers:
canary:
exact: "true"
route:
- destination:
host: myapp-canary
port:
number: 80
weight: 10
- route:
- destination:
host: myapp-stable
port:
number: 80
weight: 90
6. Implementando o Workflow de CD no GitHub Actions
Arquivo .github/workflows/deploy.yml:
name: CD Pipeline
on:
push:
branches: [main]
release:
types: [published]
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Registry
uses: docker/login-action@v3
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push
run: |
IMAGE_TAG="${{ github.ref_name }}-${{ github.sha::7 }}"
docker build -t myapp:$IMAGE_TAG .
docker tag myapp:$IMAGE_TAG ${{ secrets.REGISTRY_URL }}/myapp:$IMAGE_TAG
docker push ${{ secrets.REGISTRY_URL }}/myapp:$IMAGE_TAG
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure kubectl
run: |
echo "${{ secrets.KUBE_CONFIG }}" > kubeconfig
export KUBECONFIG=kubeconfig
- name: Deploy to Kubernetes
run: |
IMAGE_TAG="${{ github.ref_name }}-${{ github.sha::7 }}"
kubectl set image deployment/myapp myapp=${{ secrets.REGISTRY_URL }}/myapp:$IMAGE_TAG -n production
- name: Verify Deployment
run: |
kubectl rollout status deployment/myapp -n production --timeout=5m
Para pipelines mais complexos, use helm upgrade:
helm upgrade myapp ./charts/myapp \
--set image.tag=$IMAGE_TAG \
--namespace production
7. Validação e Rollback Automático
Configure health checks no manifesto do Deployment:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: myapp
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 3
No pipeline, adicione monitoramento pós-deploy:
- name: Monitor Deployment
run: |
kubectl logs deployment/myapp -n production --tail=50
kubectl get pods -n production -l app=myapp
Rollback automático em caso de falha:
- name: Rollback on Failure
if: failure()
run: |
kubectl rollout undo deployment/myapp -n production
echo "Deploy falhou. Rollback executado."
8. Boas Práticas e Próximos Passos
- Imutabilidade: nunca altere pods manualmente no cluster. Sempre passe pelo pipeline.
- Versionamento de manifestos: mantenha YAMLs do Kubernetes no mesmo repositório do código.
- Observabilidade: integre com Prometheus para métricas e Grafana para dashboards.
Próximos passos incluem:
- Implementar approval gates manuais para produção
- Usar ArgoCD para GitOps (deploy declarativo a partir do Git)
- Adicionar testes de integração pós-deploy automatizados
Referências
- GitHub Actions Documentation: Deploy to Kubernetes — Guia oficial para configurar deploy Kubernetes com GitHub Actions.
- Kubernetes Rolling Update Strategy — Documentação oficial sobre estratégias de atualização de Deployments.
- Docker Multi-stage Builds — Tutorial oficial sobre builds otimizados com multi-stage.
- Istio Canary Deployments — Guia prático para implementar canary releases com Istio.
- ArgoCD: Declarative GitOps for Kubernetes — Documentação oficial da ferramenta GitOps para deploy contínuo.
- External Secrets Operator — Projeto open source para sincronizar secrets externos com Kubernetes.