Kubernetes 입문 가이드 — 컨테이너 오케스트레이션의 핵심

Kubernetes가 필요한 이유

Docker로 컨테이너 하나를 실행하는 건 간단합니다. 하지만 프로덕션에서는 질문이 달라집니다.

  • 컨테이너가 죽으면 누가 다시 띄우나?
  • 트래픽이 몰리면 어떻게 확장하나?
  • 새 버전을 무중단으로 어떻게 배포하나?
  • 10개 서비스의 네트워크를 어떻게 관리하나?

Kubernetes(K8s)는 이 모든 것을 자동화하는 컨테이너 오케스트레이션 플랫폼입니다. Google이 내부 시스템(Borg)에서 15년간 쌓은 경험을 오픈소스로 공개한 것이 시작입니다.

핵심 아키텍처

Kubernetes 클러스터는 Control Plane(두뇌)과 Worker Node(손발)로 나뉩니다.

구성 요소역할비유
Control Plane전체 클러스터 관리, 스케줄링, 상태 감시관제탑
API Server모든 요청의 진입점 (kubectl이 통신하는 대상)접수 창구
etcd클러스터 상태를 저장하는 분산 키-값 저장소데이터베이스
SchedulerPod를 어떤 Node에 배치할지 결정배차 담당
Worker Node실제 컨테이너가 실행되는 서버공장
kubelet각 Node에서 Pod를 관리하는 에이전트현장 감독

핵심 리소스 6가지

1. Pod — 최소 배포 단위

Pod는 하나 이상의 컨테이너를 묶은 그룹입니다. 같은 Pod 안의 컨테이너는 네트워크와 스토리지를 공유합니다.

# pod.yaml — 가장 단순한 Pod 정의
apiVersion: v1
kind: Pod
metadata:
  name: my-app
  labels:
    app: my-app          # 라벨: 다른 리소스가 이 Pod를 찾는 기준
spec:
  containers:
    - name: app
      image: nginx:alpine
      ports:
        - containerPort: 80
      resources:
        requests:          # 최소 보장 리소스
          memory: "64Mi"
          cpu: "100m"      # 0.1 CPU 코어
        limits:            # 최대 사용 제한
          memory: "128Mi"
          cpu: "250m"
# Pod 생성
kubectl apply -f pod.yaml

# Pod 상태 확인
kubectl get pods
# NAME     READY   STATUS    RESTARTS   AGE
# my-app   1/1     Running   0          30s

# Pod 상세 정보 (이벤트, IP, Node 등)
kubectl describe pod my-app

# Pod 로그 확인
kubectl logs my-app

# Pod 삭제
kubectl delete pod my-app

직접 Pod를 만드는 경우는 드뭅니다. 대신 Deployment를 사용합니다.

2. Deployment — 선언적 배포 관리

Deployment는 “이 앱을 3개 복제본으로 항상 유지해줘”라고 선언하면 Kubernetes가 알아서 관리합니다. Pod가 죽으면 자동 재생성되고, 업데이트 시 롤링 배포를 수행합니다.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3               # 항상 3개 Pod 유지
  selector:
    matchLabels:
      app: my-app            # 이 라벨을 가진 Pod를 관리
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: my-app:1.0
          ports:
            - containerPort: 3000
          env:
            - name: NODE_ENV
              value: "production"
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
# Deployment 생성/업데이트
kubectl apply -f deployment.yaml

# Deployment 상태 확인
kubectl get deployments
# NAME     READY   UP-TO-DATE   AVAILABLE   AGE
# my-app   3/3     3            3           60s

# 이미지 업데이트 (롤링 배포 자동 실행)
kubectl set image deployment/my-app app=my-app:2.0

# 롤아웃 상태 확인
kubectl rollout status deployment/my-app
# Waiting for deployment "my-app" rollout to finish: 1 of 3 updated...
# deployment "my-app" successfully rolled out

# 문제 발생 시 롤백
kubectl rollout undo deployment/my-app

3. Service — 네트워크 접근점

Pod의 IP는 생성될 때마다 바뀝니다. Service는 여러 Pod 앞에 고정된 주소를 제공하고, 트래픽을 분산합니다.

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
spec:
  type: ClusterIP            # 클러스터 내부에서만 접근 (기본값)
  selector:
    app: my-app              # 이 라벨의 Pod로 트래픽 전달
  ports:
    - port: 80               # Service 포트
      targetPort: 3000       # Pod의 컨테이너 포트

