배포는 어떻게 하세요?

Pak Yeongjo·2022년 4월 5일
0

일 어떻게 하세요?

목록 보기
2/3

이 포스팅은 EC2 linux에서 git pull && nginx restart && guincorn restart를 반복하던 경험에 대한 반성입니다.

0. 배포는 어떻게 하세요?

1)
기획은 항상 디벨롭되고 요구사항은 하루에도 몇 번씩 쏟아지고 바뀐다.
태스크를 쳐내기 위해 API 코드는 계속 바뀌고 코딩은 끝나지 않을 것 같다.
그래도 어찌어찌 이번 태스크를 마무리 짓고 상용 서버에 반영하는 일만 남았다. 로컬에서 api 요청을 날려봤더니 정상적으로 동작하는 것 같다. 빨리 배포하고 슬랙에 요구사항 반영됐으니까 확인해달라고 메세지를 날리고 싶다.

2)
어차피 내 컴퓨터에는 ec2 서버에 대한 권한 설정도 다 되어있고 심지어 접속 커맨드도 alias로 등록되어 있어서 슥 접속하고 샥 pull을 땡긴다. 애플리케이션이 변경되었으니까 gunicorn을 리부팅해주고 혹시 모르니까 nginx도 한 번 재시작해준다. 필요없다고 한거같지만 조심해서 나쁠거 없다.

3)
반영이 잘 된거 같으니까 노션을 키고 다음 요구사항이 뭐였는지 찾아본다. 오늘 퇴근하기 전까지 이 작업을 두세번은 더 해야할 듯 하다.

4)
앗챠, 방금 배포한 코드에 연산자 하나가 잘못된거같다. gte로 잡았어야 할 쿼리를 gt로 배포한걸 발견한다. Git Flow에서 재빨리 Hotfix 브랜치를 하나 따고 gt를 gte로 바꿔준다. commit message에는 대충 fix query expression이라고 남겨주고 부가 설명으로 Customer age gt -> gte라고 남겨준다.

5)
2번을 반복하고 슬랙에 롤백 완료라고 메세지를 남겨둔다. 노션에 작성하던 배포 문서에도 Hotfix 내용을 추가하고 내 실수를 기록한다. 다시 3번으로 가서 아까 읽던 다음 요구사항을 마저 읽는다.

1. CI/CD?

CI/CD는 애플리케이션 개발 단계를 자동화하여 애플리케이션을 보다 짧은 주기로 고객에게 제공하는 방법입니다. CI/CD의 기본 개념은 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포입니다. CI/CD는 새로운 코드 통합으로 인해 개발 및 운영팀에 발생하는 문제(일명 "인테그레이션 헬(integration hell)")을 해결하기 위한 솔루션입니다.

만약 당신이 서버 개발자인데 무중단 배포가 뭔지 모르고 테스트 코드는 바빠서(혹은 게을러서) 미뤄뒀고 롤백이 뭐야, 비즈니스 로직을 다시 이전으로 돌려서 또 배포하면 그게 롤백 아냐? 라고 생각한다면 위의 개념은 필요가 없을지도 모르겠다.

맞다. 내 얘기다.

CI/CD는 이메일 발송처럼 하나의 모듈이나 제품으로 뚝딱 처리할 수 있는 개념이 아니다. 자세한 내용은 수도 없이 많은 레퍼런스가 있기 때문에 서술하지 않겠다.

위의 개념을 기억하고 다시 글의 처음으로 돌아가서 찬찬히 읽어본다.

2. 이제 좀 뭐가 문제인지 아시겠어요?

1. 테스트는 어디 갔을까요?

DRF 서버에는 swagger ui가 붙어있을 것이다. 여기서 요청을 날려봤을 수도 있고 postman에서 케이스별로 요청을 날려봤을 수도 있다. 어찌됐든 새로 추가된 비즈니스 로직의 검증으로는 부족하다. 유닛 테스트를 붙여놓고 Github action 등으로 자동 테스트를 수행했으면 상용 서버에 올라가기 전에 잘못된 쿼리 표현식을 잡아낼 수 있지 않았을까?

다음이 아마 문제가 가장 많을 부분이다. 나눠서 생각해보자.

2-1. OS는 신경안쓰세요?

장고 어플리케이션을 로컬에서 돌리려면 보통 가상환경을 사용해야 할 것이다.

개발 장비로 보통 맥북을 많이 사용하는데 가끔 Cpython 기반의 라이브러리 중 설치 과정에서 컴파일이 필요한 모듈이 있다.
맥북에서 pip install을 날리면 Mac OS에서 컴파일이 될 것이다. 이 모듈이 Linux EC2에서도 정상적으로 import 될 것이라는 보장은 어디에도 없다.
애초부터 어플리케이션을 도커라이징 했으면 걱정하지 않아도 될 것이다.

이거 말고도 협업 과정에서 각자의 로컬 세팅이나 IDE 세팅의 차이가 발생시킬 수 있는 문제들까지 고려하면 더욱 머리가 아파질 것이다.

2-2. 저는 EC2 인스턴스가 하나가 아닌데요?

Auto Scailing을 사용한다면? 모든 인스턴스에 하나하나 접속해서 코드를 최신화 해줘야 할까? 작업 중간에 변경된 API에 요청이 들어온다면 그 요청은 최신화 된 인스턴스를 찾아갈까, 아직 최신화 되지 않은 인스턴스를 찾아갈까?

심지어 작업 내역이 DB 변경과 관련된 내용이라면? RDS는 이미 업데이트 됐는데 EC2는 따라가지 못했다면?

AWS Beanstalk, 혹은 ECS 등의 선택지를 이용하는 방법을 고려해봐야 할 것이다.

3. 사실 이게 핵심이다.

배포 과정이 복잡해지고 길어진다는 것은 실수가 개입할 여지가 많아진다는 소리와 같다.
기민한 대응을 위해서는 이 과정 전체를 하나의 파이프라인으로 정리하고 관리할 수 있어야 한다.

4. 롤백이 뭔지 잘 모르죠?

어디서 본건 있어서 얼추 깃플로우의 이념을 따라가긴 했다.
Git은 본질적으로 버전 관리 시스템이다. Hotfix를 따고 커밋 메세지를 신중하게 작성한다고 서버의 생명 주기를 모두 담을 수는 없다.

그리고 애초에 코드를 고쳐서 다시 배포하는건 롤백이 아니다! 장애 발생 시 롤백에 대한 룰을 정해놓는 것이 최선이다.

5-1. 배포 기록은 관리 안하세요?

배포를 수작업으로 진행한다면 노션이나 깃허브 도큐 등을 사용해서 배포 기록을 관리하게 된다. 만약 귀찮아서, 까먹어서 누락되는 내역이 있다면? 문서의 포맷이 나중에 변경됐을 때 이전의 배포 내역의 해당 필드를 추가하려면?

5-2. 그래서 이번 배포는 괜찮았나요?

1번과 마찬가지로 여전히 테스트는 빠져있기 때문에 새로 배포한 서버가 정상적이라는 보장은 어디에도 없다. 어쩌면 이 사람은 다시 4번으로 돌아가야 하는 상황이 올지도 모르고 다음 요구사항은 영원히 시작하지 못하게 될 수도 있다.

References

0개의 댓글