Renewal_Deploy

장준영·2024년 5월 13일

개요

근 2년간 작업을 하였던 코인 리뉴얼에 대한 배포를 하게 되었다.

배포에 대한 고민

본인이 오기 전부터 코인에 대한 리뉴얼 버전이 스테이지에서 2년간 작업 중이었다.
코인 리뉴얼 버전에서는 사장님/어드민 기능등이 추가 되었으며, Refresh Token도입, presignedURL, DB정규화 등 다양한 기능들이 추가 되었다.
https://github.com/BCSDLab/KOIN_API/pull/342

안드로이드의 작업이 마무리 되어 강제 업데이트를 하였기에 사용자가 적은 일요일에 대응을 하게 되었다.

현재 스테이지에서 프로덕션으로 배포를 안한지 오랜 기간이 지났기에 sql버젼 등의 부조화로 인해 AMI를 활용하여 스테이지 서버를 복제한 CBT서버를 만든뒤, 프로세스를 켜고, 각종 연결을 다시 설정하여 ELB에 연결하여 배포하는 방식으로 진행을 하기로 하였다.

먼저 무중단 배포의 방식에 대해 알아보도록 하겠다.

무중단 배포에는 크게 3가지의 방식이 있다.

  1. 롤링배포
  2. 블루/그린 배포
  3. 카나리 배포

롤링배포

  • 트래픽을 점진적으로 구버전에서 새로운 버전으로 옮기는 방식
  • 점진적으로 트래픽을 어떻게 새로운 버전으로 옮길 수 있을까?

방식1

  • 기존의 v1서버를 3대 운영중이라고 하자
  • 우선 v2의 인스턴스를 하나 추가한다. 로드 밸런서에 이 인스턴스를 연결한 후 기존 3대의 v1서버를 하나씩 삭제한다.
  • 서버 개수를 유연하게 조절 할 수 있는 클라우드를 기반으로 서비스를 운영할때 적합하다.

방식2

  • v1이 실행되고 있는 서버 하나를 로드밸런서에서 뗴어낸다
  • 해당 서버에는 트래픽이 도달하지 않으므로 이 상태에서 해당 서버의 어플리케이션을 v2로 교체한다
  • 이 과정을 반복하며 모든 서버를 v2로 교체한다.

장점
롤링 배포 방식은 k8s, elastic beanstalk와 같은 많은 오케스트레이션 도구에서 지원하여 간편하다
또한 많은 서버 자원을 확보하지 않아도 무중단 배포가 가능하다.
단점
방식2와 같은 경우 배포 도중 서비스 중인 인스턴스의 수가 줄어들게 되어 각각의 서버가 부담하는 트래픽의 양이 늘어날 수 있다.
구버전과 신버전의 어플리케이션이 동시에 서비스 되기 때문에 호환성 문제가 발생할 수 있다.

블루/그린 배포

  • 트래픽을 한번에 구버전에서 신버전으로 옮기는 방법이다.
  • 현재 운영중인 서비스 환경을 블루라고 부르고, 새롭게 배포할 환경을 그린
  • 블루와 그린의 서버를 동시에 나란히 구성해둔 상태로 배포 시점에 로드밸런서가 트래픽을 블루에서 그린으로 일제히 전환시킨다.
  • 그린 버전 배포가 성공적으로 완료되었고, 문제가 없다고 판단할 때 블루 서버를 제거할 수 있다.

장점
롤링배포와 달리 한번에 트래픽을 모두 새로운 버전으로 옮기기 때문에 호환성 문제가 발생하지 않는다.
단점
실제 운영에 필요한 서버 리소스 대비 2배의 리소스를 확보해야 한다.

카나리 배포

  • 점진적으로 구부전에 대한 트래픽을 신버전으로 옮기는 것은 롤링배포 방식과 동일
  • 하지만 카나리 배포의 핵심은 새로운 버전에 대한 오류를 조기에 감지하는 것이다.
  • 소수 인원에 대해서만 트래픽을 새로운 버전에 옮겨둔 상태에서 서비스를 운영한다.
    A/B테스트를 진행할 수 있다.

장점
새로운 버전으로 인한 위험을 최소화 할 수 있다.
단점
롤링 배포와 마찬가지로 호환성 문제가 발생할 수 있다.

대응방안

현재 코인은 두가지 버전의 서버로 구성되어 있다. Production과 Stage 서버이다.
위에서도 언급하였다시피 리뉴얼 버전을 근 2년간 배포를 하지않았기에 두 서버간의 버전차이가 상당히 많이 났다.(우분투, tomcat, redis, sql버전등) 그렇기에 고안한 방법은 현업의 local-sandbox-stage-cbt-production의 계층을 채택하여 임시의 CBT서버에 Stage서버의 AMI를 바탕으로 환경을 구성하고 CBT환경에서의 테스트가 모두 끝나면 ELB를 CBT서버로 돌리고 기존의 Production서버는 종료하는 방식을 채택하였다.
이유는 일단 프로덕션의 버전이 너무 오래되었기에(우분투 같은 경우는 이미 지원을 종료한 버전이다.) 한번 업데이트를 시켜줄 필요가 있었다.
굳이 치자면 블루그린 배포를 채택하였다.

