Kubernetes의 탄생 — Google Borg에서 CNCF까지

이 글은 K8s 입문 시리즈의 첫 번째 글이다.

이 시리즈의 커리큘럼은 SK Devocean의 Kubernetes(쿠버네티스)를 처음 공부하려면 무엇을 공부해야 할까? (seungkyua) 글의 학습 로드맵을 바탕으로 구성했다.

1. docker run 하나면 충분한데, 왜 Kubernetes인가

컨테이너 하나를 띄우는 건 정말 쉽다. Docker가 설치된 서버에서 명령 한 줄이면 끝난다.

docker run -d -p 80:80 nginx

개발 서버 한 대에 컨테이너 몇 개를 올리는 수준이라면 이걸로 충분하다. 문제는 서비스가 커지면서 시작된다. 구체적인 시나리오로 따라가 보자.

서비스가 잘 돼서 서버가 3대가 됐다. 컨테이너는 30개다. 이제 이런 질문이 생긴다.

  • 새 컨테이너는 어느 서버에 띄워야 하나? 메모리가 남는 서버를 사람이 일일이 확인해야 하나?
  • 새벽 3시에 컨테이너가 죽으면 누가 재시작하나? 당직을 세워야 하나?
  • 트래픽이 몰리면 컨테이너를 늘려야 하는데, 서버마다 SSH로 들어가서 docker run을 반복해야 하나?
  • 컨테이너가 재시작되면 IP가 바뀌는데, 서로를 어떻게 찾아가나? 설정 파일을 매번 고쳐야 하나?
  • 새 버전을 배포할 때 서비스가 끊기지 않게 하려면? 30개를 하나씩 손으로 교체해야 하나?

서버가 100대, 컨테이너가 1,000개가 되면 이 질문들은 “불편함”이 아니라 “불가능”이 된다. 사람이 스프레드시트로 서버별 컨테이너 배치를 관리하고, 장애 알림을 받고 수동으로 복구하는 방식은 규모가 커지는 순간 무너진다.

식당에 비유하면 이렇다. 주방장 혼자 요리하는 동네 식당은 사장이 머릿속으로 다 관리할 수 있다. 하지만 지점이 100개인 프랜차이즈라면 본사가 필요하다. 어느 지점에 인력을 배치할지, 재료가 떨어진 지점을 어떻게 채울지, 신메뉴를 전 지점에 어떻게 순차 도입할지 — 이걸 자동으로 해주는 본사 시스템이 바로 컨테이너 오케스트레이터(orchestrator)이고, 그 사실상 표준이 Kubernetes다.

이 문제를 세상에서 가장 먼저, 가장 큰 규모로 겪은 회사가 Google이다. Kubernetes의 이야기는 Google 내부 시스템 Borg에서 시작한다.


2. Google Borg — Kubernetes의 조상

Google은 검색, Gmail, Google Docs 같은 서비스를 전 세계 규모로 운영하면서 일찍부터 컨테이너 기술을 사용했다. 그리고 이 컨테이너들을 관리하기 위해 Borg라는 내부 클러스터 매니저를 만들었다.

Borg의 존재는 오랫동안 외부에 자세히 공개되지 않다가, 2015년 EuroSys 학회에서 논문으로 발표됐다.

Large-scale cluster management at Google with Borg (Verma et al., Google, EuroSys 2015)

논문이 밝힌 Borg의 규모는 이렇다.

  • 클러스터 하나가 최대 수만 대(tens of thousands)의 머신으로 구성된다.
  • 수천 개 애플리케이션에서 나온 수십만 개(hundreds of thousands)의 job을 실행한다.
  • Gmail, Google Docs, 웹 검색 같은 사용자 대면 서비스와 내부 인프라 서비스가 모두 Borg 위에서 돌아간다.
  • admission control, 효율적인 task packing, 오버커밋, 머신 공유로 높은 자원 활용률을 달성한다.
  • 선언적(declarative) job 명세 언어, 네임 서비스 연동, 실시간 모니터링을 제공한다.

