Docker로 컨테이너를 만들었다.
하나, 둘 정도는 docker run으로 충분하다.
그런데 컨테이너가 수십, 수백 개가 되면
이 모든 것을 수작업으로 하는 건 불가능하다.
컨테이너 오케스트레이션이 필요한 이유이고, 그 사실상 표준이 바로 쿠버네티스다.
1. 쿠버네티스의 이해
쿠버네티스란?
Kubernetes(K8s)는 컨테이너화된 애플리케이션의 배포, 확장, 관리를 자동화하는 오픈소스 컨테이너 오케스트레이션 플랫폼이다. 2014년 Google이 내부 컨테이너 관리 시스템 Borg의 경험을 바탕으로 오픈소스로 공개했고, 현재는 CNCF(Cloud Native Computing Foundation)에서 관리한다.
"K8s"라는 약칭은 K와 s 사이에 8글자가 있어서 붙은 이름이다. 그리스어로 "조타수(helmsman)"라는 뜻이고, Docker 로고가 고래(컨테이너선)인 것과 맥이 닿는다.
Kubernetes의 핵심 기능
| 기능 | 설명 |
|---|---|
| 자동화된 컨테이너 관리 | 배포, 스케일링, 롤아웃, 롤백을 자동 처리 |
| Service Discovery & Load Balancing | DNS 또는 자체 IP로 컨테이너를 노출하고 트래픽 분산 |
| Storage Orchestration | 로컬, 클라우드 스토리지를 자동 마운트 |
| Self-healing | 실패한 컨테이너 재시작, 노드 장애 시 재스케줄링 |
| 선언적 구성 (Declarative Configuration) | 원하는 상태를 YAML로 선언하면 K8s가 현재 상태를 맞춰감 |
마지막 항목이 핵심 철학이다. 명령형(imperative)이 아닌 선언형(declarative)이라는 것. "nginx 3개를 띄워라"가 아니라 "nginx가 항상 3개 떠 있어야 한다"고 선언하면, K8s가 현재 상태를 지속적으로 감시하면서 desired state와 차이가 생기면 자동으로 보정한다. 이를 Reconciliation Loop이라 부른다.
Kubernetes Architecture
K8s 클러스터는 크게 Control Plane(Master)과 Worker Node로 나뉜다.
Control Plane 구성 요소:
| 컴포넌트 | 역할 |
|---|---|
| API Server | 모든 요청의 진입점. kubectl, UI, 내부 컴포넌트 모두 API Server를 통해 통신 |
| Scheduler | 새 Pod을 어떤 Node에 배치할지 결정 |
| Controller Manager | Desired State와 Current State를 비교하여 보정하는 컨트롤러들의 집합 |
| etcd | 클러스터의 모든 상태 정보를 저장하는 분산 Key-Value Store |
Worker Node 구성 요소:
| 컴포넌트 | 역할 |
|---|---|
| kubelet | 각 Node에서 실행되며, API Server의 지시에 따라 Pod을 관리 |
| kube-proxy | 네트워크 규칙을 관리하고 Service의 로드밸런싱을 처리 |
| Container Runtime | 실제 컨테이너를 실행 (containerd, CRI-O 등) |
참고로 K8s 1.24부터 Docker를 Container Runtime으로 직접 지원하지 않는다. Docker가 만든 이미지는 OCI 표준이라 그대로 쓸 수 있지만, 런타임은 containerd나 CRI-O를 사용한다. Docker Desktop 내부에서도 실제로는 containerd가 동작하므로 실무적 영향은 거의 없다.
주요 배포판
K8s를 사용하는 방식은 크게 셀프 호스팅과 관리형(Managed) 서비스로 나뉜다.
| 배포판 | 유형 | 특징 |
|---|---|---|
| Vanilla Kubernetes | 셀프 호스팅 | CNCF 공식. 모든 배포판의 기준. 직접 구축·운영 |
| Red Hat OpenShift | 엔터프라이즈 | K8s + CI/CD + Operator + RHEL 기반. 엔터프라이즈 지원 |
| Rancher | 멀티 클러스터 관리 | 온프레미스/클라우드 모두 지원, 멀티 클러스터 관리에 강점 |
| Amazon EKS | Managed (AWS) | AWS 인프라(IAM, ALB, EBS 등)와 긴밀한 통합 |
| Google GKE | Managed (GCP) | K8s 창시자 Google의 서비스. Autopilot 모드 제공 |
| Microsoft AKS | Managed (Azure) | Azure Active Directory, Azure Monitor 등과 통합 |
실무에서 선택 기준은 단순하다. 이미 사용 중인 클라우드가 있으면 해당 벤더의 Managed K8s를 쓴다. 멀티 클라우드 전략이 필요하면 Rancher나 OpenShift를 고려한다. Managed 서비스는 Control Plane을 벤더가 관리해주므로 운영 부담이 크게 줄어든다.
Minikube
Minikube는 로컬 머신에서 단일 노드 K8s 클러스터를 실행할 수 있는 경량 도구다.
| 특징 | 설명 |
|---|---|
| 단일 노드 | Master + Worker가 하나의 VM/컨테이너 안에 동작 |
| 크로스 플랫폼 | Linux, macOS, Windows 모두 지원 |
| K8s 기능 지원 | DNS, NodePorts, ConfigMaps, Secrets, Dashboard, Ingress 등 |
| 용도 | 개발, 테스트, 학습 전용. 프로덕션 불가 |
프로덕션에서는 절대 Minikube를 쓰지 않는다. 로컬 개발 환경에서 K8s manifest를 검증하거나, CI 파이프라인에서 통합 테스트를 돌릴 때 유용하다. 비슷한 도구로 kind(Kubernetes IN Docker), k3s(경량 K8s) 등이 있다.
2. 쿠버네티스의 설치와 활용
YAML — K8s의 공용어
K8s에서 모든 리소스는 YAML로 정의한다. YAML은 데이터 직렬화 포맷 중 하나로, JSON이나 XML보다 가독성이 좋다. 들여쓰기로 계층 구조를 표현하며, 탭이 아닌 스페이스만 허용한다는 점을 주의해야 한다.
K8s YAML의 기본 구조는 네 가지 필수 필드로 구성된다:
apiVersion: v1 # API 버전
kind: Pod # 리소스 종류
metadata: # 이름, 레이블 등 메타 정보
name: example
spec: # 리소스의 Desired State
containers:
- name: busybox
image: busybox:1.25
| 필드 | 설명 |
|---|---|
apiVersion |
리소스의 API 버전. Pod은 v1, Deployment는 apps/v1 |
kind |
리소스 타입. Pod, Deployment, Service, PVC 등 |
metadata |
리소스를 식별하는 정보. name, namespace, labels |
spec |
원하는 상태(Desired State)를 기술하는 본문 |
Pod — K8s의 최소 배포 단위
Pod은 K8s에서 생성하고 관리할 수 있는 가장 작은 컴퓨팅 단위다. Docker에서는 Container가 최소 단위지만, K8s에서는 Pod이다.
Pod의 핵심 특성:
- 하나의 Pod은 1개 이상의 Container를 포함할 수 있다
- 같은 Pod 내 Container들은 네트워크(IP, Port)와 스토리지를 공유한다
- K8s는 Pod 단위로 스케줄링, 로드밸런싱, 스케일링을 수행한다
Cluster
├── Node
│ ├── Pod (Container 1, Container 2) ← 같은 IP 공유
│ └── Pod (Container 1)
└── Node
├── Pod (Container 1)
└── Pod (Container 1, Container 2)
실무에서는 Pod 하나에 Container 하나를 넣는 것이 일반적이다. 멀티 컨테이너 Pod은 사이드카 패턴(로그 수집, 프록시 등)에서 사용한다.
Pod YAML 예시:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c, 'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
3. 쿠버네티스 명령어의 이해
Deployment — Pod의 관리자
실무에서 Pod을 직접 생성하는 경우는 거의 없다. 대신 Deployment를 통해 Pod을 관리한다.
Deployment는 Pod과 ReplicaSet에 대한 관리를 제공하는 상위 리소스다. 제공하는 핵심 기능:
| 기능 | 설명 |
|---|---|
| Self-healing | Pod이 죽으면 자동으로 새 Pod을 생성 |
| Scaling | replicas 수를 변경하여 수평 확장/축소 |
| Rollout | 새 이미지 버전으로 무중단 업데이트 (Rolling Update) |
| Rollback | 문제 발생 시 이전 버전으로 즉시 복원 |
Deployment YAML 예시:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # Pod 3개 유지
selector:
matchLabels:
app: nginx # 이 label을 가진 Pod을 관리 대상으로 지정
template: # Pod 템플릿
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
spec.replicas: 3으로 선언하면 K8s는 항상 nginx Pod 3개를 유지한다. 하나가 죽으면 자동으로 새로 띄우고, image를 변경하면 Rolling Update로 무중단 배포를 수행한다.
Service — Pod에 대한 안정적 접근점
Pod은 생성될 때마다 새 IP를 할당받는다. Pod이 죽었다가 다시 살아나면 IP가 바뀐다. 따라서 Pod의 IP를 직접 사용해서는 안 된다.
Service는 이 문제를 해결하는 리소스다. 고정된 IP(Cluster IP)와 DNS 이름을 제공하며, 매칭되는 Pod들에게 트래픽을 분산한다.
Service Type:
| Type | 설명 | 접근 범위 |
|---|---|---|
| ClusterIP | 클러스터 내부에서만 접근 가능한 가상 IP 할당 (기본값) | 클러스터 내부 |
| NodePort | 모든 Node의 특정 포트(30000-32767)로 외부 노출 | 외부 접근 가능 |
| LoadBalancer | 클라우드 벤더의 LB를 프로비저닝하여 외부 노출 | 외부 접근 가능 |
| ExternalName | 외부 DNS를 CNAME으로 매핑 | 외부 서비스 참조 |
Service YAML 예시:
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
selector: # label이 app: nginx인 Pod과 매칭
app: nginx
포트의 흐름을 정리하면: 외부 → NodePort(30000+) → Service Port(80) → Pod의 ContainerPort(80). 클라우드 환경에서는 NodePort 대신 LoadBalancer 타입을 쓰는 것이 일반적이고, 실제 프로덕션에서는 Ingress Controller를 앞단에 두어 L7 라우팅(도메인/경로 기반)을 처리한다.
PV / PVC — 영구 스토리지
Pod은 본질적으로 stateless하다. Pod이 죽으면 내부 데이터도 사라진다. DB, 파일 업로드 등 영구 보존이 필요한 데이터는 Persistent Volume(PV)과 Persistent Volume Claim(PVC)을 사용해야 한다.
Docker의 -v 볼륨 마운트와 개념은 같지만, K8s는 관리자와 사용자의 역할을 분리한다:
| 리소스 | 역할 | 비유 |
|---|---|---|
| PV (Persistent Volume) | 실제 스토리지의 정보. 관리자가 프로비저닝 | 창고의 실제 공간 |
| PVC (Persistent Volume Claim) | 사용자가 요청하는 스토리지 스펙 | 공간 사용 신청서 |
| StorageClass | PV를 동적으로 생성하기 위한 템플릿 | 자동 창고 배정 규칙 |
PVC YAML 예시:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteMany # ReadWriteOnce: 단일 노드, ReadWriteMany: 다중 노드
volumeMode: Filesystem
resources:
requests:
storage: 10Mi
storageClassName: standard
실무에서는 PV를 수동으로 생성하기보다, StorageClass + 동적 프로비저닝을 사용한다. PVC를 생성하면 StorageClass가 자동으로 PV를 만들어주는 방식이다. AWS EBS, Azure Disk, GCE Persistent Disk 등이 대표적인 동적 프로비저닝 백엔드다.
실습 진행
쿠버네티스를 사용해보자
우선 지난시간에 사용한 VM의 크기(사양)를 늘려야한다








