⎈ Kubernetes 기초
컨테이너화된 애플리케이션의 자동 배포, 스케일링 및 관리를 위한 오케스트레이션 플랫폼 Kubernetes의 핵심을 배웁니다.
⎈⎈ Kubernetes란 무엇인가?
정의
Kubernetes(쿠버네티스, K8s)는 컨테이너화된 애플리케이션의 배포, 스케일링 및 관리를 자동화하는 오픈소스 컨테이너 오케스트레이션 플랫폼입니다.
💡 K8s의 의미
Kubernetes를 K8s로 줄여 쓰는 이유는 'K'와 's' 사이에 8개의 문자가 있기 때문입니다.
주요 기능
🔄 자동화된 배포와 롤백
애플리케이션 배포를 자동화하고, 문제 발생 시 이전 버전으로 즉시 롤백
📊 자동 스케일링
CPU, RAM 또는 커스텀 메트릭 기반으로 자동 확장/축소
🏥 자가 치유
실행에 실패한 컨테이너를 자동으로 재시작하고 교체
⚖️ 로드 밸런싱
트래픽을 여러 컨테이너에 분산하여 안정적인 서비스 제공
💡 핵심 컴포넌트 (직접구현할 경우)
Control Plane (마스터 노드)
- API Server: 모든 요청의 진입점, kubectl과 통신하는 인터페이스
- etcd: 클러스터의 모든 데이터를 저장하는 분산 키-값 저장소
- Scheduler: 새로운 Pod를 어느 노드에 배치할지 결정
- Controller Manager: 클러스터 상태를 관리하고 원하는 상태로 유지
Worker Nodes (워커 노드)
- Kubelet: 각 노드에서 실행되며 Pod와 컨테이너 관리
- Kube-proxy: 네트워크 규칙 관리 및 Pod 간 통신 지원
- Container Runtime: 실제 컨테이너 실행 (Docker, containerd, CRI-O 등)
⎈왜 Kubernetes가 필요한가?
전통적인 배포 방식의 한계
과거에는 물리 서버에 애플리케이션을 직접 설치했습니다. 이는 리소스 할당 문제를 야기했고, 하나의 애플리케이션이 전체 서버 리소스를 독점할 수 있었습니다.
컨테이너의 등장과 한계
Docker와 같은 컨테이너 기술은 가볍고 이식성이 뛰어난 솔루션을 제공했지만, 프로덕션 환경에서 수백, 수천 개의 컨테이너를 관리하려면 오케스트레이션 도구가 필요했습니다.
Kubernetes가 해결하는 문제들
📦 대규모 컨테이너 관리
수백 개의 컨테이너를 자동화된 방식으로 관리
🌐 고가용성
애플리케이션이 항상 실행되도록 보장하고 자동 복구
🔄 무중단 배포
서비스 중단 없이 새 버전 배포 (Rolling Update)
💰 리소스 효율성
서버 리소스를 최적으로 활용하여 비용 절감
🌍 멀티 클라우드
AWS, GCP, Azure 등 어떤 환경에서도 동일하게 작동
📈 쉬운 확장
트래픽 증가에 따라 애플리케이션을 쉽게 확장
⚠️ 주의사항
Kubernetes는 강력하지만 복잡합니다. 소규모 프로젝트나 간단한 애플리케이션의 경우, Docker Compose나 다른 경량 솔루션이 더 적합할 수 있습니다.
⎈Docker와 Kubernetes의 관계
역할의 차이
Docker와 Kubernetes는 함께 사용되지만, 각각 다른 역할을 수행합니다.
| 구분 | Docker | Kubernetes |
|---|---|---|
| 주요 역할 | 컨테이너 생성 및 실행 | 컨테이너 오케스트레이션 |
| 범위 | 단일 호스트 | 클러스터 전체 |
| 자동화 | 제한적 | 완전 자동화 |
| 스케일링 | 수동 | 자동 |
| 복구 | 수동 | 자동 (Self-healing) |
연동 프로세스
- 개발 단계: Dockerfile 작성 및 로컬에서 테스트
- 이미지 저장: Container Registry(Docker Hub, ECR, GCR 등)에 푸시
- Kubernetes 배포: Deployment YAML에서 이미지 경로 지정
- 컨테이너 실행: Kubernetes가 컨테이너 런타임을 통해 실행
💡 Container Runtime Interface (CRI)
Kubernetes는 Docker뿐만 아니라 containerd, CRI-O 등 다양한 컨테이너 런타임을 지원합니다. Docker로 빌드한 이미지는 여전히 사용할 수 있습니다.
⎈💾 Persistent Volume Claim (PVC)
스토리지의 중요성
컨테이너는 기본적으로 상태가 없고(stateless) 임시적입니다. Pod가 재시작되면 컨테이너 내부의 데이터는 모두 사라집니다.
데이터베이스, 로그, 사용자 업로드 파일 등 영구적으로 저장해야 하는 데이터가 있다면 Persistent Volume이 필요합니다.
PV와 PVC의 관계
- PV (Persistent Volume): 클러스터 관리자가 프로비저닝한 실제 스토리지 리소스
- PVC (Persistent Volume Claim): 사용자가 스토리지를 요청하는 것
Access Modes: RWO vs RWX
| 모드 | 전체 이름 | 설명 | 사용 사례 |
|---|---|---|---|
| RWO | ReadWriteOnce | 단일 노드에서만 읽기/쓰기 | 데이터베이스 (MySQL, PostgreSQL) |
| RWX | ReadWriteMany | 여러 노드에서 읽기/쓰기 | 공유 파일 시스템, 로그 수집 |
⚠️ RWO의 제한사항
RWO 볼륨은 한 번에 하나의 노드에만 마운트될 수 있습니다. 같은 노드의 여러 Pod는 공유 가능하지만, 다른 노드의 Pod는 접근할 수 없습니다.
⎈Stateful vs Stateless 애플리케이션
개념의 이해
Kubernetes에서 애플리케이션을 배포할 때 가장 중요한 결정 중 하나는 해당 애플리케이션이 상태를 유지해야 하는지 여부입니다.
| 구분 | Stateless (무상태) | Stateful (상태유지) |
|---|---|---|
| 데이터 저장 | 로컬에 데이터 저장 안함 | 로컬에 데이터 저장 필요 |
| Pod ID | 랜덤 (myapp-7d8f9-xyz) | 고정 (mysql-0, mysql-1) |
| 스케일링 | 쉬움 (언제든 추가/제거) | 복잡 (순서 보장 필요) |
| 복제본 | 모두 동일 | 각각 고유한 상태 |
| 스토리지 | 불필요 또는 공유 | 각 Pod마다 전용 |
| 예시 | 웹 서버, API 서버 | 데이터베이스, 메시지 큐 |
⎈Deployment
정의
Deployment는 Pod의 배포를 관리하는 가장 기본적인 리소스입니다. ReplicaSet을 통해 지정된 수의 Pod 복제본을 유지하고, 롤링 업데이트와 롤백을 지원합니다.
주요 기능
🔄 롤링 업데이트
새 버전을 점진적으로 배포하여 무중단 업데이트
↩️ 롤백
문제 발생 시 이전 버전으로 즉시 복구
📊 복제본 관리
지정된 수의 Pod를 항상 유지
🔧 자동 복구
실패한 Pod를 자동으로 재생성
⎈Service
정의
Service는 Pod 집합에 대한 안정적인 네트워크 엔드포인트를 제공합니다. Pod는 언제든 재생성될 수 있고 IP가 변경되므로, Service를 통해 일관된 접근 방법을 제공해야 합니다.
🔗 Pod 간 통신은 어떻게 할까?
Pod는 생성될 때마다 새로운 IP를 받습니다. 따라서 직접 IP로 통신하면 Pod가 재시작될 때 연결이 끊깁니다. 이 문제를 Service가 해결합니다.
📌 핵심 원리: Label과 Selector
Service는 Label Selector를 사용하여 특정 Label을 가진 Pod들을 자동으로 찾아 트래픽을 전달합니다.
🌐 다른 Pod에서 접근하는 방법
같은 클러스터 내의 다른 Pod는 Service 이름으로 접근할 수 있습니다. Kubernetes가 자동으로 DNS를 생성해줍니다.
Service 타입
| 타입 | 설명 | 사용 사례 |
|---|---|---|
| ClusterIP | 클러스터 내부에서만 접근 가능 (기본값) | 내부 마이크로서비스 간 통신 |
| NodePort | 각 노드의 특정 포트로 외부 접근 가능 | 개발/테스트 환경 |
| LoadBalancer | 클라우드 로드밸런서 자동 생성 | 프로덕션 외부 노출 서비스 |
💡 Service Discovery
Kubernetes는 Service에 대해 자동으로 DNS 레코드를 생성합니다. Pod는 Service 이름만 알면 IP를 몰라도 통신할 수 있습니다.
형식: [서비스명].[네임스페이스].svc.cluster.local
⎈Ingress
정의
Ingress는 클러스터 외부에서 내부 서비스로의 HTTP/HTTPS 라우팅을 관리합니다.
하나의 IP 주소로 여러 서비스를 노출하고, 도메인 기반 라우팅, SSL/TLS 종료, 경로 기반 라우팅 등을 제공합니다.
⚠️ Ingress Controller 필요
Ingress 리소스를 사용하려면 Ingress Controller가 클러스터에 설치되어 있어야 합니다.
주요 Controller: NGINX, Traefik, HAProxy, AWS ALB, GKE Ingress
🔄 요청 흐름 (Request Flow)
사용자의 요청이 어떤 과정을 거쳐 최종 애플리케이션까지 도달하는지 살펴봅니다.
https://myapp.example.com/api 요청
SSL/TLS 처리 · 도메인/경로 기반 라우팅
Service A
frontend · port:80
Service B
api · port:8080
| 단계 | 구성요소 | 역할 |
|---|---|---|
| ① | 사용자 | 도메인으로 HTTPS 요청 전송 |
| ② | Ingress | 도메인/경로 기반으로 적절한 Service로 라우팅 |
| ③ | Service | 로드밸런싱을 통해 건강한 Pod 선택 |
| ④ | Pod | 실제 애플리케이션이 요청 처리 후 응답 |
⎈🔍 kubectl 모니터링 (1)
kubectl은 Kubernetes 클러스터와 상호작용하는 CLI 도구입니다. 여기서는 모니터링과 상태 확인에 집중합니다.
📋 Pod 상태 조회
🔎 Pod 상태 해석
| STATUS | 의미 | 대응 |
|---|---|---|
| Running | 정상 실행 중 | — |
| Pending | 스케줄링 대기 중 | 리소스 부족 또는 노드 확인 |
| CrashLoopBackOff | 반복적으로 실패 후 재시작 | kubectl logs로 원인 확인 |
| ImagePullBackOff | 이미지를 가져올 수 없음 | 이미지 이름/태그/레지스트리 확인 |
| Completed | 작업 완료 (Job 등) | 정상 종료 |
📝 Pod 상세 정보 보기
💡 describe는 장애 진단의 핵심 도구
Pod가 Pending이나 CrashLoopBackOff일 때, describe의 Events 섹션에서 원인을 파악할 수 있습니다.
⎈🔍 kubectl 모니터링 (2)
📜 로그 확인 (logs)
애플리케이션이 출력하는 로그를 확인하여 에러 원인을 진단합니다.
🖥️ Pod 내부 접속 (exec)
실행 중인 Pod 안에 직접 접속하여 디버깅할 수 있습니다.
🩺 장애 진단 체크리스트
Pod가 죽었을 때 확인 순서
kubectl get pods→ STATUS 확인kubectl describe pod [이름]→ Events에서 원인 파악kubectl logs [이름]→ 애플리케이션 에러 확인kubectl logs [이름] --previous→ 크래시 전 로그 확인kubectl exec -it [이름] -- /bin/bash→ 내부 직접 확인
⎈💾 정보 저장 방식: ConfigMap & Secret
Kubernetes에서는 애플리케이션이 사용하는 설정 정보와 민감한 데이터를 별도의 리소스로 분리하여 관리합니다. 코드에 직접 값을 넣지 않고 외부에서 주입하는 방식입니다.
📄 ConfigMap — 일반 설정 데이터 저장
환경 변수, 설정 파일 경로, 로그 레벨 등 민감하지 않은 데이터를 저장합니다.
🔐 Secret — 민감한 데이터 저장
비밀번호, API 키, 토큰 등 외부에 노출되면 안 되는 데이터를 base64 인코딩하여 저장합니다.
📌 Pod에서 사용하는 방법
💡 왜 분리하나요?
- 코드 변경 없이 설정만 변경하여 재배포 가능
- 환경별(dev/staging/prod) 다른 설정을 사용 가능
- Secret은 별도 권한 관리로 보안 강화
📊 참고: HorizontalPodAutoscaler (HPA)
CPU, 메모리 기반으로 Pod 수를 자동으로 조절합니다.
⎈🚨 자주 발생하는 장애 사례 분석
kubectl describe pod에서 자주 만나는 장애 상황과 해결 방법을 알아봅니다.
1️⃣ OOMKilled — 메모리 초과
❌ 증상: Pod가 갑자기 종료됨
원인: 컨테이너가 설정된 memory limits보다 더 많은 메모리를 사용
해결:
resources.limits.memory값을 늘려줌 (예: 512Mi → 1Gi)- 애플리케이션의 메모리 누수(memory leak) 점검
- JVM 기반이면
-Xmx힙 메모리 설정 확인
2️⃣ CrashLoopBackOff — 반복 크래시
❌ 증상: Pod가 계속 재시작됨
원인: 애플리케이션이 시작 직후 에러로 종료 → 재시작 → 또 종료 반복
해결:
kubectl logs [Pod이름] --previous로 크래시 전 로그 확인- 환경변수 누락, DB 연결 실패, 설정 파일 오류 등 확인
- 컨테이너 이미지가 올바른지 확인 (
docker run으로 로컬 테스트)
3️⃣ ImagePullBackOff — 이미지 가져오기 실패
❌ 증상: Pod가 Pending 상태에서 멈춤
원인: 이미지 이름/태그 오타, Private 레지스트리 인증 실패, 이미지 미존재
해결:
- 이미지 이름과 태그가 정확한지 확인
- Private 레지스트리면
imagePullSecrets설정 확인 docker pull [이미지]로 로컬에서 테스트
⎈🎯 Kubernetes 핵심 정리
1. Kubernetes란?
- 컨테이너 오케스트레이션 플랫폼
- 자동화된 배포, 스케일링, 관리
- 고가용성 및 자가 치유
2. 핵심 리소스
Pod
가장 작은 배포 단위, 하나 이상의 컨테이너 그룹
Deployment
Stateless 애플리케이션 배포 및 관리
Service
Pod에 대한 안정적인 네트워크 엔드포인트
Ingress
HTTP/HTTPS 라우팅 및 SSL 종료
PVC
영구 스토리지 관리 (RWO, RWX)
ConfigMap/Secret
설정 및 민감 데이터 관리
3. 베스트 프랙티스
- ✅ 선언적 설정 (YAML 파일을 Git으로 관리)
- ✅ 모든 컨테이너에 리소스 requests/limits 설정
- ✅ Liveness와 Readiness Probe 항상 설정
- ✅ 환경별로 네임스페이스 분리 (dev, staging, prod)
- ✅ 롤링 업데이트 전략 사용
- ✅ Secret은 암호화하여 관리
4. 학습 로드맵
- 기초: Pod, Deployment, Service
- 스토리지: PVC, ConfigMap, Secret
- 네트워킹: Ingress, Network Policy
- 고급: StatefulSet, HPA, RBAC, Helm
🚀 다음 단계
실습 환경을 구축하고 직접 리소스를 배포해보세요!
추천 도구: Minikube, kind, Docker Desktop의 Kubernetes