테크·9 min read
Kubernetes 입문 2026 — 개발자가 알아야 할 쿠버네티스 핵심 개념과 실전
개발자를 위한 Kubernetes(쿠버네티스) 입문 가이드. Pod, Deployment, Service, Ingress 핵심 개념부터 kubectl 명령어, 로컬 개발 환경(minikube/kind), 실전 배포까지 정리했습니다.
Kubernetes — 컨테이너 오케스트레이션의 표준
**Kubernetes(쿠버네티스)**는 컨테이너화된 애플리케이션의 배포, 스케일링, 자가 치유를 자동화하는 오픈소스 플랫폼입니다. Google이 개발하고 CNCF(Cloud Native Computing Foundation)가 관리하며, 현재 대부분의 클라우드 환경에서 표준으로 사용됩니다.
왜 Kubernetes인가?
| 문제 | Kubernetes 해결 방법 |
|---|---|
| 서버 한 대가 죽으면? | 다른 노드에 자동 재스케줄 |
| 트래픽이 갑자기 늘면? | HPA로 자동 수평 스케일링 |
| 새 버전 배포 시 다운타임? | 롤링 업데이트로 무중단 배포 |
| 배포가 잘못됐으면? | 이전 버전으로 즉시 롤백 |
| 환경변수·시크릿 관리? | ConfigMap, Secret으로 코드와 분리 |
핵심 오브젝트 개념
Pod
Kubernetes의 최소 실행 단위. 하나 이상의 컨테이너를 포함합니다.
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 3000
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
실제로 Pod를 직접 생성하는 경우는 드뭅니다. Deployment를 통해 관리합니다.
Deployment — Pod 관리자
원하는 Pod 수를 유지하고, 롤링 업데이트·롤백을 처리합니다.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3 # Pod 3개 유지
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
envFrom:
- secretRef:
name: my-app-secrets # Secret에서 환경변수 로드
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
Service — Pod 접근 방법
Pod는 IP가 변동되므로, Service가 안정적인 접근 포인트를 제공합니다.
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app # 이 라벨의 Pod들에 트래픽 전달
ports:
- port: 80
targetPort: 3000
type: ClusterIP # 클러스터 내부 접근용
| Service 타입 | 접근 범위 | 사용 예 |
|---|---|---|
| ClusterIP | 클러스터 내부 | 마이크로서비스 간 통신 |
| NodePort | 노드 IP + 포트 | 개발 환경 테스트 |
| LoadBalancer | 외부 (클라우드 LB) | 프로덕션 외부 노출 |
Ingress — HTTP 라우팅
여러 Service를 URL 기반으로 라우팅합니다.
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
tls:
- hosts:
- api.example.com
- app.example.com
secretName: tls-secret
ConfigMap & Secret — 설정 분리
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data:
LOG_LEVEL: "info"
API_URL: "https://api.example.com"
---
# secret.yaml (base64 인코딩)
apiVersion: v1
kind: Secret
metadata:
name: my-app-secrets
type: Opaque
data:
DATABASE_URL: cG9zdGdyZXNxbDovLy4uLg== # base64
JWT_SECRET: bXktc2VjcmV0LWtleQ==
# Secret 생성 (base64 자동 인코딩)
kubectl create secret generic my-app-secrets \
--from-literal=DATABASE_URL=postgresql://... \
--from-literal=JWT_SECRET=my-secret
로컬 Kubernetes 환경 구성
minikube (가장 간단)
# 설치 (macOS)
brew install minikube
# 클러스터 시작
minikube start --driver=docker --memory=4096 --cpus=2
# 대시보드 열기
minikube dashboard
# 중지
minikube stop
kind (CI 환경에 적합)
# 설치
brew install kind
# 클러스터 생성
kind create cluster --name my-cluster
# 여러 노드 구성
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
kubectl 핵심 명령어
# 클러스터 정보
kubectl cluster-info
kubectl get nodes
# 오브젝트 조회
kubectl get pods # Pod 목록
kubectl get pods -n kube-system # 네임스페이스 지정
kubectl get deployments
kubectl get services
kubectl get all # 모든 오브젝트
# 상세 정보
kubectl describe pod my-pod-abc123
kubectl describe deployment my-app
# 로그
kubectl logs my-pod-abc123
kubectl logs -f my-pod-abc123 # 실시간 스트리밍
kubectl logs my-pod-abc123 -c container-name # 특정 컨테이너
# Pod 내부 진입
kubectl exec -it my-pod-abc123 -- sh
kubectl exec -it my-pod-abc123 -- bash
# 오브젝트 적용/삭제
kubectl apply -f deployment.yaml # 생성 또는 업데이트
kubectl delete -f deployment.yaml # 삭제
kubectl delete pod my-pod-abc123 # 특정 Pod 삭제
# 스케일링
kubectl scale deployment my-app --replicas=5
# 롤링 업데이트
kubectl set image deployment/my-app app=my-app:1.1.0
# 롤백
kubectl rollout undo deployment/my-app
kubectl rollout history deployment/my-app
kubectl rollout status deployment/my-app
실전 배포 흐름
1. 이미지 빌드 및 레지스트리 푸시
# 이미지 빌드
docker build -t my-app:1.0.0 .
# 레지스트리에 푸시 (Docker Hub 예시)
docker tag my-app:1.0.0 username/my-app:1.0.0
docker push username/my-app:1.0.0
2. YAML 파일로 배포
# 네임스페이스 생성
kubectl create namespace production
# 모든 리소스 한 번에 적용
kubectl apply -f k8s/ -n production
# 배포 상태 확인
kubectl rollout status deployment/my-app -n production
# Pod 상태 확인
kubectl get pods -n production -w # watch 모드
3. 실전 디렉토리 구조
k8s/
├── namespace.yaml
├── configmap.yaml
├── secret.yaml # git에 절대 커밋 금지
├── deployment.yaml
├── service.yaml
├── ingress.yaml
└── hpa.yaml # 오토스케일링
자동 스케일링 (HPA)
CPU 사용량에 따라 자동으로 Pod 수를 조절합니다.
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU 70% 초과 시 스케일업
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
클라우드 관리형 Kubernetes (EKS, GKE, AKS)
직접 클러스터를 운영하지 않고 클라우드에서 관리형으로 사용하면 컨트롤 플레인 관리 부담이 없습니다.
| 서비스 | 클라우드 | 특징 |
|---|---|---|
| EKS | AWS | AWS 서비스 통합 최적화 |
| GKE | GCP | 자동 업그레이드, 가장 성숙 |
| AKS | Azure | Azure DevOps 연동 |
# AWS EKS 클러스터 연결
aws eks update-kubeconfig --region ap-northeast-2 --name my-cluster
# GKE 클러스터 연결
gcloud container clusters get-credentials my-cluster --region asia-northeast3
트러블슈팅
Pod가 Pending 상태일 때
kubectl describe pod <pod-name>
# Events 섹션에서 원인 확인
# 주요 원인: 리소스 부족, 이미지 pull 실패, PVC 마운트 실패
Pod가 CrashLoopBackOff일 때
# 로그 확인 (이전 컨테이너 포함)
kubectl logs <pod-name> --previous
# 컨테이너가 즉시 종료되는 경우
kubectl describe pod <pod-name> # Exit Code 확인
이미지를 pull할 수 없을 때
# 프라이빗 레지스트리 인증 시크릿 생성
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=myuser \
--docker-password=mypassword
# Deployment에 imagePullSecrets 추가
spec:
template:
spec:
imagePullSecrets:
- name: regcred
학습 로드맵
| 단계 | 주제 | 도구/자료 |
|---|---|---|
| 1단계 | 핵심 개념 (Pod, Deployment, Service) | 공식 문서, minikube |
| 2단계 | ConfigMap, Secret, Ingress | 실습 |
| 3단계 | HPA, 롤링 업데이트, 롤백 | 실습 |
| 4단계 | Helm 패키지 매니저 | Helm 공식 문서 |
| 5단계 | 클라우드 관리형 (EKS, GKE) | 클라우드 실습 |
| 6단계 | Monitoring (Prometheus, Grafana) | kube-prometheus-stack |
관련 글: Docker 입문 완전 가이드 · GitHub Actions CI/CD 설정법 · Vercel 무료 배포 완전 가이드