주목할 점은 “선언적 명세”라는 단어다. 사용자가 “이 작업을 이런 조건으로 실행해 달라”고 선언하면, 어느 머신에 배치할지·죽으면 어떻게 복구할지는 Borg가 알아서 처리한다. 이 철학이 Kubernetes에 그대로 이어진다.

2.1 Borg → Omega → Kubernetes 계보

Google은 10년 넘게 컨테이너를 대규모로 운영하면서 컨테이너 관리 시스템을 세 번 만들었다. 이 경험은 ACM Queue에 실린 회고 글에 정리되어 있다.

Borg, Omega, and Kubernetes (Burns et al., Google, ACM Queue 2016)

회고의 요지는 이렇다. 세 시스템은 성격이 서로 달랐다. Borg는 배치(batch) 작업과 상시 서비스라는 이질적인 워크로드를 같은 머신에 섞어 배치해 자원 활용률을 끌어올린 실전 시스템이고, Omega는 Borg 생태계를 소프트웨어 공학적으로 더 깨끗하게 재설계해 보려던 연구 프로젝트였으며, Kubernetes는 그 둘의 교훈을 Google 바깥의 개발자를 위해 풀어낸 오픈소스다. 저자들이 꼽는 10년의 가장 큰 교훈은 개별 기능이 아니라 관점의 전환이다 — 컨테이너 덕분에 데이터센터의 관리 단위가 머신에서 애플리케이션으로 바뀌었다는 것. 개발자는 “어느 서버에 무엇을 설치할까”를 고민하는 대신 “내 애플리케이션이 어떤 상태여야 하는가”를 선언하면 되고, 머신·OS 세부 사항은 인프라가 흡수한다. 이 교훈이 구체적으로 어떤 설계로 이어졌는지는 2.2절의 표에서 정리한다.

두 번째 시스템인 Omega는 Borg의 아키텍처적 한계를 개선하려는 연구였다. 하나의 거대한(monolithic) 스케줄러가 모든 결정을 내리는 대신, 여러 스케줄러가 공유 상태(shared state) 를 보며 낙관적 동시성 제어(optimistic concurrency control) 로 병렬로 스케줄링하는 구조를 제안했다.

Omega: flexible, scalable schedulers for large compute clusters (Schwarzkopf et al., Google, EuroSys 2013)

그리고 세 번째가 Kubernetes다. Borg와 Omega가 Google 내부 전용이었던 것과 달리, Kubernetes는 처음부터 오픈소스로, Google 바깥의 개발자를 위해 만들어졌다.

Borg에서 Omega, Kubernetes를 거쳐 CNCF로 이어지는 계보

다이어그램에서 눈여겨볼 점은 다음과 같다.

  • 시스템의 순서와 논문 공개 순서가 다르다. Borg는 훨씬 오래된 시스템이지만 논문은 Omega(2013)보다 늦은 2015년에 나왔다. Kubernetes가 공개(2014)된 뒤에야 그 뿌리인 Borg가 논문으로 세상에 알려진 셈이다.
  • Kubernetes는 무에서 만들어진 것이 아니라 Borg와 Omega에서 10년 넘게 쌓인 운영 경험과 교훈의 결정체다. “왜 Kubernetes는 이렇게 설계됐지?”라는 질문의 답이 이 계보에 숨어 있는 경우가 많다.
  • Kubernetes는 v1.0이 되는 날 CNCF에 기부되며 한 회사의 프로젝트에서 커뮤니티의 프로젝트가 됐다.

2.2 Borg가 Kubernetes에 남긴 유산

ACM Queue 회고 글은 Borg·Omega에서 배운 교훈이 Kubernetes 설계에 어떻게 반영됐는지를 구체적으로 짚는다. 앞으로 이 시리즈에서 만날 핵심 개념들이 사실은 전부 이 유산이다.

