DevOps

무중단 배포 적용하기

목차

  • 무중단 배포란?
  • 프로젝트의 기존 Infra 구조
  • 프로젝트의 기존 배포 흐름
    • 기존 배포 흐름의 문제점
  • Rolling Update 배포
  • Blue-Green 배포
  • 프로젝트에 무중단 배포 적용하기

프로젝트의 기존 Infra 구조

현재 보고 또 보고 서비스는 다음과 같은 구조로 구성되어있다.

Reverse Proxy — WAS1 —— DB
             \— WAS2 —/

ㅋㅋ.. 조금 빈약한 그림이지만 말로 설명해보자면 앞단에 웹 서버로 Nginx를 두어 리버스 프록시의 역할을 수행하고 있으며 뒤에 WAS가 2대 띄워져있는 상황이다. (DB Replication 구조는 나타내지 않았다.)
리버스 프록시는 두 인스턴스를 upstream 서버로 보고, 요청을 보낸 클라이언트의 ip를 hashing하여 두 서버로 적절히 요청을 분배한다.

WAS1과 WAS2는 각각 main1, main2라고 칭하겠다.

프로젝트의 기존 배포 흐름

  1. Jenkins로 main1, main2의 jar 파일을 각각의 pipeline으로 빌드한다.
  2. 현재는 한번에 하나의 pipeline만 실행되도록 설정되어있으므로, main1의 빌드가 완료되고 ssh 전송이 끝나면 main1은 새롭게 배포된다.
  3. main1의 배포가 완료되면 main2가 2와 동일하게 배포된다.

기존 배포 흐름의 문제점

health check를 하지 않는다.

  • health check를 하지 않으므로 main1에서 jar 파일은 생성되었으나 실행에 실패해도, main2는 관계없이 순차적으로 배포를 시작한다.
  • main2가 먼저 배포되었을 경우에도 마찬가지로 main2의 성공 여부에 관계없이 main1도 배포된다.
  • 따라서, jar파일에 문제가 있거나 빌드에 실패한 경우 두 대의 WAS 모두 이용이 불가능해진다.

애매한 무중단 배포의 적용

  • jenkins 빌드 시 한번에 하나의 파이프라인만 수행하므로 어쨌든 둘 중에 하나는 빌드 된 상태
    이기에, 사실상 main 서버는 항상 켜져있는 것이나 다름없다.
  • 하지만, 실제 이용중인 사용자의 경우에는 앞서 ip 해시값으로 분배된 서버를 이용하고 있으므로, 중단된 서버를 사용하고 있는 경우 새로고침 등의 서버 재접속 요청이 필요할 수 있다. (즉, 끊김을 느낄 수도 있다.)

무중단 배포란?

무중단 배포란
서버를 실제로 서비스할 때 서비스적인 장애와 배포에 있어서 부담감을 최소화하고 서비스가 중단되지 않도록 배포하는 기술

Rolling Update 배포

Rolling-Update 배포 방식은 간단하다. 배포된 서버를 한대씩 구버전에서 새로운 버전으로 교체해나가는 방법이다.

예를 들어 기존 ver1에서 ver2로 배포를 시도한다고 가정해보자.


Rolling Update 방식을 적용할 경우 main1에 대해 연결을 끊고, main1을 ver1에서 ver2로 업데이트한다. main1이 ver2로 업데이트가 완료되면, 다시 main1로 연결하고 main2에 대한 연결을 끊고 main2를 업데이트한다.

 

이 방식을 적용하면 새로운 인프라를 적용하지 않고도 무중단 배포를 실현할 수 있다는 장점이 있다. 하지만 단점으로는 두 대의 WAS로 구성된 상태에서 나머지 한대의 WAS 연결을 끊고 업데이트를 진행하기 때문에, 두 대에 나눠 분배되던 요청이 한 대로 몰릴 수 있다는 단점이 존재한다. (n대일 때에도 마찬가지이다.)

Blue-Green 배포

Blue-Green 배포 방식은 Rolling-Update의 단점을 보완할 수 있다.
Blue와 Green은 각각 다음과 같은 상태를 의미한다.

  • Blue: 배포되기 전 상태
  • Green: 배포 후 상태

Blue-Green 배포 방식은, Blue 상태를 Green 상태로 서서히 바꾸어나가는 과정이다. 예를 통해 알아보자.
예를 들어, 현재 WAS1과 WAS2에는 각각 8080포트로 서버가 띄워져있다. 그리고 ver1에서 ver2로 배포를 진행해야한다. 이 때, 우리는 WAS에서 사용하고 있지 않은 8081로 ver2에 대한 배포를 진행한다.


이 경우, 기존의 8080포트에 띄워진 서버는 Blue 상태의 서버, 8081에 띄워진 서버는 Green 상태의 서버를 나타낸다. 그리고 8081 포트에 띄워진 새 버전의 서버가 정상적으로 동작하는지 health-check를 진행한다. health-check 과정이 모두 통과하면 리버스 프록시는 8081 포트도 바라보도록 설정하고, 정상 연결되면 기존 8080 포트에 대한 연결을 끊음으로서 무중단 배포를 실현할 수 있다.

 

이 방식을 적용하면 앞선 롤링 업데이트 방식의 단점인 서버에 요청 몰림 현상이 발생하지 않을 수 있다. 하지만 포트번호를 다르게하는 경우가 아닌 새로운 인스턴스를 띄우거나 하는 경우라면 비용적인 측면에서 제약이 발생할 수 있다.

프로젝트에 적용하기

현재 우리 프로젝트에 적용된 무중단 배포 방식은 다음과 같다.

  1. 자동 배포 CI/CD 툴인 Jenkins를 이용해 새 버전의 jar를 빌드한다.
  2. 첫번째 서버(main1)에 ssh 프로토콜로 접속해 현재 애플리케이션이 실행되고 있지 않은 다른 포트에 새 버전의 애플리케이션을 띄운다.
  3. 새 버전의 애플리케이션이 잘 실행되는지 health-check를 진행한다.
  4. health-check에 성공하면 다른 서버로 2, 3과정을 수행한다.
  5. 모두 health-check에 성공하면 리버스 프록시가 바라보고 있는 포트를 변경한다.