3.1.1 구글 내부 시스템 ‘보그(Borg)’ 이야기

쿠버네티스를 제대로 이해하기 위한 첫걸음은 바로 그 전신이라고 할 수 있는 구글의 내부 클러스터 관리 시스템, ‘보그(Borg)’를 알아보는 것입니다. 보그는 쿠버네티스 개발팀에게 수많은 영감과 실질적인 교훈을 제공했으며, 쿠버네티스의 많은 핵심 개념과 설계 철학에 그 흔적을 남겼습니다. 마치 성공한 선배가 후배에게 자신의 귀중한 경험을 전수하듯, 보그는 쿠버네티스가 나아갈 길을 밝혀주었다고 해도 과언이 아닙니다.

보그 시스템의 탄생 배경: 구글 규모의 도전

지금으로부터 약 20여 년 전인 2000년대 초반으로 거슬러 올라갑니다. 당시 구글은 스탠퍼드 대학교의 작은 연구 프로젝트에서 시작하여, 전 세계 인터넷 사용자들에게 혁신적인 검색 경험을 제공하며 빠르게 성장 가도를 달리고 있었습니다.

구글 내부 시스템 '보그(Borg)' 이야기

검색 엔진을 필두로, 이후 Gmail(2004년 출시), Google Maps(2005년 출시), 그리고 YouTube(2005년 설립, 2006년 구글 인수)와 같은 혁신적인 서비스들을 연이어 선보이며 인터넷 지형을 바꾸어 놓았습니다. 이러한 서비스들의 폭발적인 인기는 곧 구글에게 상상을 초월하는 규모의 데이터 처리량과 끊임없이 증가하는 사용자 트래픽이라는 달콤하면서도 엄청난 기술적 부담을 안겨주었습니다.

2000년 대 초반 구글의 대규모 시스템 문제점과 해결

이러한 성장의 이면에는 구글 엔지니어들의 엄청난 노고와 끊임없는 기술적 도전이 숨어 있었습니다. 그들이 직면했던 가장 큰 과제는 바로 방대한 규모의 컴퓨팅 자원과 그 위에서 실행되는 수없이 많은 애플리케이션들을 어떻게 하면 효율적이면서도 동시에 안정적으로 관리할 수 있을까 하는 문제였습니다. 이는 단순히 서버 몇십, 몇백 대를 운영하는 수준을 훨씬 뛰어넘는, 그야말로 ‘구글 스케일(Google Scale)’이라고 불릴 만한 전례 없는 도전이었습니다.

구체적으로 살펴보면, 구글은 문자 그대로 수십만 대에 달하는 물리 서버로 구성된 거대한 데이터센터 클러스터 위에서, 매주 수십억 개에 이르는 다양한 종류의 내부 및 외부 서비스 작업(job)들을 안정적으로 실행해야 했습니다. 이 작업들은 사용자의 검색 쿼리에 수 밀리초(millisecond) 이내로 응답해야 하는 극도로 짧은 지연 시간이 생명인 실시간 서비스부터, 방대한 웹 페이지를 분석하고 인덱싱하거나, 대규모 데이터를 처리하는 데 몇 시간 또는 며칠이 걸리는 배치(batch) 작업까지 그 성격과 요구사항이 천차만별이었습니다.

여기에 더해, 다음과 같은 복합적인 요구사항들이 산더미처럼 쌓여 있었습니다:

  • 자원 효율성 극대화: 한정된, 그러나 엄청난 규모의 컴퓨팅 자원(CPU, 메모리, 디스크, 네트워크 대역폭 등)을 최대한 효율적으로 사용하여 비용을 절감하고 투자 대비 효과를 높여야 했습니다. 유휴 자원을 최소화하는 것이 관건이었습니다.
  • 높은 안정성과 가용성 확보: 구글의 핵심 서비스들은 단 몇 분의 장애도 용납되지 않는 경우가 많았습니다. 따라서 개별 하드웨어나 소프트웨어의 장애에도 불구하고 서비스는 중단 없이 지속적으로 제공되어야 했습니다.
  • 신속한 서비스 배포 및 업데이트: 경쟁이 치열한 인터넷 서비스 시장에서 살아남기 위해서는 새로운 기능을 빠르게 개발하여 사용자들에게 제공하고, 기존 서비스를 문제없이 업데이트할 수 있는 민첩성이 필수적이었습니다.
  • 다양한 워크로드 지원: 앞서 언급했듯이, 실시간 서비스와 배치 작업, 장기 실행 서비스와 단기 실행 작업 등 서로 다른 특성을 가진 다양한 워크로드를 동일한 인프라 위에서 효율적으로 함께 실행할 수 있어야 했습니다.

