작성일 댓글 남기기

Kubernetes 입문 — 단일 노드부터 시작하기

Kubernetes 입문 — 단일 노드부터 시작하기

Kubernetes는 정확히 무엇인가요?

Kubernetes(이하 K8s)는 Google이 2014년 오픈소스로 공개한 컨테이너 오케스트레이션 플랫폼으로, 컨테이너 애플리케이션의 배포, 확장, 관리를 자동화하는 시스템입니다. 단일 노드(Node)에서도 동작하며, 여러 노드로 확장 가능한 선형 확장성(Linear Scalability)을 제공합니다. 현재 Cloud Native Computing Foundation(CNCF)이 관리하고 있으며, 표준 컨테이너 런타임 인터페이스(CRI, Container Runtime Interface)를 준수합니다.

Kubernetes의 핵심 아키텍처는 어떻게 구성되나요?

Kubernetes 클러스터는 크게 Control Plane(제어부)과 Worker Node(작업부)로 이루어집니다. 단일 노드 환경에서는 두 역할이 동일 시스템에서 실행됩니다.

Control Plane 구성 요소:

  • API Server: 클러스터의 모든 API 요청을 처리하는 RESTful 인터페이스. 기본 포트는 6443(HTTPS)입니다.
  • etcd: 클러스터의 모든 상태 정보를 저장하는 분산 키-값 저장소. 기본 포트는 2379입니다. 단일 노드 환경에서도 고가용성 목적으로 3개 레플리카 권장.
  • Scheduler: Pod(최소 배포 단위)을 노드에 할당하는 컴포넌트. 리소스 요청(CPU, 메모리)과 제약조건을 기반으로 최적 노드를 선택합니다.
  • Controller Manager: 클러스터 상태를 유지하기 위해 실행되는 여러 컨트롤러 프로세스. Deployment, StatefulSet, DaemonSet 등의 상태를 관리합니다.

Worker Node 구성 요소:

  • kubelet: 각 노드에서 실행되는 에이전트. API Server의 명령을 받아 Pod를 생성, 관리하고 노드 상태를 주기적으로 보고합니다(기본 10초 간격).
  • Container Runtime: 컨테이너를 실제로 실행하는 소프트웨어. containerd, CRI-O, Docker 등을 지원합니다.
  • kube-proxy: 네트워크 트래픽을 관리하는 네트워크 프록시. Service 객체의 Virtual IP(VIP)를 실제 Pod로 라우팅합니다(iptables 또는 IPVS 모드).

단일 노드 Kubernetes 환경은 어떻게 구성하나요?

단일 노드 환경에서 가장 널리 사용되는 배포판은 다음과 같습니다:

배포판 메모리 요구량 디스크 용량 주요 용도 CRI 지원
minikube 2GB 이상 20GB 이상 로컬 개발, 테스트 Docker, containerd, CRI-O
kind 2GB 이상 15GB 이상 CI/CD 환경, 테스트 containerd
k3s 512MB 이상 5GB 이상 엣지 컴퓨팅, 임베디드 containerd
Docker Desktop K8s 4GB 이상 30GB 이상 Windows/Mac 개발 Docker

minikube를 기준으로 설명하면, 단일 VM(Virtual Machine) 또는 컨테이너 내에서 전체 클러스터가 실행됩니다. 초기 부팅 시간은 60120초이며, API Server의 응답 시간은 평균 50100ms입니다.

Pod는 어떻게 작동하나요?

Pod는 Kubernetes의 최소 배포 단위로, 하나 이상의 컨테이너를 포함할 수 있는 래퍼입니다. 동일 Pod 내 컨테이너는 다음을 공유합니다:

  • 네트워크 네임스페이스: 동일 IP 주소(localhost 통신 가능). Pod 내 컨테이너 간 포트 충돌 방지 필수.
  • 스토리지 볼륨: emptyDir, hostPath 등의 공유 스토리지.
  • 프로세스 네임스페이스(선택): shareProcessNamespace: true 설정 시.

단일 노드 환경에서 Pod 생성 프로세스:

  1. 사용자가 kubectl apply -f pod.yaml 실행.
  2. API Server가 Pod 정의를 etcd에 저장.
  3. Scheduler가 해당 노드를 선택하고 Pod.spec.nodeName에 할당.
  4. kubelet이 Pod 변화를 감지하고 Container Runtime에 명령.
  5. 컨테이너 이미지를 레지스트리에서 풀(Pull)하고 실행.
  6. kubelet이 Pod 상태를 10초마다 API Server에 보고.

