Table of contents
- 읽기 전에 알아두면 좋은 것
- 컨테이너 하나로는 충분하지 않다
- 수동 운영의 한계
- Kubernetes의 기원
- Kubernetes가 대신 해주는 일
- 명령형 vs 선언형
- 기본 아키텍처 한눈에 보기
- 파드, 노드, 클러스터
- Kubernetes가 모든 걸 해결하지는 않는다
읽기 전에 알아두면 좋은 것
Kubernetes는 여러 기술 위에 쌓여 있는 도구다. 완전히 처음부터 학습하기는 어렵고, 다음 주제에 대한 기본 감각이 있으면 훨씬 수월하다.
- 컨테이너와 Docker: Kubernetes는 컨테이너 오케스트레이터다. 컨테이너가 무엇이고 이미지가 어떻게 동작하는지를 알아야 한다. Docker 입문 시리즈에서 전체 그림을 다룬다
- Linux 기초: 셸 명령어, 파일시스템, 프로세스, 권한(UID/GID) 개념. 글마다
kubectl명령어가 나오고, 컨테이너 내부는 결국 Linux 프로세스다 - 네트워크 기초: TCP/IP, HTTP, DNS, 포트의 개념. Service와 Ingress를 이해하려면 필수다
컨테이너 하나로는 충분하지 않다
Docker를 처음 배우던 날을 기억해보자. docker run nginx 한 줄이면 웹 서버가 떴고, 로컬 환경과 배포 환경이 달라서 생기던 “내 컴퓨터에서는 되는데” 문제도 말끔히 사라졌다. 그 순간에는 컨테이너가 마법 같았다.
그런데 서비스가 커지면 이야기가 달라진다. nginx 컨테이너 하나, 백엔드 컨테이너 둘, Redis 컨테이너 하나, 배치 작업 컨테이너 하나. 서버가 한 대일 때는 docker-compose로 버틸 수 있다. 그런데 서버가 열 대가 되고, 하나가 갑자기 죽어버리면? 트래픽이 튀어서 백엔드 컨테이너를 세 개에서 스무 개로 늘려야 한다면? 누가 그 작업을 한다는 말인가.
이 질문에 “사람이 수동으로 한다”라고 답하는 순간, 운영팀의 삶은 불행해진다. 새벽 두 시에 알림이 울리고, SSH로 접속해서 컨테이너를 재시작하는 일이 일상이 된다. 컨테이너는 문제의 절반만 풀어준다. 나머지 절반은 여러 컨테이너를 안정적으로 굴리는 문제, 즉 오케스트레이션의 영역이다.
수동 운영의 한계
컨테이너 없이 서버를 운영하던 시절을 돌아보면 이런 문제들이 있었다.
- 서버 한 대가 죽으면 사람이 감지하고, 사람이 복구한다
- 트래픽이 튀면 새 서버를 프로비저닝하고, 배포하고, 로드밸런서에 연결한다
- 배포할 때마다 서버 목록을 훑으며 하나씩 업데이트한다
- 설정 파일이 서버마다 미묘하게 달라서 장애 원인을 찾는 게 고고학이 된다
컨테이너는 이 중 배포 포장 문제를 풀어줬다. 이미지 하나만 있으면 어디서든 똑같이 실행된다. 하지만 “서버가 죽으면 자동으로 복구”와 “트래픽에 맞춰 자동으로 확장”은 컨테이너 자체가 해주는 일이 아니다. 컨테이너를 여러 대의 물리/가상 서버 위에 뿌려놓고, 죽으면 살리고, 필요한 만큼 복제하고, 트래픽을 분산시키는 별도의 시스템이 필요하다.
이 역할을 하는 시스템을 컨테이너 오케스트레이터라고 부른다. Docker Swarm, Nomad, Mesos 같은 도구도 있지만, 2025년 기준으로 사실상의 표준이 된 건 Kubernetes다.
Kubernetes의 기원
Kubernetes는 구글이 2014년에 오픈소스로 공개한 프로젝트다. 원래 구글은 내부적으로 Borg라는 클러스터 관리 시스템을 10년 넘게 써왔는데, 그걸 바깥 세상에도 쓸 수 있게 다시 만든 게 Kubernetes다. 이름은 그리스어로 “조타수(keel holder)“라는 뜻이다. 컨테이너라는 배들을 모아서 한 방향으로 몰고 가는 역할을 한다는 비유가 들어 있다.
현재는 CNCF(Cloud Native Computing Foundation)에서 관리하고 있고, 클라우드 네이티브 생태계의 가장 핵심적인 프로젝트로 자리잡았다. AWS EKS, Google GKE, Azure AKS처럼 주요 클라우드 벤더가 모두 관리형 Kubernetes 서비스를 제공하고 있기도 하다.
짧게 말하면 이렇다. Kubernetes는 컨테이너를 대규모로, 안정적으로, 자동화된 방식으로 운영하기 위한 플랫폼이다.
Kubernetes가 대신 해주는 일
운영자가 손으로 하던 일을 Kubernetes가 대신 처리한다. 대표적으로 이런 것들이다.
- 자가 치유(Self-healing): 컨테이너가 죽으면 새로 띄운다. 노드가 다운되면 다른 노드로 컨테이너를 옮긴다
- 수평 확장(Scaling): CPU 사용률이 높아지면 복제본을 늘리고, 한가해지면 줄인다
- 로드 밸런싱: 같은 서비스의 여러 복제본에 트래픽을 분산한다
- 롤링 업데이트: 새 버전 배포 시 기존 버전을 조금씩 교체해서 무중단 배포를 만든다
- 선언적 구성: “이런 상태여야 한다”를 YAML로 기술하면, Kubernetes가 그 상태를 유지하려고 노력한다
- 서비스 디스커버리: 컨테이너들이 서로를 이름으로 찾을 수 있게 DNS를 자동으로 구성한다
- 스토리지 관리: 영구 볼륨을 마운트하고, 파드가 이동해도 데이터가 따라가도록 관리한다
이 리스트에서 가장 본질적인 건 선언적 구성이다. 다른 기능들은 전부 이 철학에서 파생된다.
명령형 vs 선언형
Kubernetes를 처음 만지면 가장 낯선 게 이 개념이다. 예전에는 “A 서버에 nginx를 설치하라, B 서버에 애플리케이션을 배포하라”처럼 명령을 순서대로 내렸다. 이게 명령형(imperative) 방식이다.
Kubernetes는 다르게 동작한다. 우리는 “이런 상태여야 한다”라고 기술할 뿐이고, 그 상태를 만드는 방법은 Kubernetes가 알아서 찾는다. 이걸 선언형(declarative) 방식이라고 부른다.
# nginx를 3개 복제본으로 운영하고 싶다는 선언
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
이 YAML이 말하는 건 “nginx 1.25 버전을 3개 띄워놓아라”다. 처음 적용할 때 컨테이너가 없으면 3개를 만들고, 이미 2개가 있으면 하나만 추가한다. 하나가 죽으면 3개를 유지하기 위해 새로 띄운다. 우리가 시키지 않아도 Kubernetes가 알아서 한다.
이 발상은 인프라 운영의 패러다임을 바꿨다. 운영자는 “어떻게 할지”를 고민하는 대신 “어떤 상태여야 하는지”만 기술하면 된다.
기본 아키텍처 한눈에 보기
Kubernetes 클러스터는 크게 두 부분으로 나뉜다. Control Plane(제어부)과 Worker Nodes(작업부)다.
flowchart TB
subgraph CP[Control Plane]
API[API Server]
ETCD[(etcd)]
SCH[Scheduler]
CM[Controller Manager]
end
subgraph W1[Worker Node 1]
K1[kubelet]
KP1[kube-proxy]
P1[Pods]
end
subgraph W2[Worker Node 2]
K2[kubelet]
KP2[kube-proxy]
P2[Pods]
end
USER[사용자 / kubectl] -->|API 요청| API
API <--> ETCD
SCH --> API
CM --> API
API <--> K1
API <--> K2
Control Plane은 클러스터의 두뇌다. 어떤 컨테이너를 어디에 띄울지 결정하고, 클러스터 상태를 저장하고, 사용자의 요청을 받아 처리한다. Worker Node는 실제로 컨테이너가 돌아가는 서버다. Control Plane이 “이 컨테이너를 너한테 배정했다”라고 하면, Worker Node의 kubelet이 그 명령을 실행한다.
사용자는 kubectl 명령어로 API Server에 “이런 상태로 만들어줘”라고 요청한다. API Server는 그 요청을 etcd에 저장하고, 각 컴포넌트가 그 상태를 읽어와 필요한 일을 한다. Scheduler는 새 파드를 어느 Worker에 배치할지 결정하고, Controller Manager는 “현재 상태가 선언된 상태와 다르다”면 맞추려고 움직인다.
이 구조가 머릿속에 어렴풋이 그려진다면 충분하다. 구체적인 컴포넌트 동작은 2편에서 자세히 파헤친다.
파드, 노드, 클러스터
Kubernetes를 배울 때 가장 먼저 익혀야 할 세 단어가 있다.
- 파드(Pod): 컨테이너를 담는 가장 작은 배포 단위. 보통 컨테이너 하나당 파드 하나지만, 밀접한 컨테이너 여러 개를 묶을 수도 있다
- 노드(Node): 파드가 실행되는 물리/가상 서버. Worker Node와 Control Plane Node로 나뉜다
- 클러스터(Cluster): 여러 노드를 묶어서 하나의 논리적 시스템으로 만든 것
비유하자면 이렇다. 클러스터는 아파트 단지, 노드는 각 동, 파드는 각 동에 있는 세대다. 세대가 여러 동에 흩어져 있어도 같은 단지 안에서는 서로를 찾을 수 있다.
왜 파드가 컨테이너보다 한 단계 위인가? 그건 관리 단위의 편의 때문이다. 밀접하게 협력하는 두 컨테이너(예: 메인 앱 + 로그 수집기)는 같은 네트워크 공간과 스토리지를 공유해야 하는데, Kubernetes는 그걸 파드로 묶어서 처리한다. 이 이야기는 3편에서 더 풀어본다.
Kubernetes가 모든 걸 해결하지는 않는다
마지막으로 짚고 갈 것이 있다. Kubernetes는 강력하지만 만능은 아니다.
- 학습 곡선이 가파르다. 며칠 만에 익숙해지는 도구가 아니다
- 작은 프로젝트에 Kubernetes를 쓰는 건 오히려 오버엔지니어링일 수 있다
- 클러스터 자체를 운영하는 비용이 있다. Control Plane도 누군가 관리해야 한다
- 애플리케이션 코드의 버그나 설계 문제는 Kubernetes가 해결해주지 않는다
그럼에도 서비스가 커지고, 여러 팀이 협업하고, 안정성이 중요해지는 순간이 오면 Kubernetes의 가치가 분명해진다. 처음 배울 땐 복잡하지만, 한 번 익숙해지면 다른 방식으로 돌아가기 어려운 도구이기도 하다.
다음 편에서는 클러스터 내부를 해부한다. Control Plane의 각 컴포넌트가 어떻게 연결되는지, Worker Node에서 kubelet이 정확히 무엇을 하는지 들여다본다.



Loading comments...