Service 타입 3가지:

타입접근 범위용도
ClusterIP클러스터 내부만내부 서비스 간 통신 (기본값)
NodePort외부에서 Node IP:Port로 접근개발/테스트용
LoadBalancer클라우드 로드밸런서 자동 생성프로덕션 외부 노출

4. ConfigMap과 Secret — 설정 분리

코드와 설정을 분리하여 같은 이미지를 dev/staging/prod에서 재사용합니다.

# configmap.yaml — 일반 설정값
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production"
  LOG_LEVEL: "info"
  MAX_CONNECTIONS: "100"
---
# secret.yaml — 민감한 정보 (base64 인코딩)
apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  DB_PASSWORD: cGFzc3dvcmQxMjM=    # echo -n "password123" | base64
  API_KEY: bXlzZWNyZXRrZXk=        # echo -n "mysecretkey" | base64

Deployment에서 참조하는 방법:

# deployment에 추가
spec:
  containers:
    - name: app
      envFrom:
        - configMapRef:
            name: app-config       # ConfigMap의 모든 키를 환경변수로
        - secretRef:
            name: app-secret       # Secret의 모든 키를 환경변수로

5. Ingress — HTTP 라우팅

외부 HTTP 요청을 도메인/경로 기반으로 내부 Service에 연결합니다. 하나의 IP로 여러 서비스를 노출할 수 있습니다.

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-svc
                port:
                  number: 80
    - host: admin.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: admin-svc
                port:
                  number: 80

6. Namespace — 환경 분리

하나의 클러스터 안에서 리소스를 논리적으로 분리합니다.

# Namespace 생성
kubectl create namespace staging
kubectl create namespace production

# 특정 Namespace에 배포
kubectl apply -f deployment.yaml -n staging

# Namespace별 리소스 확인
kubectl get pods -n staging
kubectl get pods -n production
kubectl get pods --all-namespaces    # 전체

자주 쓰는 kubectl 명령어

명령어설명
kubectl get pods -o widePod 목록 + Node/IP 정보
kubectl logs -f pod-name실시간 로그 스트리밍
kubectl exec -it pod-name -- shPod 내부 쉘 접속
kubectl port-forward svc/my-app 8080:80로컬에서 Service 접근 (디버깅용)
kubectl top podsPod CPU/메모리 사용량
kubectl get events --sort-by=.lastTimestamp최근 이벤트 (트러블슈팅)
kubectl diff -f deployment.yaml적용 전 변경사항 미리보기
kubectl scale deployment/my-app --replicas=5수동 스케일링

로컬 개발 환경

프로덕션 클러스터 없이 로컬에서 Kubernetes를 실습할 수 있습니다.

도구특징설치
Docker DesktopK8s 내장 (Settings에서 활성화)Docker Desktop 설치 후 Enable Kubernetes
minikube단일 노드 클러스터, 가장 널리 사용brew install minikube
kindDocker 컨테이너 안에서 K8s 실행, CI/CD에 적합brew install kind
# minikube 시작
minikube start

# 대시보드 열기 (웹 UI)
minikube dashboard

# 상태 확인
kubectl cluster-info

정리

개념핵심Docker Compose와 비교
Pod컨테이너 실행 단위services: 의 한 항목
Deployment복제, 롤링 업데이트, 자동 복구deploy.replicas (Swarm)
Service고정 주소 + 로드밸런싱ports: + 내부 DNS
ConfigMap/Secret설정/비밀 분리environment: / .env
Ingress도메인 기반 HTTP 라우팅Nginx 리버스 프록시
Namespace환경 격리별도 compose 파일

Docker Compose는 단일 서버에서 여러 컨테이너를 편리하게 관리하는 도구이고, Kubernetes는 여러 서버에 걸쳐 수백~수천 개 컨테이너를 자동으로 관리하는 플랫폼입니다. 소규모 서비스는 Docker Compose로 충분하지만, 고가용성과 자동 스케일링이 필요하다면 Kubernetes를 검토하세요.

이 글이 도움이 되었나요?