Pod의 생명주기 상태: Pending → Running → Succeeded(또는 Failed) → Terminating → Terminated. 단일 노드에서 상태 전환 시간은 이미지 크기와 네트워크에 따라 5~30초입니다.

Deployment를 통한 자동 관리는 어떻게 이루어지나요?

Deployment는 Pod의 선언적 관리를 제공하는 상위 추상화 객체입니다. 단일 노드 환경에서도 동일하게 작동합니다:

Deployment 스펙 예시:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi

Deployment Controller는 다음을 자동으로 관리합니다:

  • Replica 유지: 현재 Pod 수가 replicas: 3과 일치하도록 조정. Pod 장애 시 5~10초 내 재생성.
  • Rolling Update: 새 버전 배포 시 기존 Pod를 단계적으로 종료하고 신규 Pod 생성. 기본 최대 25% 동시 종료(maxUnavailable: 25%).
  • Rollback: 배포 실패 시 이전 ReplicaSet으로 자동 복구 가능.

단일 노드에서 3개 replica 운영 시 CPU 요청량이 총 300m(밀리코어)이므로, 일반 데스크톱 CPU의 약 1.5~3%를 점유합니다.

Service를 통한 네트워크 노출은 어떻게 이루어지나요?

Service는 Pod 그룹에 대한 안정적인 네트워크 엔드포인트를 제공합니다. 단일 노드에서도 다음 3가지 타입이 작동합니다:

ClusterIP (기본값):

  • 클러스터 내부 IP 할당 (예: 10.96.0.1).
  • DNS 이름 자동 등록 (예: nginx-service.default.svc.cluster.local).
  • 외부 접근 불가.

NodePort:

  • 노드의 특정 포트(30000~32767)를 Pod로 매핑.
  • kubectl port-forward와 다르게 모든 노드에서 접근 가능.
  • 단일 노드에서 localhost:30080으로 접근 가능.

LoadBalancer:

  • 외부 로드밸런서를 프로비저닝. 클라우드 환경에서만 작동.
  • 단일 노드 환경(minikube 등)에서는 ClusterIP로 downgrade.

kube-proxy는 Service의 Virtual IP(VIP)를 실제 Pod IP로 변환합니다. iptables 모드 기준 단일 Pod에 대한 연결 설정 시간은 약 10ms입니다.

스토리지 관리는 어떻게 하나요?

단일 노드 Kubernetes에서 사용 가능한 스토리지 유형:

유형 특성 영속성 노드 의존성
emptyDir 메모리 또는 디스크 기반 임시 스토리지 Pod 삭제 시 소실 현재 노드에만 존재
hostPath 호스트 시스템의 경로 직접 마운트 영구적 단일 노드에 종속
local 로컬 SSD/디스크 영속 볼륨 영구적 노드 친화성(Node Affinity) 필요
NFS 네트워크 파일 시스템 마운트 영구적 외부 NFS 서버 필수

Persistent Volume(PV) 및 Persistent Volume Claim(PVC) 패턴:

hostPath 기반 PV는 단일 노드에서 빠른 프로토타이핑에 유용합니다(접근 시간 <1ms). 그러나 프로덕션 환경에서는 다중 노드 환경을 고려해 NFS 또는 클라우드 스토리지 클래스(StorageClass)를 권장합니다.

리소스 관리와 제약은 어떻게 설정하나요?

Kubernetes는 requestslimits를 통해 Pod의 리소스 사용을 제어합니다:

  • Requests: Scheduler가 노드 선택 시 참고하는 예상 리소스량. 이 값 이상의 리소스 보장.
  • Limits: Pod이 사용할 수 있는 최대 리소스량. 초과 시 프로세스 강제 종료(Out of Memory).

단일 노드에서의 리소스 계획 예시:

minikube 기본 설정(4GB 메모리): Control Plane에 11.5GB 사용. 애플리케이션용 2.53GB 가용. 3개 replica × 256Mi = 768Mi 요청량이라면, 약 25~30% 메모리 점유.

QoS 클래스에 따른 종료 우선순위:

  1. Guaranteed: requests == limits (최우선 보호).
  2. Burstable: requests < limits (중간 우선순위).
  3. BestEffort: requests, limits 미설정 (먼저 종료).

