Skip to content

Instantly share code, notes, and snippets.

@ninanung
Last active May 1, 2023 03:23
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ninanung/9d63304cb0d070642e89f9b94b6fe24b to your computer and use it in GitHub Desktop.
Save ninanung/9d63304cb0d070642e89f9b94b6fe24b to your computer and use it in GitHub Desktop.
서버 무중단 배포하기! - "블루/그린"과 "현재위치"

서버 무중단 배포하기! - "블루/그린"과 "현재위치"

목차

Ice Breaking

서버를 배포한다는 것은 멋있는 일이라고 생각한다. 까만 터미널을 여러개 켜놓고 커맨드를 입력하는 손놀림, 번쩍이는 눈빛. 하지만 실상은 다 꺼졌으면 좋겠다는 생각으로 타자를 누르고 있을 뿐일 것이다. 그럼에도 꽤 멋있는 일임은 부정할 수 없다. 그렇다면 더 멋있는 것은 무엇일까? 그것은 바로 무중단 배포이다! 서버를 업데이트 하는 도중에도 사용자를 불편하게 하지 않으려는 따듯한 마음과 서버를 껐다켰다 하지 않는 효율성. 이 얼마나 멋있는 개발자인가. 따라서 우리도 그 멋진 개발자가 되기 위해 무중단 배포 방식 두가지를 알아보자. 참고로 이는 방식의 설명일 뿐이며 Docker, Kubernetes, AWS, GCP 혹은 VM을 이용한 방식등등 서버 자체적인 어떠한 설명도 들어있지는 않다. 자신이 사용중인 환경에서는 어떻게 하면 좋을지 고민해보자.

In-Place Deployment

In-Place Deployment즉 현재위치 배포는 무중단 배포의 한 방식이다. 현재 가동중인 서버 그대로 무중단 배포를 구현하기 때문에 현재위치 배포라고 불린다. 우선 아래의 그림을 보자.
서버 구성도1
한개의 로드밸런서가 4개의 서버로 골고루 요청을 보내고 있다. 모든 서버는 현재 1.0.1버전을 사용중이며 우리의 목표는 해당 서버를 1.0.2버전으로 업데이트 하는 것이다. 순서대로 어떻게 진행되어야 하는지 한번 알아보자.

  1. 로드밸런서와 Server 1과 Server 2의 연결을 해제한다. 로드밸런서는 Server 3과 Server 4로만 요청을 보내게 된다.
    서버 구성도2

  2. 때어낸 서버 두개를 버전 1.0.2로 업데이트 한다. 아직 연결은 하지 않는다.
    서버 구성도3

  3. 업데이트한 서버를 로드밸런서에 연결한다.
    서버 구성도4

  4. 로드밸런서에서 Server 3과 Server 4를 연결 해제한다. 이 단계부터 클라이언트는 1.0.2버전의 서버를 사용할 수 있게 된다.
    서버 구성도5

  5. 앞에서 진행한 2와 3을 똑같이 진행한 후 로드밸런서에 연결한다.
    서버 구성도6
    짠! 사용자는 계속해서 서비스를 이용할 수 있는 상태에서 서버의 업데이트가 끝났다.

이 방식은 현재 사용 가능한 자원을 그대로 사용하여 무중단 배포를 할 수 있다는 장점이 있다. 서버를 증축할 필요도 없고 로드밸런서에서 해제하고 연결하는 작업을 통해 업데이트 자체도 간단하게 끝낼 수 있을 것이다. 하지만 이 방법에는 치명적인 단점이 몇가지 있다.

  1. 서버를 나눠서 업데이트 하기 때문에 업데이트 도중에는 가용서버가 필연적으로 적어진다.
  2. 만약 1.0.2버전에 문제가 있어서 버전을 롤백해야 하는 경우 같은 방식을 통해 롤백을 따로 해야한다.

첫번째 단점은 아마 이해하기 쉬울 것이다. 네개가 돌아가던 서버가 갑자기 두개만 돌아가게 되면 요청이 몰리는 두개의 서버에 부하가 걸리는 것은 당연하다. 물론 개발자가 바보가 아닌 이상에야 사용자가 가장 적게 몰리는 시간에 업데이트를 진행하고자 하겠지만, 마음대로 시간을 정해서 업데이트 하지 못한다는 단점은 어쨌든 생기는 것이다. 만약 사람이 적게 몰리는 시간대가 새벽이라면? 혹은 주말이라면? 누구도 야근이나 주말출근은 하고싶어 하지 않는다.

두번째 문제는 "그냥 롤백 하면 되잖아?" 라고 생각할 수 있지만, 우리의 인생이 그렇게 쉽게 진행될 리 없다. 만약 1.0.2버전에 문제가 많아서 롤백과 업데이트를 반복해야 한다면? 아니, 만약 그렇지 않다고 해도 한번의 롤백에만도 배포 -> 롤백 -> 다시 배포 의 3단계를 똑깥이 진행해야 하기 때문에 결코 효율적으로 보이지는 않을 것이다. 게다가 그렇게 롤백을 하면서도 1번의 문제를 계속 신경써야 하기 때문에 빠른 시간안에 이루어 질수록 좋은 서버 업데이트 작업에 차잘이 생길 수 있다.