전통적인 시스템 관리 방식으로 예를 들어 각 서버에 수동으로 애플리케이션을 설치하고 설정하거나, 간단한 스크립트를 이용한 자동화 수준으로는 이러한 ‘구글 스케일’의 문제를 도저히 해결할 수 없었습니다. 또한, 시장에 나와 있던 어떤 상용 시스템 관리 솔루션도 구글의 독특하고 극한적인 요구사항을 만족시키기에는 역부족이었습니다. 기존 전통적인 방식으로는 문제를 해결 할 수 가 없었습니다.

결국 구글은 “다른 누구도 우리의 문제를 해결해 줄 수 없다면, 우리가 직접 만들자!”라는 담대한 결정을 내리게 됩니다. 자신들의 독특하고 극한적인 요구사항을 만족시킬 수 있는 유일한 방법은 처음부터 끝까지 자체적으로 설계하고 개발한 대규모 클러스터 관리 시스템을 구축하는 것이라고 판단한 것입니다. 그렇게 해서 2003년경부터 본격적으로 개발되어 구글 내부의 거의 모든 서비스를 떠받치는 핵심 인프라로 자리 잡기 시작한 시스템이 바로 ‘보그(Borg)’입니다.

흥미롭게도 “보그”라는 이름은 당시 구글 엔지니어들 사이에서 인기 있었던 SF 시리즈인 <스타트렉(Star Trek)>에 등장하는, 개별 구성원들이 하나의 거대한 집단 지성(collective consciousness)에 신경망으로 연결되어 마치 하나의 통일된 유기체처럼 효율적으로 작동하는 반기계적 외계 종족의 이름에서 따왔다고 합니다. 이는 구글이 보그 시스템을 통해 꿈꿨던 미래, 즉 수많은 개별 서버와 애플리케이션들이 마치 하나의 거대하고 지능적인 시스템처럼 중앙에서 통합적으로 관리되고, 서로 협력하며, 최적의 효율로 운영되는 모습을 상징적으로 보여준다고 할 수 있습니다. 보그의 탄생은 단순히 새로운 소프트웨어의 개발을 넘어, 대규모 분산 시스템 운영에 대한 구글의 근본적인 철학과 접근 방식의 변화를 의미하는 것이었습니다.

보그 시스템의 핵심 기능과 운영 철학: 대규모 자동화와 효율성

보그는 단순한 작업 실행기를 넘어, 구글의 거의 모든 프로덕션 워크로드를 책임지는 정교하고 강력한 플랫폼이었습니다. 보그가 성공적으로 구글 규모의 도전을 감당할 수 있었던 비결은 다음과 같은 혁신적인 핵심 기능과 운영 철학에 있었습니다. 이 기능과 철학들은 오늘날 쿠버네티스를 이해하는 데 매우 중요한 단서들을 제공합니다.