정리하면 어떤가요?

Kubernetes 단일 노드 환경은 로컬 개발 및 검증을 위한 완전한 클러스터 기능을 제공합니다. Control Plane(API Server, Scheduler, etcd 등)과 Worker Node 컴포넌트가 동일 시스템에서 실행되며, Pod 생성부터 Service 노출, 스토리지 관리까지 멀티 노드 환경과 동일한 메커니즘을 따릅니다. minikube(2GB 메모리 이상), kind, k3s 등의 배포판을 사용하면 30분 이내 환경 구성이 가능하며, CPU 100m과 메모리 128Mi 수준의 리소스 요청으로 경량 애플리케이션 3~5개를 동시 운영할 수 있습니다. 선언적 매니페스트(YAML) 방식으로 배포를 관리하므로, 단일 노드에서 습득한 개념과 스크립트는 멀티 노드 클러스터로 직접 확장 가능합니다.

자주 묻는 질문

Kubernetes 단일 노드 환경과 Docker Compose의 차이는 무엇인가요?

Docker Compose는 여러 컨테이너를 정의하고 로컬에서 실행하는 도구이며, 네트워크와 볼륨 관리에 특화되어 있습니다. Kubernetes는 선언적 상태 관리, 자동 재시작, 리소스 격리, 다중 노드 확장을 기본으로 제공합니다. 단일 노드 Kubernetes는 Compose보다 무겁지만(메모리 300~500MB 추가 소비), 프로덕션 배포 모델과 일치하는 이점이 있습니다. 개발 단계 초기에는 Compose, 멀티 환경 테스트가 필요할 때는 Kubernetes 단일 노드를 권장합니다.

etcd가 장애를 일으키면 어떻게 되나요?

etcd는 클러스터의 모든 상태를 저장하는 핵심 컴포넌트입니다. etcd 장애 시 새로운 Pod 배포, Service 생성 등의 API 요청이 실패합니다. 이미 실행 중인 Pod는 kubelet의 로컬 캐시로 인해 일시적으로 계속 실행되지만, 상태 동기화가 불가능합니다. 단일 노드 환경에서는 etcd 데이터를 정기적으로 백업(etcdctl snapshot save)하여 장애에 대비할 수 있습니다. CNCF 가이드에 따르면 일일 1회 이상 백업을 권장합니다.

단일 노드에서 고가용성(HA) 구성이 가능한가요?

진정한 의미의 고가용성은 다중 노드 환경에서만 가능합니다. 단일 노드 장애 시 전체 클러스터가 다운됩니다. 다만 다음과 같은 부분적 복원력을 확보할 수 있습니다: (1) Pod replica를 여러 개 운영하여 개별 Pod 장애 시 자동 재시작, (2) etcd 스냅샷으로 상태 백업, (3) 호스트 시스템의 재부팅 후 Kubernetes 서비스 자동 복구(systemd 또는 supervisord 활용). 프로덕션 고가용성 요구 시는 최소 3개 노드 클러스터 구성이 필수입니다.

단일 노드 Kubernetes의 CPU와 메모리 오버헤드는 얼마나 되나요?

minikube 기준 초기 부팅 후 유휴 상태 리소스 소비: CPU 38%, 메모리 8001,200MB. 이는 API Server, Scheduler, Controller Manager, etcd, kubelet, kube-proxy 등이 상시 실행되기 때문입니다. Kubernetes 공식 스케일링 테스트 데이터에 따르면, 노드당 110개 Pod 관리 시 Scheduler의 CPU 점유율은 약 50~100m입니다. 4GB 메모리 시스템에서는 Control Plane 1.5GB, 애플리케이션용 2.5GB 배분을 권장합니다.

단일 노드 Kubernetes에서 로깅과 모니터링은 어떻게 하나요?

기본 로깅: kubectl logs <pod-name> 명령으로 stdout/stderr 조회 가능. 컨테이너 런타임(containerd 등)이 로그를 JSON 형식으로 호스트의 /var/lib/kubelet/pods/ 하위에 저장합니다(기본 10MB 롤링). 모니터링: Metrics Server를 설치(kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml)하면 kubectl top node, kubectl top pod로 리소스 사용량 확인 가능. 단일 노드에서는 Prometheus + Grafana를 경량 구성(각 50~100MB)으로 설치하여 시계열 메트릭 수집 및 시각화를 수행할 수 있습니다.

관련 글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다