이 방식을 정리해보자면 다음과 같은 진행방식으로 진행이 되었다.
1. Stage서버에 AMI를 만든다.(이미지와는 다르게 OS까지 함께 채용한다.)
2.AMI를 바탕으로 CBT서버를 새로 만든다.
3. 기존의 서버 재부팅 매뉴얼을 활용하여 프로세스 세팅을 빠르게 한다.
4. koreaech.in, stage.koreatech.in처럼 새로운 cbt.koreatech.in이라는 도메인을 새로 만든다.
4. jenkins의 CBT용 ci/cd를 생성한다.
5. jenkins를 활용하여 was업데이트를 한다.(Stage서버를 따왔기 때문에 tomcat버전에는 크게 문제가 없지만 DB의 flyway가 잘돌아가는지는 체크를 해줘야 한다.)
6. 미리 CBT 서버에서스웨거 상에서 테스트를 진행하여 본다.
7. 이상없이 돌아간다면 기존 DB를 덤프를 활용하여 데이터베이스 마이그레이션을 진행한다.

이 방법에는 문제가 발생한다. 사실 이정도 규모에서는 큰 차이가 없지만 데이터베이스 마이그레이션 도중(dump후 flyway돌리기) 유저의 회원가입이 일어난다면 유저가 손상이 될수 있다. 그래서 추후 DB서버를 꼭 분리해야겠다는 생각을 하였다.

하지만 이렇게 거대한 배포는 처음이기도 하였고 마이그레이션의 복잡성으로 인해 문제가 발생하였다.

배포중의 문제

  1. 기존의 Production서버 DB의 Dump파일의 import도중 쿼리문이 많아 network가 fail이 자주 일어나서 기존의 안드로이드배포에 시간을 맞추지 못하였다.

해결방안: 급하게 Mysql의 MaxBuffer를 올려주어 해결하였다. DB_Migration_Guide를 만들어두어 추후 dump이관시 해결할수 있도록 하였다.(프로세스상의 방식도 메커니즘은 동일하다)

  1. elb health check issue -> nginx에서 443포트 열어줘야 하는데 열어주지 못하였다.
    최근 AWS의 비용을 절감하는 목적으로 그전에 존재하던 ELB를 Production서버를 제외한 나머지 서버의 ELB를 제거하며 nginx에서 https를 처리하게 바꾼줄 알았다. 당연히 Stage서버의 환경을 따왔으니 이것을 Production에 맞게 설정을 다시하였는데 알고보니 ELB는 현재 http로 들어오는 요청을 https로 리다이렉트 하는 역할만 할 뿐, nginx에서 https인증을 처리하고 있었다.

해결방안: nginx에서 https처리를 할수있게 세팅을 완료하였다. 이번에는 배포를 하며 elb의 도움을 받았지만 elb에서 https리다이렉션만 하는데, 과연 필요할까에 대한 고민을 하게 되었다.

  1. flyway적용시 중간의 py파일의 부재로 인해 db정규화에 실패하였다.
    이전 트랙장이 하였던 데이터베이스 정규화 처리를 Flyway를 통해 진행을 하였다.
    flyway의 방식이 이전의 문제는 flyway도중 python파일을 하나 실행시켜야 하는데, 이전 트랙장이 Stage서버에는 flyway를 잘 적용하였지만 인수인계의 문제로 DB마이그레이션 과정에서는 문제가 생겼다. flyway는 정상 빌드되었지만 추후에 문제가 된것이 배포가 된줄알고 대기를 하던 도중 SQL에서 오류를 계속 뿜어대었다.

해결방안: 로그를 살펴보니 flyway가 정상진행되려면 v1-60, python코드실행, v62-78실행 이런식이 되어야 하는데 중간의 python파일 실행이 안되어 hotfix를 파서 해결을 하였다.

후기

완성된 인프라는 다음과 같다.

바뀐게 많이 없어보이지만 EOS된 Ubuntu16.04.6LTS에서 Ubuntu20.04.4LTS로 올리게 되었고,
Mysql도 5.1에서 5.7버전으로 업데이트를 하였다.(추후 한번더 업데이트를 할 예정이다.)

여러모로 해결할 것이 많이 있었다. 이전의 서버 다운이 발생할 적이나 에러가 나올경우 대응을 한적은 많았지만 무중단 배포에 대한 고민을 하면서 아키텍처를 변경하면서 조금더 유연하게 대응을 해야 할 필요가 있다고 생각하며, 신기능을 스테이지에 계속 쌓아두는것이 아닌 프로덕션에 주기적으로 배포하는 스프린트의 중요성에 대해 알게 되었다.

0개의 댓글