보그 시스템의 핵심 기능과 운영 철학: 대규모 자동화와 효율성
  1. 작업(Job)과 태스크(Task) 기반의 워크로드 관리:보그에서 애플리케이션은 ‘작업(Job)’이라는 논리적인 단위로 관리되었습니다. 각 작업은 하나 이상의 동일한 실행 단위인 ‘태스크(Task)’로 구성되었습니다. 예를 들어, 웹 서버 애플리케이션 작업은 여러 개의 웹 서버 태스크로 이루어질 수 있었습니다. 각 태스크는 리눅스 컨테이너 기술(당시에는 지금의 컨테이너와 완전히 동일하진 않았지만, cgroups와 네임스페이스의 초기 형태를 활용한 유사한 격리 기술)을 사용하여 다른 태스크들로부터 격리된 환경에서 자신만의 리소스를 할당받아 실행되었습니다. 이는 오늘날 쿠버네티스에서 애플리케이션 배포의 기본 단위인 ‘파드(Pod)’와 그 안에서 실행되는 개별 ‘컨테이너(Container)’의 관계와 매우 흡사한 개념입니다.
  2. 클러스터 아키텍처 및 선언적 스케줄링:보그 클러스터는 수천에서 수만 대의 머신으로 구성된 ‘셀(Cell)’이라는 단위로 관리되었습니다. 각 셀에는 중앙 컨트롤러 역할을 하는 ‘보그마스터(BorgMaster)’가 존재했고, 각 머신에는 ‘보그렛(Borglet)’이라는 에이전트가 실행되어 보그마스터의 지시에 따라 태스크를 실행하고 상태를 보고했습니다. 사용자는 실행하고자 하는 작업의 명세(예: 필요한 CPU 코어 수, 메모리 양, 디스크 공간, 실행할 프로그램 바이너리 및 설정 등)를 선언적인 형태로 작성하여 보그마스터에게 제출했습니다. 그러면 보그마스터는 이 명세를 바탕으로 클러스터 내의 가용 자원, 작업의 우선순위, 할당량(quota), 그리고 다양한 제약 조건들을 종합적으로 고려하여 태스크를 가장 적절한 머신에 자동으로 배치(스케줄링)했습니다. 이 ‘선언적 접근 방식’과 ‘중앙 집중형 스케줄러’는 쿠버네티스의 핵심 설계 원칙으로 그대로 이어집니다.
  3. 리소스 공유와 극대화된 효율성:보그의 가장 중요한 설계 목표 중 하나는 구글이 보유한 막대한 서버 자원을 단 1%라도 낭비 없이 최대한 효율적으로 사용하는 것이었습니다. 이를 위해 보그는 매우 정교한 리소스 공유 메커니즘을 도입했습니다. 가장 대표적인 것이 바로 서로 다른 종류의 작업(예: 지연 시간에 민감한 사용자 대면 프로덕션 작업과, 상대적으로 덜 긴급하지만 많은 자원을 소모하는 비프로덕션 배치 작업)을 동일한 물리 머신에서 안전하게 함께 실행(co-location)하는 것이었습니다. 각 작업에는 우선순위(priority)와 리소스 할당량(quota)이 부여되어, 중요한 프로덕션 작업이 필요할 때 자원을 확보할 수 있도록 보장하면서도, 남는 자원은 우선순위가 낮은 작업들이 활용할 수 있도록 하여 머신의 평균 사용률을 극적으로 높였습니다. 이는 마치 한정된 공간을 여러 사람이 효율적으로 나눠 쓰는 것과 같은 원리입니다.
  4. 고가용성 및 자동화된 장애 복구 (Self-healing):대규모 분산 시스템에서는 개별 머신이나 소프트웨어의 장애는 피할 수 없는 일상적인 사건입니다. 보그는 이러한 철학을 바탕으로 시스템 전체의 고가용성을 확보하기 위한 다양한 장치를 마련했습니다. 보그마스터 자체도 여러 복제본으로 운영되어 단일 장애점(Single Point of Failure)을 제거했습니다. 또한, 만약 특정 태스크가 실행 중이던 머신에 하드웨어 장애가 발생하거나, 태스크 자체의 오류로 인해 비정상적으로 종료되면, 보그렛과 보그마스터는 이를 신속하게 감지하고 해당 태스크를 다른 건강한 머신에 자동으로 재시작했습니다. 이러한 ‘자가 치유(self-healing)’ 능력은 서비스 중단 시간을 최소화하고 운영자의 개입을 줄이는 데 결정적인 역할을 했으며, 쿠버네티스의 핵심 가치 중 하나로 계승되었습니다.
  5. 애플리케이션 수준의 관리 기능 (롤링 업데이트, 상태 확인 등):보그는 단순히 태스크를 실행하고 중지하는 것을 넘어, 애플리케이션의 전체 생명주기를 관리하는 데 필요한 다양한 기능들을 제공했습니다. 예를 들어, 새로운 버전의 애플리케이션을 배포할 때, 기존 버전의 모든 태스크를 한 번에 중단시키고 새 버전으로 교체하는 대신, 일부 태스크만 점진적으로 업데이트하는 롤링 업데이트(rolling update) 방식을 지원하여 서비스 중단을 최소화했습니다. 또한, 각 태스크의 건강 상태를 주기적으로 확인하는 상태 확인(health checking) 메커니즘을 통해 문제가 발생한 태스크를 신속하게 감지하고 조치할 수 있도록 했습니다.
  6. 네이밍 서비스 및 로드 밸런싱:동적으로 생성되고 소멸되며, 클러스터 내 여러 머신에 분산되어 실행되는 태스크들에 안정적으로 접근하기 위해서는 일종의 서비스 디스커버리 메커니즘이 필요합니다. 보그는 이를 위해 ‘보그 네이밍 서비스(Borg Naming Service, BNS)’라는 자체 시스템을 운영했습니다. BNS는 특정 작업에 속한 태스크들의 현재 위치(IP 주소와 포트) 정보를 관리하고, 애플리케이션이 논리적인 서비스 이름을 통해 이 태스크들에 접근할 수 있도록 해주었습니다. 또한, 여러 개의 동일한 태스크들 사이에서 들어오는 요청을 분산 처리하는 기본적인 로드 밸런싱 기능도 제공했습니다. 이는 쿠버네티스의 ‘서비스(Service)’ 오브젝트와 DNS 기반 서비스 디스커버리 개념의 중요한 모태가 되었습니다.

