사전 배포
개념

배포

gabury1

만든 소프트웨어를 실제로 도는 자리에 올려 쓸 수 있게 만드는 일입니다. 코드를 다 짜 두어도 그것만으로는 아무도 그 기능을 쓰지 못합니다. 누군가 그 자리로 옮겨 놓고 켜 주어야 합니다.

상세

「이사한다」는 말 한마디가 짐을 싸는 일, 트럭에 싣는 일, 새 집에 들여놓는 일, 풀어서 놓는 일, 안 쓰게 된 짐을 버리는 일을 다 가리킵니다. 그래서 「이사 끝났어?」라는 물음에 바로 답하기가 어렵습니다. 트럭이 떠난 때가 끝인지 박스를 다 푼 때가 끝인지는 묻는 사람마다 다릅니다.

배포는 소프트웨어를 쓸 수 있는 상태로 만드는 활동을 통틀어 부르는 말입니다. 한 번의 사건이 아닙니다. 만든 쪽이 내보낼 준비를 하는 일이 들어갑니다. 받는 쪽이 설치하는 일과 켜는 일도 들어갑니다. 켜 둔 것을 끄는 일, 새 판으로 갈아 끼우는 일, 더 쓰지 않는 것을 지우는 일도 같은 이름 아래 묶입니다. 올려 둔 것을 앞 판으로 되돌리는 일도 마찬가지입니다.

묶음이라서 「배포가 끝났다」의 기준이 저절로 정해지지 않습니다. 파일이 서버에 놓인 시점을 끝으로 볼 수도 있습니다. 프로세스가 새 판으로 다시 뜬 시점을 끝으로 볼 수도 있습니다. 마지막 사용자의 기기까지 새 판이 닿은 시점을 끝으로 볼 수도 있습니다. 어느 시점을 끝으로 잡느냐에 따라 같은 작업이 배포 한 건이 되기도 합니다. 여러 건이 되기도 합니다.

배경

만드는 쪽이 완성된 시스템 전체를 통째로 나눠 주지 않습니다. 여기서 문제가 시작됩니다. 1998년 콜로라도대 기술보고서 「A Characterization Framework for Software Deployment Technologies」가 이 상황을 적어 둡니다. Carzaniga 와 공저자들은 생산자가 자기 시스템이 돌아갈 환경의 불확실성을 더 크게 감당해야 한다고 적습니다. 설치가 성공한다고 보장하려면 그 자리에 어떤 구성요소가 있는지를 먼저 판별할 수 있어야 합니다. 그 구성요소들이 어떻게 설정되어 있는지도 판별할 수 있어야 합니다. 구성요소는 여러 조직이 나눠 만듭니다. 그래서 자기 통제 아래 있지 않은 구성요소의 갱신을 미리 내다보거나 뒤늦게라도 대응할 수 있어야 합니다.

같은 보고서는 이것이 만만찮은 일이라고 적습니다. 릴리스·설치·활성화·비활성화·갱신·제거 영역에 새 과제를 만든다는 것입니다. 그리고 그 활동들이 크고 복잡한 하나의 프로세스를 이룬다고 적습니다. 자신들은 그것을 소프트웨어 배포라고 부릅니다. 흩어져 있던 일들을 한 이름으로 묶은 자리입니다.

flowchart TD
    A[내보내기] --> B[설치]
    B --> C[켜기]
    C --> D[끄기]
    D --> E[갱신]
    E --> C
    D --> F[지우기]
활동 보고서가 적은 것
내보내기 개발 프로세스와 배포 프로세스가 맞닿는 접점입니다. 소비자 자리로 조립·전달할 준비에 필요한 모든 작업을 아우릅니다. 패키징과 알리기가 여기 들어갑니다
설치 소비자 자리에 시스템을 처음 집어넣습니다. 대개 배포 활동 가운데 가장 복잡합니다. 전송과 설정 두 하위 활동으로 나뉩니다
켜기 시스템의 실행 가능한 구성요소를 시동합니다
끄기 켜기의 역입니다. 갱신 같은 다른 배포 활동에 앞서 흔히 요구됩니다
갱신 설치의 특수한 경우입니다. 필요한 자원 상당수를 설치 때 이미 확보해 두었습니다. 그래서 대개 덜 복잡합니다
지우기 그 자리에서 더 필요하지 않은 시스템을 제거합니다. 지우려면 먼저 꺼져 있어야 합니다

