Cloud Modernization 28
MSA와 컨테이너: 배포 단위의 진화
컨테이너와 VM이 모두 격리된 실행 환경처럼 보여서 왜 MSA와 함께 자주 언급되는지 헷갈린다.
근거 · 교안 p126-p132
1장: MSA, 독립성을 꿈꾸다
솔라의 태블릿 화면 한구석에, 며칠째 지워지지 않는 메모가 떠 있었다.
컨테이너: 애플리케이션과 실행에 필요한 요소를 패키징한 실행 환경. Lightweight, Portable, Isolated, Scalable.
간결한 정의였지만, 솔라는 이 문장을 볼 때마다 미간을 찌푸렸다. 특히 ‘Isolated(격리된)’라는 단어에 자꾸만 시선이 걸렸다.
“언니, 나 MSA 공부하는데 이상한 데서 막혔어.”
거실 소파에서 책을 읽던 루나가 조용히 고개를 들었다. 솔라는 태블릿을 들고 루나 옆으로 다가와 앉으며 화면을 가리켰다.
“컨테이너의 특징 중 하나가 ‘격리된’ 환경이라는 거잖아. 그런데 이건 가상 머신(VM)도 마찬가지 아니야? VM도 각각 격리된 OS를 가지고 독립적으로 돌아가는데. 왜 다들 마이크로서비스 아키텍처, MSA만 나오면 컨테이너가 찰떡궁합이라고 하는 거지? VM으로도 서비스마다 독립된 환경을 만들 수 있는데.”
솔라의 목소리에는 ‘분명히 아는 개념인데 왜 연결이 안 되지?’ 하는 답답함이 묻어났다. VM도, 컨테이너도, 심지어 MSA의 기본 개념도 알고 있는데, 그들의 관계를 설명하는 핵심적인 고리가 빠진 느낌이었다.
루나는 솔라의 태블릿을 잠시 들여다보더니, 화면을 끄고 테이블 위에 내려놓았다.
“그 질문을 잠시 옆에 둬 보자. ‘컨테이너는 무엇인가’ 대신, ‘MSA는 무엇을 원하는가’에서 시작해 보면 어떨까?”
“MSA가 뭘 원하냐니? 그냥 큰 서비스를 잘게 나누는 거 아니었어?”
솔라의 반문에 루나는 희미하게 미소 지었다.
“상상해 보자. 우리가 아주 큰 온라인 서점을 운영하고 있어. 사용자 관리, 상품 검색, 주문, 결제, 배송 추적… 이 모든 기능이 거대한 애플리케이션 하나에 전부 들어있는 거야.”
“응, 그런 걸 모놀리식(Monolithic) 아키텍처라고 부르지.”
“맞아. 자, 그런데 연말 할인 시즌이 돼서 주문량이 평소의 100배로 폭주했어. 어떻게 해야 할까?”
솔라는 즉시 대답했다. “서버를 늘려야지. 똑같은 애플리케이션을 여러 서버에 복제해서 돌리면 되잖아.”
“그렇지. 그런데 이상하지 않아? 바쁜 건 ‘주문’ 기능뿐인데, 아무 상관 없는 ‘상품 검색’이나 ‘배송 추적’ 기능까지 통째로 복제해서 서버 자원을 쓰고 있어. 이건 좀 낭비 아닐까?”
“음… 듣고 보니 그러네.”
“더 큰 문제가 있어. 결제 시스템에 아주 사소한 버그가 하나 발견됐어. 딱 한 줄만 고치면 돼. 그런데 이 수정 사항을 반영하려면 어떻게 해야 할까?”
솔라의 얼굴에 아차 하는 표정이 스쳤다.
“전체 애플리케이션을 새로 빌드하고, 전체 기능에 대해 테스트하고, 한밤중에 서비스를 잠시 멈추고… 전체를 배포해야 하네. 결제 기능 딱 하나 고치자고 이 모든 걸 다 해야 한다니.”
“바로 그거야.” 루나가 말했다. “하나의 작은 변화가 애플리케이션 전체의 안정성을 위협하고, 개발부터 배포까지 모든 과정이 무거워지는 거지. 마치 한 팀이 맡은 업무 하나가 잘못되면 회사 전체가 멈추는 것과 비슷해.”
솔라는 고개를 끄덕였다. 거대한 단일 애플리케이션이 가진 문제점이 선명하게 그려졌다.
루나가 말을 이었다. “그래서 사람들이 생각한 거야. ‘애초에 따로 만들면 어떨까?’ 하고. 사용자 관리 서비스, 상품 검색 서비스, 주문 서비스, 결제 서비스… 각각이 마치 독립된 작은 회사처럼 움직이는 거지.”
“아! 그게 바로 마이크로서비스 아키텍처구나. 기능별로 서비스를 잘게 나누는 것.”
“단순히 나누는 것에서 그치지 않아. ‘독립적으로’ 움직인다는 게 핵심이야. 다시 온라인 서점으로 돌아가서, 주문량이 폭주하면 어떻게 될까?”
솔라의 눈이 반짝였다. 방금 전과는 다른 답이 튀어나왔다.
“‘주문 서비스’만 골라서 여러 개로 늘리면 돼! 다른 서비스는 그대로 두고.”
“결제 시스템 버그는?”
“그것도 ‘결제 서비스’만 수정해서, 그것만 다시 배포하면 끝! 다른 서비스 팀은 자기 일을 계속할 수 있고.”
“바로 그거야.”
솔라는 무릎을 탁 쳤다. “이제 알겠다! MSA는 단순히 코드를 분리하는 게 아니었어. 개발, 테스트, 배포, 확장에 이르는 애플리케이션의 ‘운영’ 단위를 완전히 독립시키는 거구나. 하나의 서비스 변경이 다른 서비스에 영향을 주지 않아야 하고, 각자 필요한 만큼만 자원을 사용하며 커지거나 작아질 수 있어야 하는 것. 그 ‘독립성’이 핵심이었네.”
마치 흐릿한 그림의 초점이 맞춰지는 기분이었다. 왜 MSA가 등장했는지, 무엇을 해결하려 하는지가 비로소 명확하게 이해됐다. 각 서비스가 자신만의 생명 주기를 가지고 독립적으로 태어나고, 바뀌고, 사라질 수 있어야 한다는 것.
그때, 솔라는 다시 원래의 질문으로 돌아왔다. 머릿속에 새로운 궁금증이 꼬리를 물었다.
“잠깐만… ‘독립적으로 배포하고 확장한다’는 건, 결국 그 작은 서비스 하나하나를 어딘가에 담아서 서버에 올려야 한다는 뜻이잖아. 그렇다면 그 서비스를 담는 ‘그릇’이 중요해지겠네.”
솔라는 다시 테이블 위의 태블릿을 집어 들었다.
“VM도 완벽하게 독립된 환경을 제공하잖아. 서비스 하나당 VM 하나씩 할당하면 독립성은 지킬 수 있는 거 아니야? 그런데 왜 굳이 컨테이너일까? 컨테이너가 가진 가벼움(Lightweight)이나 이식성(Portable) 같은 특징들이, MSA가 원하는 그 ‘독립적인 운영’에 VM보다 어떻게 더 유리하다는 거지?”
솔라의 질문은 처음과 비슷했지만, 완전히 다른 무게를 가지고 있었다. 이제 질문의 핵심은 ‘격리’라는 단어의 사전적 의미가 아니었다. MSA가 꿈꾸는 ‘완벽한 독립 운영’이라는 구체적인 목표 앞에서, 컨테이너와 VM이 어떻게 다르게 행동하는지에 대한 실질적인 질문으로 바뀌어 있었다.
2장: 컨테이너와 VM, ‘격리’ 너머의 차이
루나는 솔라의 질문에 대답하는 대신, 조용히 테이블 위에 새 노트를 펼치고 펜을 들었다. 그리고는 커다란 사각형 두 개를 나란히 그렸다. 왼쪽 사각형 안에는 또 다른 작은 사각형을 그리고, 그 안에 다시 ‘OS’라는 글자와 함께 더 작은 ‘App’ 상자를 그렸다. 왼쪽 그림의 이름은 ‘VM’이었다.
반면 오른쪽 사각형에는 아래쪽에 ‘Host OS 커널’이라는 선을 긋고, 그 위에 곧바로 ‘App’이라고 적힌 작은 상자들을 여러 개 올렸다. 오른쪽 그림의 이름은 ‘컨테이너’였다. 별다른 설명 없이, 두 개의 구조도만이 조용히 솔라의 시선을 기다리고 있었다.
솔라는 거실로 나와 테이블에 놓인 노트를 발견했다. 어제 자신이 던졌던 질문의 실마리가 그 안에 있음을 직감했다.
“이 그림… 어제 내가 했던 질문에 대한 답이야?”
솔라는 그림을 찬찬히 뜯어보았다. 왼쪽의 VM은 마치 집 속의 집처럼, 자신만의 완결된 구조를 가지고 있었다. 오른쪽의 컨테이너는 하나의 기반 위에 여러 개의 앱들이 가볍게 올라탄 모양이었다.
“VM은 안에 OS를 통째로 또 가지고 있고, 컨테이너는 OS 없이 애플리케이션만 쏙 들어있다는 거네. 그래서 컨테이너가 ‘가볍다(Lightweight)’고 하는 거구나.”
솔라는 고개를 끄덕였지만, 완전히 개운한 표정은 아니었다.
“알겠어. 구조가 달라서 무게가 다른 건 이해돼. 하지만 여전히 이상해. VM은 저렇게 OS까지 통째로 자기만의 방을 가지니까 훨씬 더 완벽하게 ‘격리’되는 거잖아. 그런데 MSA에서는 왜 그 완벽한 격리를 포기하고 가벼움을 선택한 거지? 단순히 가볍다는 이유만으로?”
루나가 조용히 입을 열었다.
“우리가 해외여행을 간다고 상상해 보자. 하나는 모든 살림살이를 다 실은 캠핑카를 통째로 배에 실어 보내는 방식이고, 다른 하나는 현지 숙소를 예약하고 꼭 필요한 짐만 배낭에 챙겨가는 방식이야. 둘 중 어떤 게 VM이고, 어떤 게 컨테이너 같아?”
“음… 당연히 캠핑카가 VM, 배낭이 컨테이너겠지.” 솔라가 즉시 대답했다.
“맞아. VM, 즉 캠핑카 방식은 어떨까? 목적지에 도착해서 문만 열면, 우리에게 익숙한 침대, 주방, 화장실이 모두 갖춰진 완벽한 ‘우리 집’ 환경이야. 외부와 완전히 분리되어 있지. 아주 안전하고 독립적이야.”
루나의 말에 솔라가 끼어들었다. “하지만 끔찍하게 무겁고, 느리고, 비용도 엄청나게 들겠지. 캠핑카를 나라 밖으로 옮기는 건 보통 일이 아니니까. 하룻밤 자려고 캠핑카 전체를 옮기는 건 완전한 낭비잖아.”
“바로 그거야.” 루나가 배낭 그림을 가리켰다. “컨테이너, 즉 배낭 방식은 어때? 우리는 현지 숙소의 침대와 화장실 같은 기본 시설은 그냥 빌려 쓰기로 약속하는 거야. 대신 우리 옷, 세면도구, 노트북처럼 우리에게만 꼭 필요한 개인 짐만 챙겨가는 거지.”
순간 솔라의 머릿속에서 두 그림과 비유가 하나로 합쳐졌다.
“아! 캠핑카가 ‘게스트 OS를 포함한 가상 머신’이고, 배낭이 ‘애플리케이션과 그에 필요한 라이브러리만 담은 컨테이너’구나! 그리고 현지 숙소의 기본 시설이 바로 호스트 컴퓨터의 OS, 특히 그 핵심인 ‘커널’을 공유한다는 뜻이었어!”
솔라는 노트를 자기 쪽으로 끌어당겼다. VM 그림의 ‘OS’ 부분과 컨테이너 그림의 ‘Host OS 커널’ 부분을 손가락으로 번갈아 가리켰다.
“그렇구나. 둘 다 ‘격리’는 맞지만, 격리의 방식과 무게가 전혀 달랐던 거야. VM은 하드웨어부터 OS까지 통째로 가상화해서 ‘나라’ 자체를 새로 만드는 수준의 격리라면, 컨테이너는 이미 있는 나라의 법(커널)은 따르되, ‘독립된 집(프로세스)’을 얻는 수준의 격리였네.”
이제 ‘가볍다(Lightweight)’는 단어는 더 이상 추상적인 수식어가 아니었다. 솔라에게 그것은 ‘게스트 OS의 부재’라는 구체적인 구조적 특징으로 보였다.
“그러면 당연히 컨테이너가 훨씬 빠르겠네. 캠핑카는 시동 걸고, 예열하고, 출발하는 데 한참 걸리지만, 배낭은 그냥 메고 나가면 끝이니까. VM은 새로운 OS를 부팅해야 해서 몇 분씩 걸리지만, 컨테이너는 그냥 호스트 OS 위에서 프로세스 하나 띄우는 거니까 몇 초면 충분하겠어.”
가볍고, 빠르다. 이제야 그 특성들이 피부에 와 닿았다. VM과 컨테이너는 단순히 성능 차이가 아니라, 태생부터 다른 존재였다. 하나는 모든 것을 갖춘 무거운 독립체, 다른 하나는 필요한 것만 챙겨 공유된 기반 위에서 빠르게 움직이는 날렵한 실행 단위.
솔라는 만족스러운 표정으로 그림을 바라보다가, 문득 새로운 질문에 부딪혔다.
“좋아. 컨테이너가 캠핑카가 아니라 배낭처럼 가볍고 빠르다는 건 완벽하게 알겠어. 그런데… 이게 지난번에 이야기했던 MSA의 ‘독립적인 배포와 확장’이랑 정확히 어떻게 연결되는 거지?”
솔라의 시선이 다시 MSA의 개념으로 향했다.
“수백 개의 서비스가 각자의 배낭을 메고 필요할 때마다 나타나고 사라지는 모습을 상상해봤어. 확실히 캠핑카 수백 대를 움직이는 것보다는 훨씬 효율적이겠지. 하지만 단지 ‘빠르니까 좋다’고 하기엔 뭔가 부족한 기분이야. 이 가벼움과 빠른 속도가, 각 서비스가 서로에게 영향을 주지 않고 독립적으로 커지고 작아지는 그 목표에 구체적으로 어떤 결정적인 이점을 주는 걸까?”
3장: MSA의 친구, 컨테이너
솔라의 질문이 남긴 공백을 채운 것은 루나의 조용한 움직임이었다. 다음 날 아침, 테이블 위에는 전날의 노트 대신, 큼직한 모형판 두 개가 놓여 있었다. 왼쪽 판에는 ‘서버 A (VM 방식)’, 오른쪽 판에는 ‘서버 B (컨테이너 방식)’라고 적혀 있었다. 그리고 그 옆에는 크기와 무게가 제각각인 나무 블록 몇 개와, 색색의 작은 포스트잇 한 묶음이 가지런히 준비되어 있었다.
솔라는 잠에서 막 깨 부스스한 모습으로 거실로 나왔다가, 테이블 위의 새로운 판을 발견했다. 어제 자신이 던졌던 마지막 질문—컨테이너의 가벼움과 빠른 속도가 MSA의 독립적 배포와 확장에 정확히 어떻게 결정적인 이점을 주는지—에 대한 다음 단계의 실험임을 직감했다.
“이건 또 뭐야? 장난감 놀이?” 솔라가 피식 웃으며 물었다.
루나는 나무 블록 하나를 집어 들며 말했다. “온라인 서점의 ‘주문 서비스’라고 생각해 봐. VM 위에 올라간 서비스지. 캠핑카 한 대야. 제법 묵직하지?”
루나는 묵직한 나무 블록을 ‘서버 A’ 판 위에 ‘쿵’ 소리가 나게 내려놓았다. 그다음엔 작은 포스트잇 한 장을 떼어 ‘주문 서비스’라고 적고는, ‘서버 B’ 판 위에 가볍게 붙였다. “이건 컨테이너에 담긴 같은 서비스. 배낭 하나.”
“무게 차이는 이제 확실히 알겠어. 그래서, 이게 ‘독립적인 운영’과 무슨 상관인데?” 솔라는 여전히 핵심을 꿰뚫고 싶어 했다.
루나는 시나리오를 제시했다. “블랙프라이데이 자정, 특가 할인 이벤트가 시작됐어. 갑자기 ‘주문 서비스’에 평소의 100배 트래픽이 몰려. 서버가 다운되기 일보 직전이야. 자, 솔라. 어서 ‘주문 서비스’를 9개 더 늘려서 총 10개로 만들어 봐. 서버를 구해야 해!”
솔라는 즉시 상황에 몰입했다. 먼저 ‘서버 A (VM 방식)’ 판으로 향했다. 나무 블록 9개를 추가로 올려놓아야 했다. 그녀는 블록을 하나씩 집어 들고 ‘쿵… 쿵…’ 소리를 내며 판 위에 조심스럽게 올렸다. 블록은 무거웠고 자리를 많이 차지했다. 몇 개 올리지 않았는데도 판이 꽉 차는 느낌이었다.
“으… 이거 시간이 너무 걸리는데. VM 하나 부팅하는 데 몇 분씩 걸린다고 생각하면… 이미 서버는 터졌겠네. 게다가 이 블록들, 너무 무거워서 서버 한 대에 몇 개 올리지도 못하겠다.”
“바로 그때, ‘쿠폰 서비스’에 치명적인 버그가 발견됐다는 긴급 알림이 떴어. 당장 서비스를 내려서 새 버전으로 교체해야 해!” 루나가 다급한 목소리로 외쳤다.
솔라는 이미 빽빽하게 들어찬 나무 블록들 사이에서 ‘쿠폰 서비스’ 블록을 빼내려 애썼다. 다른 블록들을 건드리지 않고 하나만 쏙 빼내는 건 쉽지 않았다. 겨우 빼내고 새 블록으로 교체하는 동안, 시간은 하염없이 흘렀다.
“알겠다… VM 방식으로는, 서비스 하나를 추가하거나 교체하는 작업 자체가 너무 ‘비싼’ 작업이구나. 시간도 오래 걸리고, 서버 자원도 엄청나게 차지하고. 이러니 서비스가 수십, 수백 개로 늘어나는 MSA 환경에서는 감당이 안 되겠어.”
솔라는 한숨을 쉬며 ‘서버 B (컨테이너 방식)’ 판으로 시선을 돌렸다.
“자, 이제 배낭을 멘 여행자들이야. 다시 해봐.”
루나의 말에 솔라는 포스트잇 묶음을 집어 들었다. ‘주문 서비스’라고 적힌 포스트잇 9장을 순식간에 떼어내 ‘착, 착, 착’ 하고 판 위에 붙였다. 1초도 걸리지 않았다. 판은 여전히 널찍했다.
“그리고… ‘쿠폰 서비스’ 버그!”
솔라는 망설임 없이 ‘쿠폰 서비스’ 포스트잇을 떼어내 휴지통에 버리고, 새 포스트잇에 다시 써서 원래 자리에 붙였다. 모든 과정이 눈 깜짝할 사이에 끝났다.
그 순간, 모든 조각이 맞춰졌다.
“이거였구나!” 솔라는 무릎을 탁 쳤다. “단순히 ‘빠르다’는 게 아니었어. 컨테이너의 그 ‘가벼움’과 ‘빠른 속도’가 MSA가 원하는 두 가지 핵심 목표를 직접적으로 가능하게 만드는 거였어.”
솔라는 두 개의 서버 판을 번갈아 가리키며 자신의 깨달음을 쏟아냈다.
“첫째, 신속한 확장(Scalable). 주문량이 폭주할 때 VM은 캠핑카를 새로 가져오는 것처럼 느려서 대응이 불가능하지만, 컨테이너는 그냥 배낭 멘 사람 몇 명 더 부르는 것처럼 순식간에 서비스 수를 늘릴 수 있어. 트래픽 변화에 실시간으로 반응할 수 있는 능력, 이게 MSA가 원하는 확장성이야.”
“둘째, 진정한 독립 배포(Independent Deployment). VM은 너무 무겁고 비싸니까, 작은 서비스 하나마다 VM 하나를 할당하는 건 낭비야. 결국 몇몇 서비스를 한 VM에 같이 넣게 되겠지. 그럼 다시 모놀리식 시절의 문제로 돌아가는 거잖아. 하지만 컨테이너는 포스트잇처럼 가볍고 자원을 적게 쓰니까, 서버 한 대에 수백 개를 띄울 수 있어. 아주 작은 기능 하나까지 전부 각자의 컨테이너에 담아 완벽하게 ‘독립적으로’ 배포하고 관리할 수 있게 되는 거야. 이게 바로 MSA가 꿈꾸던 그림이었어!”
가볍기 때문에 높은 밀도로 서버를 운영할 수 있고, 빠르기 때문에 변화에 민첩하게 대응할 수 있다. 이 두 가지 특성이 서로 맞물려 MSA의 ‘독립성’이라는 철학을 현실의 기술로 구현해주는 핵심 열쇠였던 것이다.
솔라는 처음의 혼란을 떠올렸다. ‘격리’라는 단어에만 갇혀 있던 자신을. 이제 그녀는 첫날 봤던 태블릿 메모를 다시 열었다.
컨테이너: ... Lightweight, Portable, Isolated, Scalable.
솔라는 각 단어 옆에 자신만의 주석을 달기 시작했다.
Lightweight: 게스트 OS 없음 → 높은 집적도, 빠른 시작/종료Portable: OS 커널 공유 → 어떤 환경이든 ‘배낭’만 옮기면 실행Isolated: 프로세스 격리 → 다른 서비스에 영향 주지 않는 독립성Scalable: Lightweight 특성 덕분에 → 트래픽에 맞춰 수초 내 서비스 확장/축소 가능
이제 이 단어들은 더 이상 뜬구름 잡는 마케팅 용어가 아니었다. MSA라는 구체적인 목표 아래, 각 특성이 어떤 역할을 수행하는지 명확하게 설명하는 설계도로 보였다. 솔라는 만족스러운 미소를 지으며, 잘 정리된 자신의 노트를 바라보았다. 왜 MSA가 컨테이너를 최고의 친구로 여기는지, 이제는 누구에게든 자신 있게 설명할 수 있을 것 같았다.