🟣 소프트웨어를 만드는 것보다 어려운 일
프로그램을 짜는 일보다 그것을 안정적으로 자주 배포하는 일이 더 어렵다는 걸, 서버 쪽을 들여다보고 나서 알았다. 전통적인 방식에서 배포는 하나의 큰 사건이었다. 개발팀이 몇 달을 모아 기능을 만들고, 어느 날 운영팀에 넘기면, 운영팀이 밤을 새워 서버에 올렸다. 문제가 생기면 개발과 운영이 서로를 탓했다. 배포가 무서우니 자주 하지 않았고, 자주 하지 않으니 한 번에 바뀌는 양이 커서 더 무서웠다.
클라우드가 이 그림을 바꿀 여지를 열었다. 서버를 사서 랙에 꽂는 대신, 필요하면 몇 분 만에 수십 대를 켜고 트래픽이 빠지면 다시 끄는 일이 가능해졌다. 문제는 클라우드가 탄력적이어도 그 위에 올리는 애플리케이션과 배포 방식이 예전 그대로면 그 탄력을 쓰지 못한다는 데 있다. 서버 한 대에 통째로 설치하고 손으로 재시작하는 앱은, 열 대로 늘려도 열 배로 손이 갈 뿐이다.
클라우드 네이티브는 이 간극을 메우려는 접근이다. 클라우드의 탄력성을 처음부터 전제하고 애플리케이션을 설계하고, 배포하고, 운영한다. 재단인 CNCF는 이를 확장 가능하고, 회복력 있고, 자주 바꿀 수 있는 시스템을 만드는 방식이라고 정의한다. 이 정의를 떠받치는 것이 데브옵스, 컨테이너, 마이크로서비스, CI/CD라는 네 개의 기둥이다.
🟣 첫 번째 기둥: 데브옵스
가장 먼저 무너뜨려야 했던 것은 기술이 아니라 개발과 운영 사이의 벽이었다. "우리는 코드를 만들었으니 이제 돌리는 건 너희 일"이라는 태도가 배포를 느리게 만든 근본 원인이었다. 개발자는 운영 환경을 모르고, 운영자는 코드를 모르니, 장애가 나면 원인을 찾는 데만 며칠이 걸렸다.
데브옵스는 특정 도구가 아니라 개발과 운영을 하나의 책임으로 묶는 문화다. 코드를 짠 사람이 그 코드가 프로덕션에서 어떻게 도는지까지 본다. 배포를 자동화해서 사람의 실수를 줄이고, 무언가 잘못되면 빨리 발견해 빨리 되돌린다. 도구가 문화를 따라오는 것이지 그 반대가 아니라는 점이 중요하다. 아무리 좋은 배포 도구를 깔아도 조직이 여전히 벽으로 나뉘어 있으면 배포는 느리다. 나머지 세 기둥은 이 문화를 실제로 굴러가게 만드는 기술적 장치에 가깝다.
🟣 두 번째 기둥: 컨테이너
배포를 자주 하려면 "내 컴퓨터에선 되는데 서버에선 안 된다"는 고질적인 문제부터 없애야 했다. 개발자의 노트북, 테스트 서버, 프로덕션 서버는 운영체제 버전도, 설치된 라이브러리도 미묘하게 다르다. 그 차이가 배포 때마다 예측 불가능한 사고를 만든다.
컨테이너는 애플리케이션과 그것이 필요로 하는 실행 환경을 하나의 이미지로 함께 묶는다. 코드뿐 아니라 런타임, 라이브러리, 설정까지 한 덩어리로 포장하니, 이 이미지는 어느 기계에 올려도 똑같이 동작한다. 배포 단위가 "코드"에서 "실행까지 보장된 이미지"로 바뀌는 셈이다. 이 컨테이너가 어떻게 무겁지 않게 격리를 해내는지는 다음 장에서 커널 수준까지 내려가 본다.
🟣 세 번째 기둥: 마이크로서비스
애플리케이션이 커질수록 하나의 덩어리로 두는 것이 부담이 됐다. 결제 로직 한 줄을 고쳤을 뿐인데 주문, 재고, 알림까지 전부 다시 배포해야 한다면, 작은 수정조차 위험해진다. 트래픽이 몰리는 일부 기능만 늘리고 싶어도 앱 전체를 복제해야 한다.
마이크로서비스는 하나의 큰 애플리케이션을 독립적으로 배포하고 확장할 수 있는 작은 서비스들로 쪼갠다. 주문은 주문대로, 결제는 결제대로 각자의 배포 주기를 갖는다. 대신 하나였던 것이 여럿이 되면서 서비스 사이의 통신과 데이터 정합성이라는 새로운 비용이 생긴다. 이 트레이드오프와, 쪼개진 서비스들을 실제로 굴리는 쿠버네티스는 3장에서 다룬다.
🟣 네 번째 기둥: CI/CD
서비스를 잘게 쪼개고 각각을 컨테이너로 만들면, 이제 배포할 단위가 폭발적으로 늘어난다. 이걸 사람이 손으로 빌드하고 테스트하고 서버에 올리는 것은 느릴 뿐 아니라 반드시 실수를 부른다. 자동화가 선택이 아니라 전제 조건이 된다.
CI/CD는 코드 변경이 들어올 때마다 자동으로 빌드하고, 테스트를 돌리고, 통과하면 배포까지 잇는 파이프라인이다. 사람은 코드를 올리는 것까지만 하고, 그 뒤의 반복 작업은 기계가 맡는다. 덕분에 하루에도 여러 번 안전하게 배포할 수 있다. 앞의 세 기둥이 만들어낸 복잡함을 실제로 감당 가능하게 만드는 것이 이 마지막 기둥이고, 자세한 파이프라인은 4장에서 본다.
🟣 네 기둥은 따로 서 있지 않다
네 기둥을 하나씩 보면 별개의 기술처럼 보이지만, 실제로는 서로가 서로를 부른다. 마이크로서비스로 쪼개니 배포 단위가 늘고, 그 단위를 어디서나 똑같이 실행하려고 컨테이너로 감싸고, 컨테이너가 많아지니 쿠버네티스가 대신 배치하고, 그 전 과정을 CI/CD가 자동으로 잇는다. 그리고 이 모든 것을 한 팀이 책임지고 돌리는 방식이 데브옵스다.
이 사슬을 이론적으로 정리해 둔 것이 12 팩터 앱이다. 설정을 코드에서 분리해 환경 변수로 두기, 애플리케이션을 상태 없이 만들어 아무 인스턴스나 죽고 살아도 되게 하기, 로그를 파일이 아니라 표준 출력 스트림으로 흘려보내기 같은 원칙들이다. 처음 봤을 때는 잔소리 같았는데, 네 기둥을 이해하고 나니 전부 "클라우드에서 마음대로 늘리고 줄이려면 애플리케이션이 지켜야 할 조건"이라는 하나의 목적에서 나온 것이었다.
🟣 정리
- 클라우드 네이티브는 클라우드의 탄력성을 전제로 애플리케이션을 설계하고 배포하는 방식이다. 목표는 자주, 안정적으로, 규모 있게 배포하는 것 하나다.
- 데브옵스는 도구가 아니라 개발과 운영의 벽을 없애 배포를 한 팀의 책임으로 묶는 문화다.
- 컨테이너는 실행 환경까지 함께 묶어 "내 컴퓨터에선 되는데" 문제를 없앤다. 마이크로서비스는 배포 단위를 잘게 나눠 부분 배포와 부분 확장을 가능하게 한다.
- CI/CD는 앞의 기둥들이 만든 배포 단위의 폭증을 자동화로 감당한다. 네 기둥은 필요의 사슬로 서로 맞물려 있다.
- 12 팩터 앱은 이 사슬을 애플리케이션이 지켜야 할 원칙으로 정리한 것이다.
실무와 면접에서 클라우드 네이티브 질문은 보통 도구 이름을 아느냐가 아니라 "왜 이렇게까지 하느냐"를 묻는다. 도커와 쿠버네티스를 각각 설명하는 것보다, 네 기둥이 하나의 배포 목표를 향해 어떻게 맞물리는지를 사슬로 말할 수 있으면 이해의 깊이가 드러난다. 특히 마이크로서비스의 이점만 말하고 그 대가를 말하지 못하면 얕게 읽힌다.
다음 장에서는 네 기둥 중 가장 밑바탕이 되는 컨테이너를 파고든다. 컨테이너가 가상 머신과 무엇이 다른지, 그리고 그 가벼운 격리가 실은 리눅스 커널의 어떤 기능으로 만들어지는지를 커널 수준까지 내려가 본다.