배포를 우아하게 - 원-클릭(one-click) 배포

Image not Found

일반적으로 런타임 환경이 늘어날 수록 배포 시스템의 복잡성은 높아지기 마련입니다. 이 글에선 버즈빌에선 어떻게 문제를 해결했는지 소개합니다.

배포를 우아하게 - 원-클릭 배포

Demo

현재 버즈빌은 사용자가 UI에서 단 몇 번만의 클릭만으로 서비스를 배포하고 있으며, 어플리케이션의 런타임(runtime) 환경과 상관없이 동일한 방법으로 배포하고 있습니다. 런타임 환경이란 프로그램이 실행되는 환경을 의미합니다. 버즈빌은 런타임 환경으로 AWS EKS 기반의 쿠버네티스(Kubernetes), AWS 람다(Lambda), AWS S3등을 사용하고 있고 각 런타임 환경 별로 다른 배포 도구를 사용하고 있습니다. 그러나 여러 배포 도구를 사용하고 있음에도 사용자는 동일한 방식으로 배포합니다.

일반적으로 런타임 환경 별로 배포 도구가 다르기 마련입니다. 버즈빌은 쿠버네티스는 스피네이커(Spinnaker), AWS S3는 드론(Drone) CI를 사용하고 있습니다. 그리고 배포 도구 별로 다른 배포 방식을 가지게 됩니다. 따라서 사용자는 각각의 배포 도구 사용에 익숙해져야 하며, 배포 파이프라인의 구체적인 내용을 이해하고 있어야만 합니다. 즉, 런타임 환경이 늘어나면 배포 시스템의 복잡성도 커지게 됩니다.

단순한 해결책으로는 한 개의 배포 도구만 운영하는 방법이 있습니다. 하지만 단 하나의 배포 도구는 각 런타임 환경에서 필요한 기능들을 모두 만족하기 어렵습니다.

버즈빌은 깃헙(GitHub) 배포 API를 통해서 배포 파이프라인을 추상화해서 이 문제를 해결했습니다. 사용자는 직접 배포 도구와 상호작용 없이 깃헙 API만을 통해 배포를 트리거하고 배포 상태을 확인할 수 있습니다. 따라서 사용자는 동일한 방식으로 배포가 가능해집니다. 다음은 깃헙 배포 API를 알아보고 버즈빌에선 어떻게 이용하고 있는지 살펴보도록 하겠습니다.

깃헙 배포 API

버즈빌은 소스 코드 관리 도구로 깃헙(GitHub)을 이용하고 있으며, 깃헙에서 제공하고 있는 배포 API를 사용하고 있습니다. 배포 API는 특정 ref(브랜치, 커밋 또는 태그)에 대한 배포를 깃헙에 요청합니다. 그리고 깃헙에선 배포 API가 호출되면 이벤트를 배포 도구에 전달하게 됩니다.

또한, 깃헙은 배포 상태 API를 제공하는데 외부에서 배포의 상태를 업데이트할 때 사용됩니다. 배포 상태 API는 여러 상태를 표현할 수 있도록 status 파라미터를 제공하고 있으며, 선택적으로 description, log_url 파라미터를 통해 배포 상태를 자세하게 설명할 수 있도록 합니다.

아래는 버즈빌의 도구들이 깃헙과 어떻게 상호작용하는지 보여주는 다이어그램입니다. 사용자는 Trigger 만을 통해서 깃헙과 통신합니다. 그리고 깃헙은 3rd Party 배포 도구 - 스피네이커나 드론 CI - 를 통해서 배포합니다.

+---------+             +--------+            +-----------+        +-------------+
| Trigger |             | GitHub |            | 3rd Party |        |   Server    |
+---------+             +--------+            +-----------+        +-------------+
     |                      |                       |                     |
     |  Create Deployment   |                       |                     |
     |--------------------->|                       |                     |
     |                      |                       |                     |
     |  Deployment Created  |                       |                     |
     |<---------------------|                       |                     |
     |                      |                       |                     |
     |                      |   Deployment Event    |                     |
     |                      |---------------------->|                     |
     |                      |                       |       Deploys       |
     |                      |                       |-------------------->|
     |                      |                       |                     |
     |                      |   Deployment Status   |                     |
     |                      |<----------------------|                     |
     |                      |                       |                     |
     |                      |                       |   Deploy Completed  |
     |                      |                       |<--------------------|
     |                      |                       |                     |
     |                      |   Deployment Status   |                     |
     |                      |<----------------------|                     |
     |                      |                       |                     |

배포 API는 배포를 안전하고 유연하게 할 수 있도록 다양한 파라미터를 제공하고 있습니다. 다음은 배포 API에서 제공하고 있는 주요 파라미터를 소개하고 버즈빌에서 어떻게 사용을 하고 있는지 설명하겠습니다.

