CI/CD

배포 롤백 — SemVer 로 기준을 세우고 blue/green 으로 되돌리기

배포 롤백 — SemVer 로 기준을 세우고 blue/green 으로 되돌리기

배포하다 보면 나가면 안 될 것이 나간다. 그때 필요한 건 되돌리는 능력이고,
그건 사고가 난 뒤에 만들 수 있는 게 아니다. 미리 정해 둬야 한다.

정할 것은 셋이다.

정할 것 답해야 하는 질문
기준점 어디로 되돌릴 것인가
아티팩트 예전 것을 쓸 것인가, 다시 빌드할 것인가
전환 방식 어떻게 바꿔 끼울 것인가

1. 기준점 — SemVer#

"이전 버전으로 돌려 주세요" 가 되려면 버전이 무엇인지 서로 같게 알고 있어야
한다.
그 약속이 SemVer(Semantic Versioning)다.

Major . Minor . Patch
  2   .   4   .   1
자리 언제 올리나
Major 이전 버전과 호환되지 않는 변경
Minor 호환되면서 기능이 추가·변경됨
Patch 단순 버그 수정

배포 시기나 분위기로 버전을 올리지 않고 변경의 성격으로 올리는 것이 핵심이다.
그러면 버전만 보고도 호환 여부와 어디까지 나갔는지 알 수 있다.

팁

롤백 관점에서 Major 자리가 특히 중요하다. Major 를 건너 되돌리는 것은
단순 교체가 아니다
— DB 스키마나 API 계약이 함께 바뀌었을 수 있다. 버전
번호가 "이 롤백은 위험하다" 를 미리 알려 주는 셈이다.

2. 아티팩트 — 보관할 것인가, 다시 빌드할 것인가#

참고

산출물을 어디에 쌓고 어떻게 배포 대상으로 넘기는지는
빌드한 산출물을 Ansible 로 넘기기에서 다룬다.

롤백에 쓸 산출물을 어떻게 마련하느냐에 두 갈래가 있다.

롤백 경로 두 가지. 빨간 선은 저장된 아티팩트를 바로 배포하고, 파란 선은 해당 버전 코드로 돌아가 다시 빌드한다
롤백 경로 두 가지. 빨간 선은 저장된 아티팩트를 바로 배포하고, 파란 선은 해당 버전 코드로 돌아가 다시 빌드한다

빨간 선 — 저장해 둔 아티팩트를 그대로 쓴다

  • git clone 과 build 를 건너뛰어 빠르다
  • 예전에 실제로 돌던 바로 그 산출물이라 동작이 보장된다
  • 대신 보관 공간이 필요하고, 며칠·몇 개를 남길지 정책을 정해야 한다

파란 선 — 그 버전 코드로 돌아가 다시 빌드한다

  • 저장 공간이 필요 없고 모든 버전으로 갈 수 있다
  • 대신 느리다. 장애 중에 빌드를 기다리는 것은 생각보다 길게 느껴진다

주의

파란 선에는 함정이 하나 더 있다. 같은 커밋을 빌드해도 결과가 같다는 보장이
없다.
의존성이 최신으로 당겨지거나 빌드 도구 버전이 달라지면 그때와 다른
산출물이 나온다. "되돌렸는데 같은 증상" 이 여기서 온다. 의존성을 잠가 두지
않았다면 빨간 선이 훨씬 안전하다.

실무에서는 대개 섞는다. 최근 몇 개 버전은 아티팩트를 보관해 빠르게 되돌리고,
그보다 오래된 것은 재빌드로 간다.

3. 전환 방식별 롤백#

롤링 배포#

인스턴스를 하나씩 차례로 새 버전으로 바꾼다. 롤백도 똑같이 하나씩 되돌린다.

  • 추가 장비가 필요 없다
  • 대신 인스턴스가 많을수록 오래 걸린다. 되돌리는 동안 신·구 버전이 섞여 있다

주의

롤링 중에는 같은 서비스의 두 버전이 동시에 떠 있다. 두 버전이 같은 DB 를
보고 있다면 스키마가 양쪽 모두와 호환돼야 한다. 롤백 시간이 길수록 이 구간도
길어진다.