이처럼 보그는 오늘날 우리가 쿠버네티스에서 당연하게 여기는 많은 핵심 기능들 – 컨테이너 기반의 워크로드 격리, 선언적 설정 관리, 자동 스케줄링, 리소스 효율화, 자가 치유, 서비스 디스커버리, 롤링 업데이트 등 – 의 초기 형태를 이미 십수 년 전에 구현하고 대규모로 운영하고 있었습니다. 보그의 핵심 운영 철학은 “대규모 분산 시스템은 인간의 수동 개입을 최소화하고, 가능한 모든 것을 자동화하며, 장애는 예외가 아닌 일상으로 간주하고 이에 대비해야 하며, 자원은 최대한 공유하여 효율성을 극대화해야 한다”는 것으로 요약될 수 있습니다. 이 철학은 쿠버네티스에도 깊숙이 스며들어, 클라우드 네이티브 시대를 이끄는 핵심 동력이 되고 있습니다.

쿠버네티스는 보그의 직접적인 복제품은 아니지만, 보그를 만들고 운영하며 얻었던 수많은 시행착오와 값진 경험, 그리고 성공적인 패턴들을 바탕으로 탄생한, 더 현대적이고 개방적인 시스템입니다. 보그라는 거인의 어깨 위에서 시작했기에 쿠버네티스는 빠르게 성숙하고 발전할 수 있었던 것이죠. 다음 절에서는 이러한 보그의 유산을 바탕으로 쿠버네티스가 어떻게 세상에 등장하게 되었는지, 그 이야기를 계속 이어가도록 하겠습니다.

보그가 쿠버네티스 설계에 미친 영향: 경험으로부터 얻은 교훈

쿠버네티스는 보그 시스템의 코드를 직접 가져와 만든 후속 버전, 즉 ‘보그 2.0’과 같은 직접적인 후계자는 아닙니다. 오히려, 보그를 10년 이상 개발하고 운영하면서 얻었던 방대한 경험과 심오한 교훈을 바탕으로, 구글의 엔지니어들이 클라우드 시대의 새로운 요구사항에 맞춰 완전히 새롭게 설계하고 구현한 시스템이라고 이해하는 것이 더 정확합니다. 보그는 구글이라는 특정 기업의 내부 환경과 워크로드에 매우 깊숙이 맞춰져 최적화되어 있었습니다. 이는 구글 내부에서는 엄청난 효율성과 안정성을 제공했지만, 동시에 외부 세계의 다양한 기업과 개발자들이 가진 각기 다른 인프라 환경, 애플리케이션 특성, 그리고 운영 방식을 모두 만족시키기에는 구조적인 한계가 있었습니다. 보그는 마치 고도로 전문화된 장인과 같아서, 특정 작업에는 최고였지만 범용성은 떨어졌던 셈이죠.