이번엔 Deployment를 실습해보자

Deployment를 활용하면 선언형태로 실행되기때문에 pod가 종료된다면 즉시 재실행하게되어 3개의 실행상태를 유지한다.


정리
이번 주에는 컨테이너 오케스트레이션의 표준인 Kubernetes를 다뤘다.
- Kubernetes: 컨테이너의 배포, 확장, 관리를 자동화하는 플랫폼. 선언적 구성(Desired State)이 핵심 철학이다
- Architecture: Control Plane(API Server, Scheduler, Controller Manager, etcd) + Worker Node(kubelet, kube-proxy, Container Runtime)
- 배포판: 클라우드 벤더의 Managed 서비스(EKS, GKE, AKS)가 운영 부담이 가장 적다. 로컬 개발에는 Minikube, kind, k3s를 사용한다
- Pod: K8s의 최소 배포 단위. 1개 이상의 Container를 포함하며 네트워크/스토리지를 공유한다
- Deployment: Pod의 복제, Self-healing, Rolling Update를 관리하는 상위 리소스. 실무에서 Pod을 직접 만들지 않고 Deployment를 사용한다
- Service: Pod에 대한 안정적 접근점. ClusterIP, NodePort, LoadBalancer 타입으로 내부/외부 트래픽을 라우팅한다
- PV/PVC: Pod의 stateless 한계를 보완하는 영구 스토리지 리소스. StorageClass를 통한 동적 프로비저닝이 일반적이다
다음 시간에는 클라우드 환경에서의 Kubernetes 활용, 즉 Managed Kubernetes Service에 대해 알아본다.
'개인공부' 카테고리의 다른 글
| [Microsoft Azure] 11. AI 앱의 개발과 활용 - Azure AI 서비스 (0) | 2026.06.09 |
|---|---|
| [Microsoft Azure] 10. 컨테이너 기술의 활용 - 클라우드 쿠버네티스 (0) | 2026.06.03 |
| [Microsoft Azure] 8. 컨테이너 기술의 이해 - 도커 (0) | 2026.06.03 |
| [Microsoft Azure] 7. 서버리스 서비스의 이해 (0) | 2026.05.19 |
| [Microsoft Azure] 6. 클라우드 웹 서비스 플랫폼 (2) (0) | 2026.04.21 |