웹 인프라

지속적 배포(CD), 통과해야만 나가는 문

검증한 파일과 배포한 파일이 같으려면 무엇이 필요할까요? 자동 검사와 산출물 승격, 배포를 멈추는 것과 되돌리는 것의 차이를 알아봐요.

이 글의 목차손으로 올리던 시절이 남긴 문제5
  1. 손으로 올리던 시절이 남긴 문제
  2. 산출물은 한 번만 만든다
  3. 도구를 누가 갖느냐는 문제
  4. 멈추는 것과 되돌리는 것은 다르다
  5. 저는 이 문을 어디에 두었나

인쇄소는 원고를 기계에 걸기 전에 교정지를 한 장 뽑아요. 잉크가 돌기 시작하면 되돌릴 수 없기 때문이에요. 교정지를 보는 사람은 인쇄를 늦추려고 있는 것이 아니라, 잘못된 것이 수천 부로 찍히지 않게 하려고 그 자리에 있어요.

만든 것을 사람들이 실제로 쓰는 곳에 옮기는 일을 배포(deploy)라고 불러요. 배포 직전의 교정지 자리를 요즘은 기계가 지키는데, 그 장치를 파이프라인이라고 불러요. 파이프라인의 값어치는 흔히 속도로 이야기되지만 실무에서 실제로 중요한 것은 다른 세 가지예요. 같은 입력이 같은 결과를 내는가, 잘못된 것이 나가지 않게 막는가, 나가 버렸을 때 되돌릴 수 있는가.

검사 결과에 따른 배포 분기 검사 실패는 배포 경계에서 새 산출물을 멈추므로 운영 서비스는 직전 상태를 유지한다. 개념 도해 검사 결과에 따른 배포 분기 산출물 승격 경로 ① 변경 올림 ② 산출물 빌드 ③ 검사 ④ 배포 동일 산출물 통과 실패 · 중단 검사 결과별 운영 반영 배포 경계 검사 실패 직전 상태 유지 검사 통과 새 산출물 반영 변경 운영 · 파이프라인 진행 검사 실패는 배포 경계에서 새 산출물을 멈추므로 운영 서비스는 직전 상태를 유지한다. SOSHIN · DEV NOTES
검사를 통과하지 못하면 다음 칸으로 넘어가지 않아요. 멈추는 것이 이 구조의 목적이에요.

손으로 올리던 시절이 남긴 문제

예전 배포는 말 그대로 파일을 옮기는 일이었어요. 내 컴퓨터에서 만든 결과물을 서버에 복사해 넣었고, 잘 돌아갈 때는 문제가 없었지만 어긋나면 원인을 찾기 어려웠어요. 내 컴퓨터에서는 되는데 서버에서는 안 된다는 말이 이 시절의 관용구였어요.

더 큰 문제는 사람이 여럿일 때 나왔어요. 각자 오래 따로 작업하다 한꺼번에 합치면 충돌이 몰려 나오고, 미룰수록 나중에 치를 비용이 커졌어요. Martin Fowler는 2001년에 처음 쓰고 이후 두 번 다시 쓴 글에서 해법을 간단히 정리했어요. 합치는 일을 미루지 말고 자주 하고, 합칠 때마다 기계가 자동으로 검사하게 하라는 것이에요. 이것이 지속적 통합(Continuous Integration), CI예요. 여기서 한 걸음 더 나가 검사를 통과한 결과를 사람이 버튼을 누르지 않아도 내보내면 지속적 배포(Continuous Deployment)가 돼요.

산출물은 한 번만 만든다

개발용 결과물을 확인한 뒤 운영용으로 다시 빌드하면 무엇이 달라질까요? 소스가 같아도 의존성이나 빌드 도구, 환경별 설정 때문에 다른 파일이 나올 수 있어요. 꼭 환경마다 빌드해야 한다면 그 차이를 포함해 검사해야 해요. 같은 결과물을 옮길 수 있는 구조라면 이미 확인한 파일을 그대로 배포하는 편이 비교할 변수를 줄여 줘요.

그래서 산출물은 한 번만 만들고 그것을 환경 사이로 옮겨요. 이 옮김을 승격이라고 불러요. 개발에서 확인한 그 파일 묶음이 그대로 운영으로 가요. 환경마다 달라지는 값은 산출물 안이 아니라 실행할 때 주입해요. 같은 입력이 같은 결과를 내야 한다는 재현성 요구가 이 구조를 강제해요. 설치가 매번 같게 재현되는지의 문제는 어제 되던 설치가 오늘 깨진 이유에서 따로 다뤘어요.

