<aside>

image.png

</aside>

현재 사용중인 아키텍처 구성도이다.

단일 EC2 인스턴스 내에서 Dockerhub 에서 최신화된 Image Push/Pull 하는 과정을 통해 새로운 버전을 배포해왔다.

해당 방식은 무조건적으로 서비스가 중단되는 시간이 발생하게 되고, 이를 Down Time 이라고 부른다. 이 Down Time 이 지속되면 사용자 경험에 안좋은 영향을 끼칠 수 있다 판단했고, 이를 최소화 하기에 Blue-Green 무중단 배포 전략을 적용하고자 한다.

Blue-Green 전략은 다운 타임이 발생하지 않는다 ?

존재하긴 하지만, 체감하지 못할 정도이다. 컨테이너 전환 시, Nginx 가 받는 트래픽을 전환되는 컨테이너로 reload 하는 과정에서 다운 타임이 발생하지만, 이는 1초 이내로 사용자가 체감하지 못할 정도이다.

실제로 테스트 시, 컨테이너가 전환되는 과정에서 WAS 로 요청을 계속해서 보냈지만(채팅) 로그 상이나 내 시점에서도 전혀 서비스가 끊긴다는 느낌을 받지 못했다.

Blue-Green 배포 개념 요약

기존의 docker-compose.yml

services:
  ... 

  backend:
    build:
      context: ./
      dockerfile: Dockerfile
    env_file:
      - .env
    expose:
      - "8080"
    environment:
      - MYSQL_USER=${PROD_DB_USERNAME}
      - MYSQL_PASSWORD=${PROD_DB_PASSWORD}
      - MYSQL_URL=jdbc:mysql://${PROD_DB_ENDPOINT}:3306/${PROD_DB_NAME}?serverTimezone=UTC
    networks:
      - gdg_network
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
    healthcheck:
      test: [ "CMD", "curl", "-f", "<http://localhost:8080/api/health>" ]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 60s

  nginx:
		...
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
			- ./nginx/backend_upstream.conf:/etc/nginx/backend_upstream.conf:ro
      - /etc/letsencrypt/live/api.zimeet.store:/etc/letsencrypt/live/api.zimeet.store:ro
      - /etc/letsencrypt/archive:/etc/letsencrypt/archive:ro
      - /etc/letsencrypt/privkey.pem:/etc/letsencrypt/privkey.pem:ro

		... 

<aside>

EC2 내부 nginx/backend_upstream.conf

server backend-blue:8080;

Blue ↔ Green 컨테이너가 전환되면, 여기도 동적으로 바뀌게 된다.

http {
    upstream backend_server {      
        include /etc/nginx/backend_upstream.conf;
        // 기존 :  include server backend:8080;
    }

		server {
		    location / {
		        proxy_pass <http://backend>;
		    }
		}
		
    # 나머지 설정 동일
}

nginx 에서 위의 backend_upstream 을 include 하는 이유가 배포 시 동적으로 백엔드 서버 주소를 바꾸기 위해서이다 backend_upstream.conf 은 배포 스크립트가 자동으로 덮어쓰며, 현재 트래픽을 보낼 컨테이너를 지정한다.

이를 통해 nginx -s reload로 설정만 반영되고, 서비스 중단 없이 적용할 수 있는 것이다.

</aside>