Prática Completa: Implantação do Projeto OrderFlow
Implantação é a última milha — automação CI/CD, orquestração K8s e monitoramento com alertas garantem uma jornada sem interrupções das aplicações do desenvolvimento à produção.
1. O Que Você Vai Aprender
- Pipeline CI/CD: Construir imagens usando GitHub Actions → Push para o registry → Rolling deployment no K8s
- Implantação K8s de Produção: Deployment + HPA Auto-Scaling + Ingress Gateway
- Implantação de Observabilidade: Prometheus + Grafana + AlertManager Regras de Alerta
- Hardening de Segurança de Produção: Gerenciamento de Secrets / NetworkPolicy / Pod Security Standards
- Bob implantou o OrderFlow no ambiente de produção para suportar operações de negócio lidando com milhões de pedidos por dia.
2. Uma História Real de um Engenheiro DevOps
(1) Dor: Implantação manual é como pisar em uma mina
Bob implantou manualmente o OrderFlow em produção: localmente mvn package → docker build → fez push da imagem → kubectl apply → verificou health status. O processo inteiro leva 30 minutos e é propenso a erros: esquecer de atualizar a configuração, fazer push da versão errada da imagem ou Pods antigos não desligarem graciosamente durante rolling updates, resultando em erros 502.
(2) Soluções CI/CD
Serviço Completo para Linhas de Produção Automatizadas:
graph LR
A["Git Push"] --> B["GitHub Actions<br/>Build + Test"]
B --> C["Docker Build<br/>+ Push para Registry"]
C --> D["K8s Rolling<br/>Deploy"]
D --> E["Health Check<br/>+ Smoke Test"]
E --> F["Monitor<br/>Grafana"]
(3) Resultado
Depois que Bob configurou CI/CD, pushes de código dispararam implantações automáticas, completando o processo do código à produção em 5 minutos. Com HPA cuidando do auto-scaling e Prometheus cuidando dos alertas automáticos, Bob passou de "bombeiro" a "observador de monitoramento."
3. Pipeline CI/CD
(1) ▶ Exemplo: Workflow do GitHub Actions
# .github/workflows/deploy.yml
name: OrderFlow CI/CD
on:
push:
branches: [main]
tags: ['v*']
env:
REGISTRY: registry.example.com
IMAGE_NAME: orderflow-service
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Run tests
run: mvn verify -B
- name: Build Docker image
run: docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} .
- name: Login to Registry
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u ${{ secrets.REGISTRY_USERNAME }} --password-stdin
- name: Push image
run: docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
deploy:
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/orderflow \
orderflow=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \
-n orderflow
kubectl rollout status deployment/orderflow -n orderflow --timeout=300s
- name: Smoke test
run: |
sleep 10
curl -sf https://api.orderflow.example.com/actuator/health | grep '"status":"UP"'
Saída:
CONTAINER ID IMAGE STATUS PORTS
abc123 nginx:latest Up 2 hours 0.0.0.0:80->80/tcp
| Estágio do Pipeline | Operação | Tratamento de Falha |
|---|---|---|
| Build + Test | mvn verify |
Bloquear Implantação |
| Docker Build | Build de imagem multi-stage | Bloquear Implantação |
| Push Registry | Push para repositório de imagens | Retentar 3 vezes |
| K8s Deploy | kubectl set image + rollout |
Rollback automático |
| Smoke Test | Validação de Health Check | Rollback + Notificação |
4. Implantação K8s de Produção
(1) ▶ Exemplo: Deployment de Produção + HPA
apiVersion: apps/v1
kind: Deployment
metadata:
name: orderflow
namespace: orderflow
spec:
replicas: 3
selector:
matchLabels: { app: orderflow }
strategy:
rollingUpdate: { maxUnavailable: 0, maxSurge: 1 }
template:
metadata:
labels: { app: orderflow }
spec:
terminationGracePeriodSeconds: 60
containers:
- name: orderflow
image: registry.example.com/orderflow-service:latest
ports:
- { containerPort: 8080 }
- { containerPort: 8081 }
envFrom:
- configMapRef: { name: orderflow-config }
- secretRef: { name: orderflow-secrets }
resources:
requests: { memory: "512Mi", cpu: "250m" }
limits: { memory: "1Gi", cpu: "1000m" }
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
initialDelaySeconds: 60
periodSeconds: 30
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: orderflow-hpa
namespace: orderflow
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: orderflow
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Saída:
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
| Configuração K8s de Produção | Valor | Motivo |
|---|---|---|
maxUnavailable: 0 |
Zero Downtime | Sempre Manter o Número Alvo de Cópias |
terminationGracePeriodSeconds: 60 |
Fechamento gracoso | Aguardar limpeza das requisições |
preStop: sleep 10 |
Término Atrasado | K8s Continua Drenando Tráfego Mesmo Após Remoção do Service |
resources.requests/limits |
Configurar QoS | Garantir Alocação de Recursos + Limitar Excessos |
(2) ▶ Exemplo: Ingress + TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orderflow-ingress
namespace: orderflow
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts: [api.orderflow.example.com]
secretName: orderflow-tls
rules:
- host: api.orderflow.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service: { name: orderflow, port: { number: 80 } }
Saída:
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
5. Lançamento de Observabilidade
(1) ▶ Exemplo: Prometheus + AlertManager
# prometheus.yml
scrape_configs:
- job_name: orderflow
metrics_path: /actuator/prometheus
scrape_interval: 15s
kubernetes_sd_configs:
- role: pod
namespaces:
names: [orderflow]
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: orderflow
Saída:
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
# alert_rules.yml
groups:
- name: orderflow-slo
rules:
- alert: SLOErrorRateExceeded
expr: |
sum(rate(http_server_requests_seconds_total{namespace="orderflow",status=~"5.."}[5m]))
/ sum(rate(http_server_requests_seconds_total{namespace="orderflow"}[5m])) > 0.001
for: 5m
labels: { severity: critical }
annotations:
summary: "OrderFlow taxa de erro excede SLO (0,1%)"
- alert: SLOLatencyExceeded
expr: |
histogram_quantile(0.99,
sum(rate(http_server_requests_seconds_bucket{namespace="orderflow"}[5m])) by (le))
> 0.1
for: 5m
labels: { severity: warning }
annotations:
summary: "OrderFlow latência P99 excede SLO (100ms)"
(2) ▶ Exemplo: Métricas do Dashboard SLO Grafana
| Dashboard | PromQL | Alvo SLO |
|---|---|---|
| Latência P99 | histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket{namespace="orderflow"}[5m])) by (le)) |
< 100 ms |
| Taxa de Erro | sum(rate(http_server_requests_seconds_total{namespace="orderflow",status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_total{namespace="orderflow"}[5m])) |
< 0,1% |
| Disponibilidade | 1 - (sum(rate(http_server_requests_seconds_total{namespace="orderflow",status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_total{namespace="orderflow"}[5m]))) |
> 99,9% |
| Throughput de Pedidos | rate(orderflow_orders_created_total[1m]) * 60 |
> 100/min |
6. Hardening de Segurança de Produção
(1) ▶ Exemplo: NetworkPolicy + Pod Security
# NetworkPolicy: restringir acesso
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: orderflow-netpol
namespace: orderflow
spec:
podSelector:
matchLabels: { app: orderflow }
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels: { name: ingress-nginx }
ports:
- { port: 8080, protocol: TCP }
- from:
- namespaceSelector:
matchLabels: { name: monitoring }
ports:
- { port: 8081, protocol: TCP }
---
# Segurança do Pod: executar como não-root
apiVersion: v1
kind: LimitRange
metadata:
name: orderflow-limits
namespace: orderflow
spec:
limits:
- type: Container
default:
memory: "1Gi"
cpu: "500m"
defaultRequest:
memory: "256Mi"
cpu: "100m"
Saída:
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
| Item de Hardening de Segurança | Medida | Descrição |
|---|---|---|
| Execução Não-root | Dockerfile USER appuser |
Prevenir Escape de Contêiner |
| NetworkPolicy | Restringir Fontes de Entrada | Permitir Apenas Ingress e Monitoramento |
| Criptografia de Secret | Configuração de Criptografia etcd | Prevenir Secrets Armazenadas em Texto Puro |
| TLS | Certificados automáticos cert-manager | Transmissão Criptografada |
| Limites de Recursos | LimitRange | Prevenir Contenção de Recursos |
7. Exemplo Completo: Checklist Completo de Implantação do OrderFlow
# k8s/orderflow-complete.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: orderflow
labels: { name: orderflow }
---
apiVersion: v1
kind: ConfigMap
metadata: { name: orderflow-config, namespace: orderflow }
data:
SPRING_PROFILES_ACTIVE: "prod"
DB_HOST: "mysql.orderflow.svc.cluster.local"
REDIS_HOST: "redis.orderflow.svc.cluster.local"
MANAGEMENT_SERVER_PORT: "8081"
---
apiVersion: v1
kind: Secret
metadata: { name: orderflow-secrets, namespace: orderflow }
type: Opaque
data:
DB_PASSWORD: <base64-encoded>
REDIS_PASSWORD: <base64-encoded>
JWT_PRIVATE_KEY: <base64-encoded>
---
apiVersion: apps/v1
kind: Deployment
metadata: { name: orderflow, namespace: orderflow }
spec:
replicas: 3
selector: { matchLabels: { app: orderflow } }
strategy: { rollingUpdate: { maxUnavailable: 0, maxSurge: 1 } }
template:
metadata: { labels: { app: orderflow } }
spec:
terminationGracePeriodSeconds: 60
containers:
- name: orderflow
image: registry.example.com/orderflow-service:1.0.0
ports: [{ containerPort: 8080 }, { containerPort: 8081 }]
envFrom:
- { configMapRef: { name: orderflow-config } }
- { secretRef: { name: orderflow-secrets } }
resources:
requests: { memory: "512Mi", cpu: "250m" }
limits: { memory: "1Gi", cpu: "1000m" }
lifecycle:
preStop: { exec: { command: ["sh", "-c", "sleep 10"] } }
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
initialDelaySeconds: 60; periodSeconds: 30
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
initialDelaySeconds: 30; periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata: { name: orderflow, namespace: orderflow }
spec:
selector: { app: orderflow }
ports:
- { name: http, port: 80, targetPort: 8080 }
- { name: management, port: 8081, targetPort: 8081 }
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: orderflow-hpa, namespace: orderflow }
spec:
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: orderflow }
minReplicas: 3
maxReplicas: 10
metrics:
- { type: Resource, resource: { name: cpu, target: { type: Utilization, averageUtilization: 70 } } }
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orderflow-ingress
namespace: orderflow
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- { hosts: [api.orderflow.example.com], secretName: orderflow-tls }
rules:
- host: api.orderflow.example.com
http:
paths:
- { path: /, pathType: Prefix, backend: { service: { name: orderflow, port: { number: 80 } } } }
❓ Perguntas Frequentes
readinessProbe para garantir que Pods estejam prontos antes de serem adicionados ao Service; 3) Definir preStop sleep 10 para permitir que o K8s drene requisições após o Pod ser removido do Service; 4) Aplicar a configuração server.shutdown=graceful.📖 Resumo
- Pipeline CI/CD: Push de código → Teste automatizado → Build de imagem → Push para Registry → Rolling deployment no K8s
- Implantação de Produção: Deployment + HPA Auto-Scaling + Ingress Gateway + TLS
- Implantação com zero downtime: maxUnavailable=0 + readinessProbe + preStop + graceful shutdown
- Observabilidade: Coleta de dados Prometheus + Dashboards SLO Grafana + Alertas AlertManager
- Hardening de Segurança: Usuários não-root + NetworkPolicy + Criptografia de Secret + TLS + Limites de Recursos
- Entrega end-to-end do design à implantação, suportando um negócio que lida com milhões de pedidos por dia
📝 Exercícios
-
Problema Básico (Dificuldade: ⭐): Escreva um workflow do GitHub Actions para testar e construir automaticamente uma imagem Docker após o push de código.
-
Exercício Avançado (Dificuldade: ⭐⭐): Escreva um YAML completo de implantação K8s de produção (Deployment + Service + Ingress + HPA + ConfigMap + Secret) para implementar rolling updates com zero downtime.
-
Desafio (Dificuldade: ⭐⭐⭐): Configure um sistema de observabilidade completo (Prometheus + Grafana + AlertManager + Jaeger), configure dashboards SLO e regras de alerta e simule uma falha para testar as capacidades de alerta e recuperação automática.