Borg/Omega에서의 경험 Kubernetes의 설계 시리즈에서 다루는 편
컨테이너 하나가 아니라 함께 배치되는 컨테이너 묶음이 실제 배포 단위였다 최소 배포 단위를 컨테이너가 아닌 Pod로 정의 04편
노드 IP를 공유하고 포트를 나눠 쓰는 방식은 포트 충돌 등 복잡성이 컸다 Pod마다 고유 IP를 부여해 포트 관리 문제를 제거 04·06편
경직된 job 계층 구조로는 워크로드를 유연하게 묶기 어려웠다 자유롭게 붙이고 조회하는 Label 기반 그룹핑 05편
중앙 시스템이 모든 것을 명령하는 구조는 확장에 불리했다 API 서버 + 선언적 상태 + reconcile 컨트롤러 구조 03·05편
Omega의 공유 상태(shared state) 아키텍처 실험 모든 컴포넌트가 API 서버를 통해 상태 저장소를 공유하는 구조 03편

한 가지 더, Borg의 컨테이너 격리는 리눅스 커널의 cgroups를 기반으로 했다. Docker를 포함한 오늘날의 컨테이너 기술 역시 같은 커널 기능 위에 서 있으니, Kubernetes와 Docker는 뿌리에서부터 같은 토양을 공유하는 셈이다.

정리하면, 뒤에서 배울 Pod·Label·컨트롤러 같은 개념은 누군가 책상에서 발명한 것이 아니라 Google이 10년 넘게 실제 서비스를 운영하며 검증한 패턴이다. “왜 이런 개념이 있지?”라는 의문이 들 때마다 이 표로 돌아오면 답이 보인다.


3. 오픈소스로 — 2014년 공개, 2015년 v1.0

3.1 2014년 6월: Kubernetes 공개

2014년 6월, Google은 Kubernetes를 오픈소스 프로젝트로 공개했다. 당시는 Docker의 등장으로 컨테이너가 폭발적으로 대중화되던 시점이었다. 개별 컨테이너를 만들고 실행하는 문제는 Docker가 풀었지만, 1장에서 본 “수백 대 서버 위 수천 개 컨테이너”의 운영 문제는 여전히 비어 있었고, Google은 Borg의 경험을 오픈소스로 풀어내며 이 자리를 차지했다.

이름에 대한 상식 하나. Kubernetes는 그리스어 κυβερνήτης(kubernētēs)에서 왔고, 키잡이(helmsman)·조타수(pilot) 라는 뜻이다. 컨테이너를 실은 배(Docker의 고래 로고를 떠올려 보자)를 조종하는 키잡이라는 의미가 담겨 있다. 흔히 쓰는 약어 K8s는 K와 s 사이의 8글자를 숫자로 줄인 표기(numeronym)다.

3.2 2015년 7월 21일: v1.0과 CNCF 창립

약 1년 뒤인 2015년 7월 21일, Kubernetes v1.0이 릴리스됐다. 개발팀이 “실제 프로덕션에서 쓸 수 있을 만큼 안정적”이라고 선언한 첫 버전이다.

그리고 같은 날, Linux Foundation은 CNCF(Cloud Native Computing Foundation) 창립을 발표했다. Google은 Kubernetes를 CNCF에 시드(seed) 기술로 기부했고, Google 외에도 Red Hat, Docker, IBM, Intel, Cisco, VMware, CoreOS, Twitter 등 21개 조직이 창립 멤버로 참여했다.

여기서 “왜”를 물어볼 필요가 있다. Google은 왜 애써 만든 프로젝트를 재단에 넘겼을까?

  • 벤더 중립성 때문이다. Kubernetes가 Google 소유로 남아 있었다면, 경쟁사인 AWS·Microsoft·Red Hat이 자사 제품의 기반으로 채택하기 어려웠을 것이다. 중립 재단이 상표권과 거버넌스를 관리하면 모든 회사가 안심하고 올라탈 수 있다.
  • 생태계 선점 효과도 있다. 당시 컨테이너 오케스트레이션은 Docker Swarm, Apache Mesos 등과의 경쟁 구도였다. 오픈 거버넌스는 커뮤니티와 기업의 기여를 끌어모으는 가장 강력한 무기였고, 실제로 Kubernetes는 이 경쟁에서 사실상 표준의 자리를 가져갔다.