Blue/Green 배포#

운영과 같은 환경을 하나 더 두고 통째로 갈아 끼운다. 롤백에 최적화된 방식이다.

① 평소 — A 그룹만 서비스한다

로드밸런서가 A 그룹만 바라보고 있고, B 그룹은 멤버에서 빠져 있다
로드밸런서가 A 그룹만 바라보고 있고, B 그룹은 멤버에서 빠져 있다

② 배포 — 빠져 있는 B 그룹에 새 버전을 깐다

아티팩트 저장소에서 B 그룹의 인스턴스들로 새 버전이 배포되는 모습
아티팩트 저장소에서 B 그룹의 인스턴스들로 새 버전이 배포되는 모습

B 는 트래픽을 안 받고 있으니 배포 중에 서비스 영향이 없다.

③ 전환 — 로드밸런서를 B 로 돌린다

로드밸런서가 B 그룹을 바라보도록 전환된 모습
로드밸런서가 B 그룹을 바라보도록 전환된 모습

모든 인스턴스가 한 번에 바뀐다. 롤링과 달리 신·구가 섞이는 구간이 없다.

④ 롤백 — 로드밸런서를 A 로 되돌린다

문제가 생기면 git clone 도 빌드도 배포도 다시 할 필요가 없다. 로드밸런서
방향만 A 로 돌리면 끝이다.
A 그룹은 조금 전까지 멀쩡히 돌던 환경 그대로다.

참고

대가는 비용이다. 운영의 두 배 환경을 늘 갖고 있어야 한다. 클라우드라면
전환 후 옛 그룹을 줄여 비용을 낮출 수 있지만, 그러면 롤백 자산도 같이
사라진다.
얼마나 오래 A 를 살려 둘지가 곧 "얼마나 오래 되돌릴 수 있는가" 다.

비교#

롤링 Blue/Green
추가 환경 필요 없음 운영의 2배
배포 속도 인스턴스 수에 비례 전환 한 번
롤백 속도 느림 (하나씩 되돌림) 빠름 (LB 전환)
신·구 혼재 있음 없음

확인#

롤백 절차는 사고 전에 한 번 해 봐야 쓸 수 있다. 점검할 것은 이 정도다.

  • 되돌릴 대상이 특정되나 — "지난 버전" 이 아니라 2.4.0 처럼 말할 수 있나
  • 아티팩트가 실제로 있나 — 보관 정책대로 남아 있는지 목록을 직접 본다
  • 얼마나 걸리나 — 재빌드 경로라면 실제로 재 본다. 생각보다 길다
  • DB 는 되돌아가나 — 대부분의 롤백 사고는 여기서 난다. 코드는 돌아갔는데 스키마가 안 돌아가면 더 나빠진다

주의

스키마 변경은 롤백과 함께 되돌리기 어렵다. 컬럼을 지우는 마이그레이션이
나간 뒤 코드만 되돌리면 옛 코드가 없는 컬럼을 찾는다. 그래서 스키마 변경은
지우지 않고 더하는 방향으로 두 단계에 나눠 배포하는 것이 안전하다.

정리#

  • 롤백은 사고 전에 정해 두는 것이다. 기준점·아티팩트·전환 방식 셋을 미리 정한다.
  • SemVer 는 버전 규칙이 아니라 합의다. Major 를 건너는 롤백은 단순 교체가 아니다.
  • 보관이냐 재빌드냐는 속도와 공간의 맞교환이다. 다만 재빌드는 같은 결과를 보장하지 않는다 — 의존성을 잠그지 않았다면 보관 쪽이 안전하다.
  • Blue/Green 의 롤백은 로드밸런서 전환 한 번이다. 대가는 두 배의 환경 비용이고, 옛 그룹을 줄이는 순간 롤백 자산도 사라진다.
  • 코드는 되돌아가도 DB 는 안 돌아간다. 스키마 변경은 지우지 말고 더하는 방향으로 나눠 배포한다.
공유
욱콩

욱콩

서버와 배포를 만지면서 겪은 것을 기록합니다. 직접 돌려 보고 나온 결과만 씁니다.

댓글

댓글 남기기