[Container] Kubernetes
Kubernetes
컨테이너가 수십, 수백 개로 늘어난 순간부터 필요해지는 것들. 개념과 왜 쓰는지부터 아키텍처, 핵심 리소스, 네트워킹, 자동 복구까지.
| Category | Level | Reads | Status |
|---|---|---|---|
| Cloud Computing · Kubernetes | 중급 | 약 14분 | VERIFIED |
Kubernetes(K8s)란?
Kubernetes는 수많은 컨테이너를 여러 서버에 걸쳐 자동으로 배치, 확장, 복구, 관리해주는 컨테이너 오케스트레이션 플랫폼이다.
이름은 그리스어로 "조타수(배를 조종하는 사람)"에서 왔고, 흔히 K8s라고 줄여 쓴다(K와 s 사이에 8글자가 있어서). Docker가 "컨테이너 하나를 어떻게 규격화해서 실행할까"를 다룬다면, Kubernetes는 "그 컨테이너 수백 개를 어떻게 안 죽고 잘 돌아가게 운영할까"를 다룬다.
왜 Kubernetes가 필요한가
컨테이너 한두 개면 docker run으로 충분하다. 하지만 서비스가 커지면 아래 같은 질문들이 생긴다 — 이걸 사람이 수동으로 감당하긴 어렵다.
새벽에 컨테이너 하나가 죽었다고 사람이 직접 재시작해야 할까? Kubernetes는 죽은 컨테이너를 자동으로 재시작한다(Self-healing).
사람이 그때그때 컨테이너를 늘렸다 줄였다 해야 할까? Kubernetes는 지표를 보고 자동으로 늘리고 줄인다(Auto-scaling).
새 버전을 배포하는 동안 서비스가 잠깐이라도 멈추면 안 된다면? Kubernetes는 하나씩 순차 교체하며 무중단 배포한다(Rolling Update).
컨테이너를 어느 서버에 올릴지 사람이 일일이 정해야 할까? Kubernetes는 자원 상황을 보고 알아서 적절한 서버에 배치한다(Scheduling).
클러스터 아키텍처
Kubernetes는 여러 서버를 하나의 클러스터(Cluster)로 묶어서 관리한다. 클러스터는 크게 두 종류의 서버로 나뉜다.
API Server가 모든 요청의 관문 역할을 하고, etcd가 클러스터의 모든 상태를 저장하며, Scheduler가 Pod를 어느 노드에 배치할지 결정하고, Controller Manager가 "지금 상태 = 원하는 상태"가 되도록 계속 감시·조정한다.
실제로 컨테이너(Pod)가 돌아가는 서버. Kubelet이 그 노드의 Pod들을 관리하고, kube-proxy가 네트워크 트래픽을 알맞은 Pod로 전달한다.
핵심 리소스 — Pod부터 Service까지
Kubernetes는 "이런 상태가 되어야 한다"를 선언하면 그 상태를 계속 유지해주는 방식으로 동작한다. 그 선언의 단위가 되는 리소스들이 아래처럼 계층을 이룬다.
Kubernetes에서 배포할 수 있는 가장 작은 단위. 보통 컨테이너 1개(때로는 긴밀하게 묶인 여러 개)를 감싼 껍데기다.
"똑같은 Pod를 항상 N개 유지해라"를 담당한다. Pod가 죽으면 즉시 새 Pod를 만들어 개수를 채운다.
ReplicaSet을 관리하는 상위 리소스. 새 버전 배포, 롤백, 무중단 업데이트를 이 레벨에서 다룬다. 실무에서 Pod를 직접 만들기보다 거의 항상 Deployment를 통해 다룬다.
Pod는 재시작될 때마다 IP가 바뀐다. Service는 고정된 주소를 제공하고, label을 기준으로 실제 살아있는 Pod들에게 트래픽을 나눠준다.
// 실무에서 자주 보는 Deployment 정의 (일부) apiVersion: apps/v1 kind: Deployment spec: replicas: 3 # 항상 3개를 유지 selector: matchLabels: app: my-api # 이 label을 가진 Pod를 관리
네트워킹 — 외부에서 어떻게 들어오나
클러스터 밖에서 안의 Pod로 트래픽을 보내는 방법은 여러 단계가 있다. 규모가 커질수록 아래 순서로 쓰는 경우가 많다.
| 방식 | 설명 | 주로 쓰는 경우 |
|---|---|---|
| ClusterIP | 클러스터 내부에서만 접근 가능한 기본 Service | 내부 서비스 간 통신 (외부 노출 X) |
| NodePort | 각 노드의 특정 포트를 열어 외부에서 접근 가능하게 함 | 개발·테스트 단계의 간단한 외부 노출 |
| LoadBalancer | 클라우드(AWS 등)의 로드밸런서를 자동으로 생성해 연결 | 운영 환경에서 외부 트래픽을 안정적으로 받을 때 |
| Ingress | 도메인·경로 기준으로 여러 Service를 하나의 진입점으로 라우팅 | 여러 서비스를 하나의 도메인/로드밸런서로 묶을 때 |
자동 복구와 스케일링
Pod가 죽거나 응답이 없으면 Controller Manager가 감지해 즉시 새 Pod로 교체한다. 사람이 야간에 깨어나 재시작할 필요가 없다.
Horizontal Pod Autoscaler. CPU·메모리 사용률 같은 지표를 보고 Pod 개수를 자동으로 늘리거나 줄인다.
새 버전 Pod를 하나씩 띄우고 기존 Pod를 하나씩 내리는 방식으로, 서비스 중단 없이 배포한다. Deployment의 기본 배포 전략이다.
Kubernetes의 장단점
- 장애 발생 시 자동으로 복구(Self-healing)
- 트래픽에 맞춰 자동으로 확장·축소
- 무중단 배포와 손쉬운 롤백
- 클라우드 벤더에 크게 종속되지 않는 표준 플랫폼
- 학습 곡선이 가파름 — 개념과 YAML이 많음
- 운영 복잡도 자체가 하나의 비용(클러스터를 관리해야 함)
- 소규모 서비스에는 과한 인프라일 수 있음
- 디버깅이 여러 계층(Pod·Node·Network)에 걸쳐 있어 까다로움
언제 써야 할까
트래픽이 작고 안정적인 소규모 서비스, 컨테이너 몇 개 수준, 팀에 운영 인력이 많지 않은 초기 스타트업.
여러 서버에 걸친 다수의 컨테이너 운영, 트래픽 변동이 크고 자동 확장이 중요한 경우, 무중단 배포·자동 복구가 필수인 프로덕션 서비스.
참고로 AWS 환경이라면 직접 클러스터를 관리하는 대신 EKS(Elastic Kubernetes Service)처럼 Control Plane을 관리해주는 서비스를 쓰는 경우가 많다. 어떤 서비스인지는 다음 섹션에서 자세히 본다.
EKS(Elastic Kubernetes Service)란?
지금까지 본 Control Plane(API Server, etcd, Scheduler, Controller Manager)을 직접 서버에 설치해서 운영하려면, 고가용성 구성·버전 업그레이드·보안 패치·백업까지 전부 사람이 해야 한다. EKS는 이 Control Plane을 AWS가 대신 관리해주는 완전관리형 Kubernetes 서비스다.
Worker Node를 만드는 3가지 방법
EC2 인스턴스를 직접 만들어 클러스터에 연결한다. 가장 세밀하게 제어할 수 있지만 OS 패치·오토스케일링 설정도 직접 해야 한다.
EC2 인스턴스이긴 하지만, 프로비저닝·업그레이드·정상 종료까지 AWS가 자동화해준다. 실무에서 가장 많이 쓰는 방식.
노드(서버) 자체가 없다. Pod 단위로 서버리스처럼 실행되어 노드 관리가 아예 필요 없지만, 세밀한 서버 설정은 포기해야 한다.
- Control Plane 운영 부담이 완전히 사라짐
- Multi-AZ 기반 고가용성이 기본 제공됨
- IAM, VPC, ALB 등 AWS 서비스와 통합이 쉬움
- Fargate를 쓰면 Worker Node 관리도 없앨 수 있음
- Control Plane 자체에 시간당 비용이 별도로 발생
- AWS 생태계에 종속되어 다른 클라우드로 이전이 번거로움
- 최신 Kubernetes 버전 지원이 오픈소스보다 다소 늦게 반영될 수 있음