연도가 헷갈리기 쉬우니 표로 정리한다.

연도 사건 의미
2013 Omega 논문 (EuroSys 2013) Borg 후속 연구, 스케줄러 아키텍처 실험
2014년 6월 Kubernetes 오픈소스 공개 Borg/Omega의 교훈을 담은 3세대 시스템, 처음부터 오픈소스
2015년 4월 Borg 논문 (EuroSys 2015) 베일에 싸여 있던 Kubernetes의 뿌리가 공식 공개
2015년 7월 21일 Kubernetes v1.0 + CNCF 창립 프로덕션 준비 선언, Google이 K8s를 CNCF에 기부
2016 “Borg, Omega, and Kubernetes” (ACM Queue) 세 시스템에서 얻은 교훈을 Google이 직접 회고

4. CNCF는 무엇을 하는 조직인가

CNCF(Cloud Native Computing Foundation) 는 Linux Foundation 산하의 비영리 재단으로, 클라우드 네이티브 오픈소스 생태계를 키우는 것이 목적이다. 하는 일을 요약하면 다음과 같다.

  • 프로젝트 육성: Kubernetes를 비롯한 오픈소스 프로젝트를 받아들여 거버넌스, 법적 지원(상표·라이선스), 인프라를 제공한다.
  • 벤더 중립 거버넌스: 특정 회사가 아니라 재단과 커뮤니티가 프로젝트의 방향을 결정한다.
  • 커뮤니티와 표준: KubeCon + CloudNativeCon 같은 컨퍼런스를 열고, 자격증(CKA 등)과 교육 프로그램을 운영한다.

CNCF 프로젝트에는 성숙도에 따라 Sandbox → Incubating → Graduated라는 3단계 등급이 있다. 프로젝트가 얼마나 널리 채택됐는지, 거버넌스가 건강한지 등을 기준으로 승급하는데, 자세한 기준과 대표 프로젝트들은 이 시리즈의 마지막 글(09편)에서 다룬다. 지금은 “Kubernetes는 CNCF의 첫 번째이자 대표 Graduated 프로젝트”라는 것만 기억하면 된다.

비유하면 CNCF는 국제 표준화 기구 + 인큐베이터다. 유망한 오픈소스 프로젝트를 받아 중립적인 운동장에서 키우고, 졸업(Graduated)시켜 업계 표준으로 만든다.

Kubernetes를 배우는 입장에서 CNCF가 중요한 이유는 두 가지다.

  • 기술 선택의 나침반이 된다. 모니터링, 로깅, 서비스 메시 같은 주변 도구를 고를 때 CNCF 프로젝트 목록과 성숙도 등급은 “커뮤니티가 검증한 선택지”를 알려주는 지도 역할을 한다.
  • 한 회사에 종속되지 않는다는 보증이다. Kubernetes를 배워두면 특정 클라우드(AWS, GCP, Azure)나 특정 벤더에 갇히지 않는다. 같은 개념과 명령이 어디서나 통한다. 이 시리즈에 시간을 투자할 가치가 있는 이유이기도 하다.

5. 그래서 Kubernetes는 무슨 일을 하는가

역사를 알았으니, Kubernetes가 실제로 해주는 일을 1장의 질문에 대응시켜 보자. Kubernetes는 흔히 오케스트라 지휘자에 비유된다. 바이올린(컨테이너) 하나하나를 직접 연주하지는 않지만, 누가 언제 무엇을 연주할지 조율해서 전체가 하나의 곡(서비스)이 되게 만든다.

