Kubernetes 핵심 개념 완전 정복: 컨테이너 오케스트레이션의 모든 것
사내 빅데이터 모니터링 플랫폼의 초기 아키텍처는 하둡 에코시스템의 관례대로, 엣지 서버 한 대에 거대한 모놀리식 Spring Boot 서버와 데이터 수집 데몬들을 모두 올리는 방식이었습니다.
클라우드 시대가 도래하면서 고객사들은 점점 “AWS EKS에 Docker 컨테이너로 조각조각 내서 배포해 달라” 는 요구를 던지기 시작했고, R&D 팀은 차세대 버전을 준비하며 인프라 패러다임을 완전히 갈아엎어야 했습니다. 그 중심에 있었던 도구가 Kubernetes(k8s) 입니다.
1. Kubernetes란?
- 이름: 그리스어로 ‘조타수(Helmsman)’. 수많은 컨테이너 화물선을 지휘하는 선장의 역할에서 유래.
- k8s: ‘k’와 ‘s’ 사이의 8글자(‘ubernete’)를 숫자로 대체한 약어.
- 탄생: Google 내부에서 주당 20억 개 이상의 컨테이너를 관리하던 Borg 시스템의 노하우를 오픈소스화하여 CNCF에 기부.
2. 핵심 아키텍처
plaintext
┌─────────────────────────────────────────────┐
│ Control Plane (Master) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ API │ │ etcd │ │Scheduler │ │
│ │ Server │ │(상태 DB) │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────┘
│ kubectl / API 통신
┌──────────┴──────────────────────────────────┐
│ Worker Node 1 │
│ ┌────────────────┐ ┌───────────────────┐ │
│ │ Pod │ │ Pod │ │
│ │ [Container A] │ │ [Container B] │ │
│ └────────────────┘ └───────────────────┘ │
│ kubelet │ kube-proxy │
└─────────────────────────────────────────────┘| 컴포넌트 | 역할 |
|---|---|
| API Server | 모든 kubectl 명령의 진입점. REST API 게이트웨이 |
| etcd | 클러스터 전체 상태를 저장하는 분산 Key-Value DB |
| Scheduler | 새 Pod를 어느 Node에 배치할지 결정 |
| Controller Manager | ReplicaSet, Deployment 등 상태를 지속 감시하고 복원 |
| kubelet | 각 Node에서 Pod 생명주기를 관리하는 에이전트 |
| kube-proxy | Pod 간 네트워크 트래픽 라우팅 |
3. 핵심 리소스 개념
Pod — 배포의 최소 단위
yaml
apiVersion: v1
kind: Pod
metadata:
name: collector-pod
spec:
containers:
- name: collector
image: myregistry/collector:1.0
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"Pod는 1개 이상의 컨테이너를 묶은 단위입니다. 같은 Pod 내 컨테이너는 localhost로 통신하고 스토리지를 공유합니다.
Deployment — 선언적 롤아웃 관리
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-portal
spec:
replicas: 3 # 항상 3개 Pod 유지
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 업데이트 중 최소 2개는 항상 살아있음
maxSurge: 1
selector:
matchLabels:
app: web-portal
template:
spec:
containers:
- name: web
image: myregistry/web:2.0
livenessProbe: # 헬스체크 실패 시 자동 재시작
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10livenessProbe가 실패하면 Kubernetes가 자동으로 해당 Pod를 재시작합니다. 밤샘 배포 스트레스가 사라지는 가장 큰 이유입니다.
Service — 고정 DNS 엔드포인트
Pod의 IP는 재시작마다 바뀌기 때문에 Service가 고정 DNS 이름을 제공합니다.
yaml
apiVersion: v1
kind: Service
metadata:
name: web-portal-svc
spec:
selector:
app: web-portal # 위 Deployment Pod들을 타겟
ports:
- port: 80
targetPort: 8080
type: ClusterIP # 클러스터 내부 통신
# type: LoadBalancer # 외부 노출 (AWS ELB 자동 생성)
# type: NodePort # Node IP + 포트로 외부 노출ConfigMap & Secret — 설정 분리
yaml
# ConfigMap: 평문 설정값
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DATABASE_HOST: "postgres-svc"
LOG_LEVEL: "INFO"
---
# Secret: Base64 인코딩된 민감 정보
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_PASSWORD: cGFzc3dvcmQxMjM= # echo -n "password123" | base64PersistentVolume / PVC — 영구 스토리지
yaml
# PVC: 스토리지 요청
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: collector-data-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: gp2 # AWS EBS SSDPod가 죽어도 데이터는 PVC에 남아있어, 재시작 후 그대로 마운트할 수 있습니다.
4. 실전에서 유용했던 기능 4가지
-
무중단 롤링 업데이트: 새 버전 배포 시 트래픽을 새 Pod로 점진적으로 이동.
livenessProbe실패 시 즉시 롤백 (kubectl rollout undo deployment/web-portal). -
자동 스케일링 (HPA): CPU 사용률이 70%를 넘으면 Pod를 자동으로 늘립니다.
shell
$ kubectl autoscale deployment web-portal --cpu-percent=70 --min=2 --max=10- 네임스페이스 격리: 개발/스테이징/운영 환경을 같은 클러스터에서 논리적으로 분리합니다.
shell
$ kubectl create namespace production
$ kubectl apply -f deployment.yaml -n production- Bin Packing: CPU/RAM 여유가 있는 Node에 컨테이너를 테트리스처럼 배치하여 서버 인프라 비용을 절감합니다.
5. 참고 자료
Last updated on