쿠버네티스 개발팀(Joe Beda, Brendan Burns, Craig McLuckie 등 초기 핵심 멤버들은 대부분 보그 프로젝트에 깊이 관여했던 엔지니어들이었습니다)은 보그의 성공적인 핵심 원칙과 아이디어는 적극적으로 계승하되, 보그를 운영하면서 느꼈던 아쉬움이나 한계점을 극복하고, 더 나아가 오픈소스 커뮤니티와 함께 성장할 수 있는 더욱 유연하고 개방적인 시스템을 만들고자 했습니다. 그들이 보그로부터 얻은 귀중한 교훈과 이를 쿠버네티스 설계에 반영한 주요 내용은 다음과 같습니다.

  • API 중심 설계 (API-centric Design)와 확장성:보그는 강력한 기능을 가지고 있었지만, 그 내부 로직과 인터페이스가 상대적으로 덜 개방적이었고, 주로 구글 내부 도구들과 긴밀하게 통합되어 있었습니다. 이는 외부 개발자들이 보그 시스템을 활용하거나 확장하는 데 어려움을 주었습니다. 반면, 쿠버네티스는 프로젝트 초기부터 잘 정의되고, 버전 관리되며, RESTful 원칙을 따르는 강력한 API를 시스템의 핵심으로 삼았습니다. 모든 쿠버네티스 기능은 이 API를 통해 노출되고 제어됩니다. kubectl과 같은 커맨드 라인 도구, 웹 대시보드, 그리고 수많은 서드파티 도구들이 모두 이 동일한 API를 사용하여 쿠버네티스와 상호작용합니다. 이러한 API 중심 설계는 다음과 같은 중요한 이점을 가져다주었습니다.
    • 상호 운용성 및 통합 용이성: 다양한 외부 시스템(예: CI/CD 도구, 모니터링 시스템, 로깅 시스템, 스토리지 솔루션 등)과의 손쉬운 통합이 가능해졌습니다.
    • 자동화 촉진: API를 통해 프로그래밍 방식으로 클러스터 자원을 관리하고 운영 작업을 자동화하는 것이 매우 용이해졌습니다.
    • 생태계 확장: 개발자들이 쿠버네티스 API를 기반으로 새로운 도구나 기능을 쉽게 개발하고 공유할 수 있는 기반을 마련하여, 풍부하고 활발한 생태계가 형성되는 데 크게 기여했습니다.
    • 확장성: 이후에 배울 CRD(Custom Resource Definition)와 오퍼레이터(Operator) 패턴을 통해 사용자가 직접 쿠버네티스 API를 확장하여 자신만의 커스텀 리소스를 정의하고 관리할 수 있게 되었습니다. 이는 보그에서는 상상하기 어려웠던 수준의 유연성입니다.
  • 애플리케이션 중심적 관점 (Application-centric Perspective):보그는 본질적으로 클러스터의 자원을 효율적으로 관리하고 작업을 안정적으로 실행하는 데 초점을 맞춘, 다소 머신 중심적인(machine-oriented) 측면이 있었습니다. 물론 애플리케이션 운영을 위한 기능도 제공했지만, 시스템의 근본적인 추상화 단위는 머신과 그 위에서 실행되는 프로세스에 가까웠습니다. 반면, 쿠버네티스는 개발자가 자신의 애플리케이션을 어떻게 배포하고, 연결하고, 확장하고, 관리할 것인가라는 애플리케이션 개발자의 관점을 더욱 중요하게 고려하여 설계되었습니다.

    이러한 애플리케이션 중심적 사고를 가장 잘 보여주는 예가 바로 ‘파드(Pod)’라는 개념입니다. 파드는 하나 이상의 긴밀하게 연관된 컨테이너 그룹과 이들이 공유하는 네트워크 및 스토리지 자원을 함께 묶은, 쿠버네티스에서 배포 가능한 가장 작은 단위입니다. 이는 마치 단일 애플리케이션(또는 그 일부)을 나타내는 논리적인 호스트와 같습니다. 개발자는 개별 컨테이너의 낮은 수준의 세부 사항보다는, 파드라는 더 높은 수준의 추상화를 통해 애플리케이션을 정의하고 관리할 수 있게 되었습니다. 이는 애플리케이션 배포와 관리의 복잡성을 줄이고 개발자의 생산성을 높이는 데 크게 기여했습니다.

  • 개방성과 이식성 (Openness and Portability):보그는 구글의 고도로 통제되고 최적화된 내부 데이터센터 인프라에 깊숙이 결합되어 있었습니다. 이는 구글 내부에서는 최고의 성능과 효율성을 낼 수 있었지만, 다른 환경으로 이전하거나 다른 기업에서 사용하는 것은 거의 불가능했습니다. 쿠버네티스는 이러한 한계를 극복하고자, 처음부터 특정 클라우드 제공업체나 특정 하드웨어, 특정 운영체제에 종속되지 않고, 온프레미스 데이터센터, 다양한 퍼블릭 클라우드(AWS, Azure, GCP 등), 심지어 개발자의 로컬 머신에 이르기까지 다양한 환경에서 동일하게 작동할 수 있도록 설계되었습니다. 이러한 이식성은 사용자가 특정 벤더에 종속되는 것을 피하고(vendor lock-in 방지), 워크로드를 자유롭게 이동하며, 하이브리드 클라우드나 멀티 클라우드 전략을 효과적으로 구현할 수 있는 유연성을 제공합니다. 이를 위해 쿠버네티스는 CNI(Container Network Interface), CSI(Container Storage Interface), CRI(Container Runtime Interface)와 같은 표준 인터페이스를 정의하여, 다양한 네트워크, 스토리지, 컨테이너 런타임 플러그인을 손쉽게 통합할 수 있도록 했습니다.
  • 커뮤니티 기반의 발전과 거버넌스 (Community-driven Development and Governance):보그는 전적으로 구글 내부의 필요에 의해, 구글 엔지니어들에 의해 개발되고 발전하는 폐쇄적인 모델이었습니다. 반면, 쿠버네티스는 2014년 구글에 의해 처음 오픈소스 프로젝트로 공개된 이후, 곧바로 클라우드 네이티브 컴퓨팅 재단(CNCF)에 기증되어 벤더 중립적인 거버넌스 하에 전 세계 개발자 커뮤니티의 참여와 기여를 통해 발전하는 모델을 채택했습니다. 이는 쿠버네티스가 단일 기업의 이해관계를 넘어, 업계 전체의 표준 기술로 성장하고, 다양한 사용 사례와 요구사항을 폭넓게 수용하며, 지속 가능하고 건강한 생태계를 구축하는 데 결정적인 역할을 했습니다. 수많은 개인 개발자와 경쟁 관계에 있는 여러 기업들이 쿠버네티스라는 공동의 목표를 위해 협력하고 기여하는 오픈소스 커뮤니티의 힘은 쿠버네티스 성공의 가장 중요한 원동력 중 하나입니다.