기능 하는 일 한 줄 비유
스케줄링 (Scheduling) 컨테이너를 자원 여유·조건에 맞는 서버(노드)에 자동 배치한다 호텔 프런트가 빈 방 상태를 보고 손님 방을 배정한다
자동 복구 (Self-healing) 컨테이너가 죽으면 감지해서 자동으로 다시 띄운다 쓰러진 볼링핀을 자동으로 다시 세우는 기계
스케일링 (Scaling) 부하에 따라 컨테이너 개수를 늘리고 줄인다 점심시간에 계산대를 더 열고 한가하면 닫는 마트
서비스 디스커버리 & 로드밸런싱 컨테이너 IP가 바뀌어도 고정된 이름으로 찾아가게 하고 트래픽을 분산한다 담당자가 바뀌어도 번호는 그대로인 회사 대표 전화
자동 롤아웃 & 롤백 (Rollout/Rollback) 새 버전을 무중단으로 점진 배포하고, 문제가 생기면 이전 버전으로 되돌린다 비행기 조종을 한 명씩 교대해 비행이 끊기지 않게 하는 것

이 기능들을 관통하는 설계 철학이 하나 있다. Borg에서 물려받은 선언적(declarative) 모델이다.

  • 사용자는 “nginx 컨테이너 3개가 항상 떠 있어야 한다”라는 원하는 상태(desired state) 를 선언한다.
  • Kubernetes는 현재 상태(current state) 를 계속 관찰하면서, 둘이 어긋나면 스스로 맞춘다. 컨테이너가 하나 죽어 2개가 되면, 사람이 명령하지 않아도 1개를 새로 띄워 3개로 되돌린다.
선언적 모델의 reconcile 루프 — 원하는 상태와 현재 상태를 비교해 차이를 메우는 조치를 반복한다
  • 이 루프는 한 번 실행되고 끝나는 것이 아니라 끝없이 반복된다. 그래서 새벽 3시에 컨테이너가 죽어도 사람 개입 없이 몇 초 안에 복구된다.
  • 화살표가 사용자에게 돌아가지 않는다는 점이 핵심이다. 선언 이후의 모든 판단과 조치는 Kubernetes의 몫이다.
  • 위 다섯 가지 기능(스케줄링·복구·스케일링·디스커버리·롤아웃)은 전부 이 루프의 변주다. “무엇이 어긋났고, 어떻게 메꾸는가”의 대상만 다를 뿐이다.

"서버에 들어가서 이 명령을 실행해라"(명령형)가 아니라 "결과적으로 이 상태여야 한다"(선언형)로 운영 방식을 바꾼 것이 Kubernetes의 본질이다. 이 동작 원리(reconcile 루프)는 03편에서 아키텍처와 함께 자세히 해부한다.

1장의 시나리오로 돌아가 보면 이렇게 정리된다. 어느 서버에 띄울지는 스케줄러가, 새벽 3시의 재시작은 자동 복구가, 트래픽 대응은 스케일링이, 바뀌는 IP 문제는 서비스 디스커버리가, 무중단 배포는 롤아웃/롤백이 대신한다. 사람은 원하는 상태를 선언하는 일만 하면 된다.


6. 그럼 Docker와 Kubernetes는 무슨 관계인가

입문자가 가장 자주 헷갈리는 지점이라 짚고 넘어간다. 결론부터 말하면 둘은 경쟁 관계가 아니라 서로 다른 층을 담당하는 보완 관계다.

  • Docker는 컨테이너 이미지를 만들고, 한 대의 머신에서 컨테이너를 실행하는 도구다.
  • Kubernetes는 여러 대의 머신에 걸쳐 수많은 컨테이너를 배치·복구·확장하는 오케스트레이터다. 컨테이너 실행 자체는 각 노드의 컨테이너 런타임에게 맡긴다.

항만 물류에 비유하면, Docker는 화물을 규격 컨테이너 박스에 담고 옮기는 지게차이고, Kubernetes는 수천 개 컨테이너를 어느 배에 어떤 순서로 실을지 결정하는 항만 관제 시스템이다. 지게차가 없으면 관제 시스템이 할 일이 없고, 관제 시스템이 없으면 지게차 수백 대가 뒤엉킨다.