ref 파라미터는 브랜치 명, 태그 명 또는 커밋 SHA 값이 될 수 있습니다. 버즈빌에선 지속해서 배포하는 어플리케이션은 브랜치 또는 커밋 SHA 값을 이용하고 있고, 시맨틱 버저닝을 사용하는 어플리케이션을 태그를 사용하고 있습니다.

environment 파라미터는 배포될 환경을 지정하는 데 사용됩니다. 버즈빌에선 목적에 따라서 몇 가지 환경 - dev, staging, prod - 을 제공하고 있습니다. 엔지니어는 작업 중인 브랜치를 특정 환경에 배포해서 어플리케이션을 검증합니다. 또한 환경별로 배포 기록을 수집해서 변경 내용을 추적하고 있습니다.

auto_merge 파라미터는 선택된 ref 가 레포지토리의 기본 지점보다 앞에 있는지 검증하는 데 사용됩니다. 만약 ref가 레포지토리의 기본 지점보다 뒤에 있다면 깃헙에서 자동으로 머지합니다. 버즈빌은 auto_merge 를 통해 운영 환경에 배포 시 메인 브랜치가 반영될 수 있도록 합니다.

required_contexts 파라미터는 success 여야만 하는 커밋의 컨택스트(context)을 지정할 수 있습니다. 예를 들어, 아래와 같이 두 개의 커밋 컨택스트 중 하나만 선택한다면 required_contexts 로 지정이 가능합니다. 버즈빌에서 쿠버네티스로 배포하는 경우 해당 커밋에 도커 이미지의 존재 여부를 검증하기 위해서 사용하고 있습니다(i.e., required_contexts: ['docker-image']).

커밋 컨택스트

payload 파라미터는 배포 도구에 추가로 필요한 정보를 전달하는 데 사용됩니다. 버즈빌은 payload 를 통해 사용자가 배포하는 시점에 배포 전략을 선택할 수 있게 합니다. 현재는 두 가지 배포 전략 - 롤링 업데이트와 카나리 배포 -를 제공하고 있으며, 배포 시 샐렉트(Select) 박스로 선택이 가능합니다.

이벤트 기반 배포 시스템

저희가 깃헙 배포 API를 중심으로 배포 시스템을 구축한 이유는 배포 도구를 느슨하게 결합하기 위해서입니다. 많은 경우 배포 시스템은 배포 도구와 강력하게 결합이 되며, 배포 시스템은 배포 도구에 의존성을 가지게 됩니다. 만약 필요에 의해 배포 도구를 변경하고 싶어도 변경할 수 없는 상황이 되는 것입니다. 버즈빌은 문제를 해결하기 위해 깃헙 배포 API를 통해서 각 도구의 사용법을 추상화했습니다. 추상화를 통해서 사용자는 배포 도구들과 상호작용하는 것이 아닌 깃헙 배포 API와 상호작용함으로 항상 동일하게 배포할 수 있습니다.

시스템 구축은 여러 도구를 가져와서 조합함으로 자체적인 개발 없이 빠르게 구성이 가능했습니다. 먼저 깃헙 배포 API와 통신 - 다이어그램에서 Trigger - 하기 위해서 깃플로이(Gitploy)를 선택했습니다. 깃플로이는 직관적인 UI를 제공하고 있어 낮은 러닝(learning) 커브를 보장할 수 있었습니다. 그리고 배포 도구 - 다이어그램의 3rd Party - 로 쿠버네티스는 스피네이커(Spinnaker), AWS S3나 람다 는 드론(Drone) CI를 선택했습니다.

또한 사용자는 롤백, 락(Lock), 리뷰 등의 배포에 필수적인 기능을 동일하게 실행할 수 있게 됐습니다. 기존에는 각 배포 도구별로 사용법을 익혀야 했다면 더 이상 도구를 배우는 데 시간을 소비하지 않을 수 있었습니다.

마치면서

저는 깃헙 배포 API가 코드(code)에서 인터페이스(interface)와 비슷하다고 생각합니다. 코딩에서 인터페이스가 복잡성을 낮추고 확장성을 높이는 역할을 하듯이, 배포 시스템에선 깃헙 배포 API를 통해서 같은 효과를 경험할 수 있었습니다. 그리고 이를 통해 버즈빌의 배포 시스템은 훨씬 유연해질 수 있었습니다. 만약 여러분이 확장성 있는 배포 시스템을 고민하고 있다면 이 글이 도움이 됐으면 좋겠습니다.

아쉽게도 해당 글에서 시스템 구현을 포함하지 못했습니다. 하지만 다음 글 - 배포를 안전하게 - 에서 실제 구현과 과정에 배운 점들을 공유할 수 있도록 하겠습니다. 긴 글 읽어주셔서 감사합니다. 다음 글도 기대해주세요!

버즈빌 개발자 지원하기 (클릭)

버즈빌 테크 리크루터와 Coffee Chat하기 (클릭)

You May Also Like

버즈빌, 아마도 당신이 원하던 회사!

지원하기