결론적으로, 보그는 쿠버네티스에게 “대규모 분산 시스템에서 무엇이 실제로 작동하고, 무엇이 중요하며, 어떤 설계 결정이 장기적으로 어떤 결과를 가져오는지, 그리고 어떤 실수를 반복해서는 안 되는지”에 대한 값으로 매길 수 없는 귀중한 청사진과 경험적 지혜를 제공했습니다. 쿠버네티스는 이 보그라는 거인의 어깨 위에서 시작하여, 거기에 더해 API 중심 설계, 애플리케이션 중심 관점, 개방성과 이식성, 그리고 커뮤니티 기반 발전이라는 새로운 가치를 더함으로써, 컨테이너 오케스트레이션이라는 새로운 기술 영역을 개척하고 오늘날 클라우드 네이티브 시대를 이끄는 핵심 기술로 당당히 발돋움할 수 있었던 것입니다.

이처럼 성공적인 기술 뒤에는 항상 선구적인 시도와 그로부터 얻은 값진 경험, 그리고 과거의 한계를 극복하려는 끊임없는 혁신의 노력이 숨어 있다는 것을 기억하는 것은, 우리가 새로운 기술을 배우고 이해하는 데 있어 매우 중요한 관점을 제공해 줄 것입니다. 쿠버네티스의 여정은 이제 막 시작되었으며, 그 발전 가능성은 무궁무진하다고 할 수 있습니다.