GitLab CI/CD: Blue-Green Deployment com Spring Boot e Helm
Automatizar o deploy de aplicações Spring Boot exige estratégias que eliminem o downtime e permitam rollbacks instantâneos. Enquanto o Canary foca em tráfego progressivo, o Blue-Green Deployment foca em ambientes espelhados: você sobe a nova versão (Green) ao lado da atual (Blue) e alterna o tráfego de uma só vez após a validação.
Neste artigo, vamos construir uma pipeline no GitLab CI que utiliza um Docker Registry para armazenar imagens imutáveis e o Helm para gerenciar a alternância de tráfego no Kubernetes.
O código completo e os manifestos utilizados nesta simulação estão disponíveis no repositório: blue-green-deployment-simulation
O Fluxo Blue-Green
Diferente do deploy tradicional, o Blue-Green mantém duas versões da aplicação. O Service do Kubernetes atua como o roteador, apontando para uma das duas.
flowchart TD
Build[Build & Test] --> Package[Push to Registry]
Package --> Green[Deploy Green - V2]
Green --> Test[Validation on Green]
Test --> Switch{Manual Switch?}
Switch -->|Approve| Blue[Service points to Green]
Blue --> OldBlue[Delete/Standby V1]
style Switch fill:#ff5,stroke:#333,stroke-width:2px
1. O Artefato imutável no Registry
Para que o deploy seja confiável, a imagem deve ser construída uma única vez e armazenada em um registro (como o GitLab Container Registry ou Docker Hub).
Dockerfile Otimizado
1
2
3
4
5
6
7
8
9
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
2. A Pipeline no GitLab CI (.gitlab-ci.yml)
A pipeline agora é configurada para garantir que a imagem chegue ao registro antes de qualquer tentativa de deploy.
Variáveis e Autenticação
1
2
3
4
5
6
7
variables:
REGISTRY: index.docker.io/meu-usuario
IMAGE_NAME: spring-app
IMAGE_TAG: $CI_COMMIT_SHORT_SHA
before_script:
- docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
Estágio de Package (Registry)
1
2
3
4
5
package-image:
stage: package
script:
- docker build -t $REGISTRY/$IMAGE_NAME:$IMAGE_TAG .
- docker push $REGISTRY/$IMAGE_NAME:$IMAGE_TAG
Estágio Deploy Green (Ambiente Novo)
Nesta fase, instalamos a nova versão sem afetar o tráfego principal. O Helm Chart deve usar um sufixo ou seletor específico.
1
2
3
4
5
6
7
8
9
deploy-green:
stage: deploy
image: dtzar/helm-kubectl:latest
script:
- helm upgrade --install myapp-green ./chart
--set image.repository=$REGISTRY/$IMAGE_NAME
--set image.tag=$IMAGE_TAG
--set replicaCount=2
--set versionLabel=green
Estágio de Promoção (Switch de Tráfego)
Este é o passo manual. Ao ser executado, o Service principal do Kubernetes é atualizado para apontar para os Pods com a label versionLabel=green.
1
2
3
4
5
6
promote-to-production:
stage: promote
script:
- helm upgrade myapp-service ./chart-service
--set activeVersion=green
when: manual
3. Simulação Totalmente Local com Registry
Para simular isso localmente com fidelidade à produção, não usaremos o docker-env do Minikube. Vamos rodar um Local Registry.
Passo a Passo
- Inicie o Registry Local:
1
docker run -d -p 5000:5000 --name local-registry registry:2
- Configure o Minikube para aceitar o Insecure Registry:
1
minikube start --insecure-registry="{{host}}"
- Build e Push (Simulando o GitLab CI):
1 2 3 4
# Build docker build -t {{name}}:{{version}} . # Push para o registro local (como a pipeline faria) docker push {{name}}:{{version}}
- Deploy Blue-Green Manual: Instale a versão Green no cluster:
1
helm upgrade --install myapp-green ./chart --set image.repository=localhost:5000/spring-app --set image.tag={{version}}
Conclusão
A transição de Canary para Blue-Green oferece um controle mais binário e seguro sobre a entrega. Ao centralizar as imagens em um Docker Registry, garantimos que o Kubernetes sempre baixe o mesmo artefato validado pela pipeline de CI, evitando a “deriva de configuração” entre máquinas locais e servidores de produção.
Dica: Em um cenário de Rollback, basta re-executar o job de switch apontando o seletor de volta para
blue. A versão antiga ainda estará rodando nos Pods originais até que você decida removê-los.