질문
Kubernetes는 Docker를 대체하나? 아니다. 담당 계층이 다르다. 이미지 빌드에는 여전히 Docker(또는 호환 도구)를 쓴다
Docker 없이도 Kubernetes를 쓸 수 있나? 가능하다. Kubernetes는 CRI라는 표준 인터페이스로 containerd 등 여러 런타임을 지원한다 (03편에서 상세히)
Docker를 모르면 이 시리즈를 못 따라오나? docker run으로 컨테이너를 한 번이라도 띄워봤다면 충분하다. 나머지는 시리즈 안에서 설명한다

실제로 다음 편에서 쓸 kind라는 도구는 “Kubernetes in Docker”라는 이름 그대로, Docker 컨테이너 안에 Kubernetes 클러스터를 통째로 띄운다. 두 기술이 얼마나 자연스럽게 맞물리는지 직접 확인하게 될 것이다.


7. 이 시리즈에서 배울 것

이 시리즈는 Kubernetes를 처음 접하는 사람이 로컬 환경에서 직접 손을 움직이며 핵심 개념을 잡는 것을 목표로 한다. 순서는 SK Devocean의 로드맵 글(참고 문헌)을 바탕으로 재구성했다.

주제 이 글이 답하는 질문
01 역사와 배경 (현재 글) Kubernetes는 왜, 어떻게 태어났나?
02 kind와 kubectl 내 노트북에 클러스터를 어떻게 만드나?
03 아키텍처 클러스터 내부는 어떤 부품으로 돌아가나?
04 Pod 배포의 최소 단위는 무엇이고 어떻게 스케줄링되나?
05 워크로드 Pod를 여러 개, 안전하게 운영하려면?
06 네트워킹 Pod끼리, 그리고 외부와 어떻게 통신하나?
07 스토리지와 설정 데이터와 설정을 컨테이너 밖에서 어떻게 관리하나?
08 권한 관리 누가 무엇을 할 수 있는지 어떻게 통제하나?
09 Operator와 CNCF 생태계 Kubernetes를 어떻게 확장하고, 그다음엔 뭘 공부하나?

02편에서 환경을 만들고, 03편에서 구조를 이해한 뒤, 04~08편에서 핵심 리소스를 하나씩 실습하고, 09편에서 생태계로 시야를 넓히는 흐름이다.


8. 마무리

핵심을 한 문장으로 요약하면 이렇다. Kubernetes는 Google이 Borg와 Omega로 10년 넘게 축적한 대규모 컨테이너 운영 경험을 오픈소스로 풀어낸 3세대 시스템이고, CNCF라는 중립 재단 아래에서 컨테이너 오케스트레이션의 사실상 표준이 됐다.

질문
왜 필요한가 수백 대 서버, 수천 개 컨테이너의 수동 운영은 불가능하다
어디서 왔나 Google Borg(내부 운영) → Omega(아키텍처 연구) → Kubernetes(오픈소스)
언제 태어났나 2014년 6월 공개, 2015년 7월 21일 v1.0 + CNCF 창립
누가 관리하나 Linux Foundation 산하 벤더 중립 재단 CNCF
핵심 철학은 선언적 모델 — 원하는 상태를 선언하면 시스템이 현재 상태를 맞춘다

역사는 여기까지다. 다음 글부터는 직접 손을 움직인다.

다음 글 02: 내 노트북에 클러스터 만들기 — kind와 kubectl에서는 kind로 내 노트북에 진짜 Kubernetes 클러스터를 띄우고 kubectl로 조작해 본다.


참고 문헌




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Kubernetes 확장과 생태계 — Operator와 CNCF Projects
  • Kubernetes 권한 관리 — ServiceAccount와 RBAC
  • Kubernetes 스토리지와 설정 — PV/PVC, ConfigMap, Secret
  • Kubernetes 네트워킹 — Service와 Ingress
  • Kubernetes 워크로드 — ReplicaSet, Deployment, StatefulSet, DaemonSet