데브옵스 · 인프라 엔지니어를 위한 핵심 요약
Kubernetes(쿠버네티스, K8s)는 컨테이너화된 애플리케이션의 배포, 스케일링, 관리를 자동화하는 오픈소스 플랫폼입니다. Google의 Borg 시스템에서 기원했으며, 현재 CNCF(Cloud Native Computing Foundation)의 주력 프로젝트입니다.
서비스 디스커버리, 로드 밸런싱, 스토리지 오케스트레이션, 자동화된 롤아웃/롤백, 자동 복구(셀프 힐링) 등을 제공합니다.
물리적/가상 머신, 퍼블릭/프라이빗 클라우드 등 하부 인프라를 추상화하여 애플리케이션 중심의 운영을 가능하게 합니다.
YAML/JSON 매니페스트 파일을 통해 원하는 시스템 상태(Desired State)를 선언하면 K8s가 현재 상태를 그에 맞추어 조정합니다.
기존의 배포 및 관리 방식과 비교했을 때 Kubernetes가 제공하는 주요 이점을 살펴봅니다.
| 기준 | 전통적 방식 (수동/Virtual Machines) | Kubernetes |
|---|---|---|
| 배포 속도 | 수동 프로비저닝, 구성 관리 도구 필요, 느림 | 컨테이너 기반, 선언적 구성, 초 단위 배포 |
| 리소스 효율 | VM 당 OS 오버헤드, 리소스 과할당 일반적 | 컨테이너 공유, 높은 밀도 패킹, 효율적 활용 |
| 확장성 | 수동 스케일링 또는 복잡한 자동화 스크립트 필요 | HPA(Horizontal Pod Autoscaler)를 통한 자동 수평 확장 |
| 가용성 | 장애 시 수동 개입 필요, 복구 시간 길음 | 자동 복구, 롤링 업데이트, 레플리카셋으로 고가용성 보장 |
| 이식성 | 환경 간 차이로 인한 "내 컴퓨터에서는 되는데" 문제 | 컨테이너 표준으로 인한 하이브리드/멀티 클라우드 이식성 |
Kubernetes 클러스터의 기본 아키텍처와 핵심 객체(Object)들을 이해합니다.
로컬 개발 환경(minikube)에서 Kubernetes를 빠르게 시작하는 방법입니다.
# Minikube 설치 (macOS, Homebrew)
brew install minikube
# 클러스터 시작 (가상 드라이버 사용)
minikube start --driver=virtualbox
# 클러스터 상태 확인
minikube status
kubectl cluster-info
다음과 같은 간단한 Flask 앱을 배포해봅니다.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello from Kubernetes!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: python-flask-app
spec:
replicas: 3
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask-container
image: myregistry/flask-app:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: flask-service
spec:
selector:
app: flask-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
# 매니페스트 적용
kubectl apply -f deployment.yaml
# 배포 상태 확인
kubectl get deployments
kubectl get pods
kubectl get services
# Pod 로그 확인
kubectl logs -l app=flask-app --tail=10
# 서비스 접근 (minikube)
minikube service flask-service
자주 사용되는 Kubernetes 리소스의 주요 필드와 설정값입니다.
| 리소스 | 주요 필드 | 설명 및 예시 값 |
|---|---|---|
| Pod | spec.containers[].image spec.containers[].ports spec.containers[].resources |
컨테이너 이미지, 노출 포트, CPU/Memory 요청/제한 |
| Deployment | spec.replicas spec.strategy.type spec.template |
Pod 복제본 수 (기본 1), RollingUpdate/Recreate, Pod 템플릿 |
| Service | spec.type spec.ports spec.selector |
ClusterIP, NodePort, LoadBalancer, ExternalName |
| ConfigMap | data (key-value) binaryData |
환경 변수, 구성 파일 내용, 바이너리 데이터 |
| Ingress | spec.rules[].host spec.rules[].http.paths spec.tls |
호스트 기반 라우팅, 경로 매핑, TLS 인증서 설정 |
| PersistentVolumeClaim | spec.resources.requests.storage spec.accessModes spec.storageClassName |
요청 스토리지 크기 (e.g., 10Gi), ReadWriteOnce, 스토리지 클래스 |
Pod에 resources.requests와 resources.limits를 명시하지 않으면 노드의 리소스가 고갈되거나 Pod가 OOM Kill될 수 있습니다. 항상 설정하세요.
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
증상: Pod가 ImagePullBackOff 상태로 멈춤.
원인: 이미지 이름 오타, 프라이빗 레지스트리 인증 문제, 네트워크 문제.
해결:
# 이미지 이름 확인
kubectl describe pod <pod-name>
# 프라이빗 레지스트리 인증 설정
kubectl create secret docker-registry my-registry-key \
--docker-server=<registry-url> \
--docker-username=<user> \
--docker-password=<pass>
# Pod의 imagePullSecrets에 secret 참조 추가
증상: Pod가 반복적으로 시작되고 종료됨.
원인: 애플리케이션 충돌, 잘못된 구성, 의존성 서비스 연결 실패.
해결:
# Pod 로그 확인 (가장 중요한 첫 단계)
kubectl logs <pod-name> --previous # 이전 컨테이너 로그
kubectl logs <pod-name> -f # 실시간 로그
# Pod 상세 정보 확인
kubectl describe pod <pod-name>
# 애플리케이션의 liveness/readiness Probe 설정 확인
# 초기 지연(startupProbe)이나 타임아웃 설정을 조정
개발/스테이징/프로덕션 환경을 네임스페이스로 분리하면 리소스 관리와 권한 제어가 용이합니다.
# 네임스페이스 생성
kubectl create namespace staging
kubectl create namespace production
# 특정 네임스페이스에 리소스 배포
kubectl apply -f deployment.yaml -n staging
# 네임스페이스 별 컨텍스트 설정 (kubectx 권장)