도구를 누가 갖느냐는 문제

이 방식이 퍼지려면 자동으로 검사해 주는 도구가 필요했어요. 그 자리를 오래 지킨 것이 Hudson이었고, 여기서 소프트웨어 역사에 남을 이름 다툼이 벌어져요.

프로젝트를 만든 사람과 참여자들은 운영 방식을 두고 상표권을 가진 회사와 이견을 좁히지 못했어요. 2011년 1월 프로젝트의 앞날을 묻는 글이 올라왔고, 이름을 바꾸자는 안건이 투표에 부쳐졌어요. 1월 29일 집계된 결과는 찬성 214표, 반대 14표였어요. 새 이름은 Jenkins가 됐어요. 기능이 아니라 프로젝트를 누가 이끄느냐를 두고 갈라진 사건이었고, 이후 검사와 배포 도구는 대체로 저장소 가까이에서 함께 관리되는 방향으로 옮겨 갔어요.

멈추는 것과 되돌리는 것은 다르다

실행 방식에 따른 배포 단계 보존 사람의 기억에 맡긴 절차는 급한 상황에서 짧아질 수 있지만, 파이프라인은 정의된 단계를 같은 순서로 반복한다. 개념 도해 실행 방식에 따른 배포 단계 보존 배포 단계 실행 경로 사람 · 급함 기억 의존 · 단계 단축 ① 변경 ② 빌드 ③ 검사 ④ 배포 파이프라인 ① 변경 ② 빌드 ③ 검사 ④ 배포 실행 방식별 단계 보존 정의된 순서 끝 기억 의존 검사 누락 파이프라인 전 단계 실행 누락 전 단계 · 절차 완전성 사람의 기억에 맡긴 절차는 급한 상황에서 짧아질 수 있지만, 파이프라인은 정의된 단계를 같은 순서로 반복한다. SOSHIN · DEV NOTES
사람이 지키던 순서를 기계에 옮기면, 바쁜 날에도 순서가 줄어들지 않아요.

검사에서 걸려 배포가 멈추면 살아 있는 서비스는 어제 상태 그대로예요. 아무 일도 일어나지 않았으므로 복구할 것도 없어요. 문제는 검사를 통과했는데 실제 환경에서 문제가 드러나는 경우예요. 이때 필요한 것은 게이트가 아니라 되돌리기이고, 되돌리기가 빠르려면 직전 산출물이 그대로 남아 있어야 해요. 승격 구조가 여기서 두 번째로 값을 해요.

검사의 종류무엇을 막나걸리면 어떻게 되나
빌드와 타입 검사형태가 깨진 코드산출물이 만들어지지 않는다
규칙 검사지키기로 한 약속의 위반산출물은 있어도 나가지 않는다
배포 후 상태 확인실제 환경에서만 드러나는 문제직전 산출물로 되돌린다

저는 이 문을 어디에 두었나

이 블로그를 만들면서 조금 유별나게 정한 것이 있어요. 코드뿐 아니라 글에도 같은 문을 달았어요.

이 블로그의 글은 코드 조각이나 설치 명령, 절차 목록을 싣지 않기로 했어요. 그런데 이런 규칙은 사람의 기억에 맡기면 반드시 무너져요. 급하게 쓴 날, 설명이 잘 안 풀리는 날에 가장 먼저 손이 가는 것이 코드 한 줄이기 때문이에요. 그래서 규칙을 배포 직전의 검사로 옮겼어요. 본문에 코드 블록이 들어가거나 표가 두 개가 되면 배포가 그 자리에서 멈춰요.

최근에 검사가 하나 늘었어요. 강조 표시가 렌더링되지 않고 별표째 본문에 남은 글을 뒤늦게 발견했는데, 한국어에서 조사가 붙을 때만 생기는 조건이라 눈으로는 놓치기 쉬웠어요. 고치는 김에 같은 형태를 잡아내는 규칙을 검사에 추가했어요. 게이트는 처음부터 완성되는 것이 아니라 놓친 것을 발견할 때마다 한 줄씩 자라는 물건이었어요.

소신을 상징하는 까마귀 목판화 일러스트
작성자소신 · Soshin

웹과 서버를 만들고, 개발하며 배운 것들을 글로 남깁니다.

좌우로 움직여 보세요