보고서는 여기에 두 가지를 덧붙입니다. 하나는 갱신과 적응이 갈리는 자리입니다. 갱신은 원격 사건에서 시작됩니다. 적응은 소비자 자리의 환경 변화 같은 지역 사건에서 시작됩니다. 다른 하나는 마지막에 은퇴가 있다는 것입니다. 시스템이 낡은 것으로 표시되는 자리입니다. 생산자의 지원도 철회됩니다. 알려진 소비자 모두에게 그 철회를 알려야 합니다.

경계

서버에 올라갔지만 기능 스위치가 꺼져 있는 것

새 코드가 프로덕션에 올라갔습니다. 프로세스까지 새 판으로 다시 떴습니다. 그런데 그 기능을 켜는 스위치가 꺼져 있습니다. 배포된 것인가. 배포된 것입니다.

기능 스위치는 배포와 다른 축에 있습니다. AWS(Amazon Web Services) AppConfig 문서는 기능 스위치를 애플리케이션 안에서 어떤 기능의 동작을 제어하는 데 쓰는 설정 유형이라고 정의합니다. 스위치 하나는 켜짐이나 꺼짐이라는 상태를 갖습니다. 문자열·숫자·불리언·배열 값을 담는 속성 묶음을 선택적으로 함께 갖습니다. 스위치가 꺼져 있다는 것은 설정 값이 그렇다는 뜻입니다. 새 판이 그 자리에 안 올라갔다는 뜻이 아닙니다. Google 의 SRE(Site Reliability Engineering) Book 은 구성을 메인라인에서 관리하는 방식을 적습니다. 그 결과로 바이너리 릴리스와 구성 변경이 분리된다고 적습니다.

세는 쪽도 같은 자리에 선을 긋습니다. Google Cloud 가 운영하는 DORA 프로그램은 배포 빈도를 주어진 기간의 배포 횟수, 또는 배포와 배포 사이의 시간으로 정의합니다. 변경 리드 타임은 버전 관리에 커밋된 시점부터 프로덕션에 배포된 시점까지 걸리는 시간으로 정의합니다. 세는 단위가 「프로덕션에 배포되었나」입니다. 「사용자가 그 기능을 보았나」가 아닙니다. 다만 그 기능이 사용자에게 닿았는지는 배포와 별개 사실로 남습니다.

패키지를 만들어 라벨을 붙이는 데까지

빌드한 결과를 패키지로 묶고 그 패키지에 라벨을 붙이는 데까지 한 것도 배포인가. 아닙니다. 거기까지는 릴리스입니다.

Google SRE Book 은 릴리스 엔지니어링을 소프트웨어의 빌드와 전달로 간결히 기술할 수 있다고 적습니다. 그리고 그 장 안에서 빌드·브랜치·테스트·패키징과 배포를 각각 다른 절로 나눕니다. 패키징 절은 패키지에 dev·canary·production 같은 라벨을 붙여 릴리스 과정 안에서의 위치를 표시한다고 적습니다. 기존 라벨을 새 패키지에 붙이면 그 라벨이 옛 패키지에서 새 패키지로 자동으로 옮겨 갑니다. 라벨이 옮겨 갔다고 해서 지금 도는 것이 바뀌지는 않습니다.

배포 절은 그 뒤에 따로 있습니다. Google 이 만든 릴리스 시스템 Rapid 는 단순한 배포를 직접 구동하는 데 흔히 쓰입니다. 설계도 파일에 적힌 배포 정의를 근거로 새로 빌드된 패키지를 쓰도록 실행 중인 잡을 갱신합니다. 더 복잡한 배포에는 SRE 가 만든 범용 롤아웃 자동화 프레임워크 Sisyphus 를 씁니다. 롤아웃은 하나 이상의 개별 작업으로 이루어진 논리적 작업 단위입니다. 같은 문서는 목표가 배포 프로세스를 그 서비스의 위험 프로필에 맞추는 것이라고 적습니다. 개발이나 사전 프로덕션 환경에서는 매시간 빌드할 수도 있습니다. 테스트가 모두 통과하면 릴리스를 자동으로 밀어 넣을 수도 있습니다. 사용자가 많이 쓰는 서비스에서는 클러스터 하나에서 시작할 수도 있습니다. 그 뒤로 모든 클러스터가 갱신될 때까지 지수적으로 넓혀 갑니다. 민감한 인프라에서는 여러 날에 걸쳐 롤아웃을 늘려 갈 수도 있습니다. 지리적으로 다른 지역의 인스턴스에 번갈아 적용합니다.

가르는 선은 그래서 이렇습니다. 옮길 수 있는 물건을 만들어 표시해 두는 데까지가 릴리스입니다. 실제로 도는 것을 그 물건으로 바꾸는 데서부터가 배포입니다.

예시

Kubernetes 디플로이먼트

Kubernetes 공식 문서는 디플로이먼트를 애플리케이션 워크로드를 돌리는 파드 묶음을 관리하는 것이라고 적습니다. 대개 상태를 유지하지 않는 워크로드입니다. 원하는 상태를 적어 두면 디플로이먼트 컨트롤러가 실제 상태를 그 상태로 통제된 속도로 바꿉니다.

.spec.strategy.type 이 RollingUpdate 이면 파드를 롤링 업데이트 방식으로 갱신합니다. 옛 레플리카셋을 점진적으로 줄입니다. 새 레플리카셋을 늘립니다. 진행을 제어하는 값이 둘입니다.

필드 무엇을 정하나 기본값
.spec.strategy.rollingUpdate.maxUnavailable 갱신 도중 사용할 수 없는 상태가 될 수 있는 파드의 최대 개수 25%
.spec.strategy.rollingUpdate.maxSurge 원하는 파드 수를 넘어 만들어질 수 있는 파드의 최대 개수 25%

두 값 모두 절대 수로도 원하는 파드 수의 백분율로도 적을 수 있습니다. 절대 수는 백분율에서 계산합니다. maxUnavailable 은 내림합니다. maxSurge 는 올립니다. maxSurge 가 0 이면 maxUnavailable 은 0 일 수 없습니다. 반대도 같습니다. 공식 문서의 예시는 파드를 3개 둡니다. 갱신 도중 사용할 수 없는 파드는 1개까지 허용합니다.

YAML
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1

되돌리기도 같은 자리에 있습니다. 문서는 디플로이먼트가 안정적이지 않을 때, 예를 들어 크래시 루프에 빠졌을 때 롤백하고 싶을 수 있다고 적습니다. 기본적으로 롤아웃 이력 전체가 시스템에 보관됩니다. 그래서 언제든 롤백할 수 있습니다. 리비전 이력 제한을 고쳐 그 동작을 바꿀 수 있습니다. 롤백 한 번마다 디플로이먼트의 리비전이 갱신됩니다.

Apple 단계별 배포

App Store Connect 도움말은 이 옵션을 고르면 앱 갱신이 7일에 걸쳐 점진적으로 배포된다고 적습니다. 자동 업데이트를 켠 대상 기기 사용자 가운데 무작위 표본이 갱신을 받습니다. 자신이 단계별 배포에 참여하고 있다는 알림은 없습니다.

단계별 배포 날짜 사용자 비율
1 1%
2 2%
3 5%
4 10%
5 20%
6 50%
7 100%

단계별 배포 중에는 최대 30일까지 배포를 일시정지할 수 있습니다. 정지 횟수에는 제한이 없습니다. 앱을 판매 중단하면 단계별 배포가 멈춥니다. 그 버전에는 다시 쓸 수 없습니다. Apple Developer Program 멤버십이 만료되는 경우도 여기 들어갑니다.

Google Play 단계적 출시

Play Console 도움말은 단계적 출시로 프로덕션 트랙과 테스트 트랙에 앱 갱신을 낼 수 있다고 적습니다. 갱신은 사용자 가운데 일정 비율에게만 닿습니다. 그 비율은 시간을 두고 올릴 수 있습니다. 단계적 출시는 앱 갱신에만 쓸 수 있습니다. 앱을 처음 게시할 때는 쓸 수 없습니다.

신규 사용자와 기존 사용자 모두 단계적 출시의 갱신을 받을 자격이 있습니다. 릴리스 출시마다 무작위로 뽑힙니다. 비율에 든 사용자에게 갱신이 열립니다. 다만 그 집단 전체가 갱신을 받기까지는 시간이 걸릴 수 있습니다. 사용자는 단계적 출시 버전을 받았다는 알림을 받지 않습니다.

문제를 발견하면 단계적 출시를 중단할 수 있습니다. 그 문제를 겪는 사용자 수를 최소화하는 데 도움이 됩니다. 중단하면 추가 사용자는 그 버전을 받지 않습니다. 이미 그 버전을 받은 사용자는 그 버전에 남습니다.

Debian 패키지 유지관리 스크립트

Debian Policy Manual 6장은 패키지의 일부로 스크립트를 함께 넣을 수 있다고 적습니다. 패키지 관리 시스템이 패키지를 설치하거나 업그레이드하거나 제거할 때 그 스크립트를 대신 실행합니다. 스크립트는 preinst·postinst·prerm·postrm 네 개의 패키지 메타데이터 파일입니다. 대체로 preinst 는 특정 판의 패키지가 언팩되기 전에 불립니다. postinst 는 그 뒤에 불립니다. prerm 은 특정 판이 제거되기 전에 불립니다. postrm 은 그 뒤에 불립니다.

같은 일도 어떤 상황인지가 호출 인자로 갈립니다.

new-preinst install
new-preinst install old-version new-version
new-preinst upgrade old-version new-version

postinst configure most-recently-configured-version

관련 항목

밀어 올리는 전략

롤링 업데이트 · 블루-그린 배포 · 카나리 배포 · 트래픽 전환 · 롤아웃 · 단계적 출시 · 단계별 배포

문제가 생겼을 때 되돌리는 방법

기능 스위치 · 기능 스위치 변형 · 롤백 · 리비전 이력

옮겨지는 산출물

빌드 산출물 · 패키지 · 컨테이너 이미지

배포로 다시 뜨는 실행 단위

프로세스 · 파드 · 레플리카셋

설치와 구성을 다루는 방식

패키지 관리 시스템 · 유지관리 스크립트 · 불변 인프라 · 코드형 인프라

배포 앞에 있는 활동

개발 · 버전 관리 · 커밋에서 배포까지 · 릴리스 엔지니어링

자동화하는 실천

지속적 통합 · 지속적 전달 · 지속적 배포 · 배포 자동화 · 파이프라인 · 구성 관리 · 데이터베이스 변경 관리

배포 뒤 상태를 확인하는 도구

상태 점검 · 로드 밸런서 · 모니터링과 관측성

잘못 관리하면 생기는 문제

구성 드리프트 · 스노플레이크 서버 · 배포 중 스키마 불일치 · 롤백 불가 마이그레이션 · 부분 배포

재는 지표

배포 빈도 · 변경 리드 타임 · 배포 실패 복구 시간 · 변경 실패율 · 배포 재작업률

구현하거나 정의한 주체

Kubernetes · 디플로이먼트 · App Store Connect · Play Console · Debian · AWS · DORA · SRE · Google

다른 이름: deployment · software deployment · deploy · 소프트웨어 배포