Blue-Green Deployment

Blue-Green Deployment는 현재위치 배포의 단점을 어느정도 보완할 수 있는 방법이다. 우선 아래의 이미를 통해 서버의 구조를 보고 설명을 시작해 보자.
서버 구성도1
현재위치 배포에서 했던것과 비슷하지만 이번에는 4개의 서버가 하나의 그룹에 들어가 있다는 전제하에 설명을 진행하겠다. 특별이 뭔가 달라진 건 아니고 현재위치 배포에서 설정한 서버 4개도 하나의 그룹에 속해있다고 가정할 수 있지만 그러지 않는 편이 더 설명하기 편해서 그렇게 했다. 서버 설정은 동일하게 1.0.1버전이며 1.0.2버전으로 무중단 업데이트를 진행하는게 목표가 된다. 한 단계씩 진행해 보자.

  1. 우선 기존의 서버그룹과 같은 서버그룹을 하나 더 만든다. 서버 버전도 동일하고 모든게 똑같지만 로드밸런서에 연결되어 있지는 않다.
    서버 구성도2

  2. 복사한 서버그룹 내부의 서버들을 1.0.2버전으로 업데이트 진행한다. 여전히 로드밸런서에는 연결되어 있지 않다.
    서버 구성도3

  3. 업데이트가 진행된 복사한 서버그룹을 로드밸런서에 연결한다.
    서버 구성도4

  4. 기존에 존재하던 1.0.1버전 서버그룹을 로드밸런서에서 연결 해제한다. 이 상태부터 사용자들은 온전하게 1.0.2버전을 이용할 수 있게 된다.
    서버 구성도5
    짜잔! 이번에도 사용자는 서비스를 이용하는 것에 문제가 없었고 서버는 제대로 업데이트 되었다.

상당히 알기쉬운 방식이다. 그냥 업데이트된 서버를 만들어서 기존 서버 대신 연결하는 방식으로 사용했다. 덕분에 현재위치 배포의 단점 두가지를 동시에 해결할 수 있었다.

  1. 업데이트를 진행하는 도중에도 서버의 수는 그대로 유지되기 때문에 기존 사용되던 그대로 서버를 업데이트 하면 된다. 따라서 부하가 걸릴 위험이 사라진다.
  2. 만약 1.0.2버전에 문제가 있으면 아직 없애지 않은 1.0.1버전의 서버그룹으로 로드밸런서를 연결해 주기만 하면 된다. 이후에 1.0.2버전의 문제를 해결하고 다시 로드밸런서만 옮겨서 연결하면 된다.

하지만 이 방식에도 문제가 없는 건 아니다. 만약 서버가 구동중인 상황이 클라우드나 가상환경이 아니라면? 정말 그냥 컴퓨터를 통해 물리적인 서버로 존재한다면? 아무리 돈이 많은 회사라도 기존에 있던 서버의 환경과 같은 수준의 서버를 두배로 늘렸다가 필요 없어지면 다시 줄이는 비 효율적인 방식을 선택할 수 없다. 한마디로, 물리적으로 존재하는 서버에서는 사용하기 어려우며 현재위치 배포 방식이 더 어울린다. 블루/그린 방식은 쉽게 인스턴스를 생성하고 없앨 수 있는 클라우드 환경이나, 컨테이너를 올렸다가 내리는 것이 자유로운 Docker등의 가상환경에 어울리는 방식이다.

Conclusion

결론을 내려보자. 서버 무중단 배포를 위한 두가지 방식을 설명해 보았다. 두가지는 장단점이 다르고 어느정도 서로 보완하기도 하는 관계를 가지고 있다. 따라서 어느 것이 반드시 옳다고 결론내릴 수 없다. 개발자들에게 있어서 골은 하나라도 그 골까지 가는 방법은 언제나 여러개인 법이다. 서버도 마찬가지라고 생각하면 될 것이다. 자신이 속한 회사의 서버는 어떤 방식으로? 어떤 S/W로? 어떤 환경에서? 구동하는지 고려해야 한다. 심지어, 지금까지 이렇게 좋다고 난리를 치고서는, 무중단 배포조차 반드시 옳은 방식은 아니다! 중단 배포는 나빠, 무중단 배포는 좋아라는 공식은 절대적이지 않다. 예를 들어, 만약 데이터베이스의 스키마를 건드리는 업데이트가 필요할 경우에는 무중단 배포를 할 시 업데이트 된 서버와 안된 서버 사이에서 데이터베이스의 차이로 인한 문제가 발생할 수 있다. 따라서 그런 경우에는 중단 배포를 하는 게 옳은 방법이다. 결국 "업데이트 조건 + 서버 환경" 두가지를 모두 고려하여 가장 효율적인 방식을 선택하는 게 좋을 것이다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment