Programmers

[67일차]쿠버네티스(Kubernetes)를 활용한 웹 개발 배포 시스템 이해

PARKpatchnotes 2025. 12. 16. 00:05

1. 쿠버네티스(k8s) 개요

쿠버네티스는 컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화하는 오픈소스 시스템이다. 도커(Docker)와 같은 컨테이너 기술로 만들어진 애플리케이션들을 대규모 환경에서 효율적으로 운영할 수 있도록 돕는 클러스터 관리 시스템이다.

k8s는 사용자가 추구하는 상태(Desired State)를 선언하면, 현재 상태를 지속적으로 모니터링하여 목표 상태를 유지하려고 노력하는 선언적(Declarative) 구조를 가지고 있다.


2. 쿠버네티스 클러스터 구성 요소

k8s 클러스터는 크게 마스터 노드(Master Node)워커 노드(Worker Node)로 구성된다.

2.1. 마스터 노드 (컨트롤 플레인)

클러스터 전체를 관리하고 제어하는 중심부이다.

  • API 서버: 클러스터의 프론트엔드 역할을 하며 모든 통신(명령)을 받는 중심 허브이다. kubectl을 통한 모든 명령은 API 서버를 거친다.
  • etcd: 클러스터의 모든 구성 데이터, 상태, 메타데이터 등을 저장하는 분산형 키-값 저장소이다. 클러스터의 '뇌' 역할을 한다.
  • 컨트롤러 매니저: 다양한 컨트롤러들을 관리하며 클러스터의 현재 상태를 지속적으로 관찰하여 선언된 목표 상태와 일치시키도록 조정한다.
  • 스케줄러: 새로 생성된 포드(Pod)가 실행될 수 있는 최적의 워커 노드를 선택하고 할당하는 역할을 한다.

2.2. 워커 노드

컨테이너화된 애플리케이션이 실제로 실행되는 컴퓨팅 자원이다.

  • kubelet: 각 워커 노드에서 실행되며, 마스터 노드의 명령을 받아 포드의 구성 내용을 컨테이너 런타임(CRI)에 전달하고, 포드와 노드의 상태를 모니터링하여 API 서버에 보고한다.
  • 컨테이너 런타임(CRI, Container Runtime Interface): 도커 엔진과 같이 컨테이너를 실제로 실행하고 관리하는 역할을 한다.

3. 쿠버네티스의 주요 기능

k8s는 컨테이너화된 애플리케이션의 운영에 필수적인 다양한 자동화 기능을 제공한다.

  • 오류 복구 (Self-Healing): 포드와 노드를 지속적으로 모니터링하며, 장애 발생 시 자동으로 새 포드를 실행하여 지정된 복제본(Replica) 수를 유지한다.
  • 동적 수평 스케일링 (Horizontal Pod Autoscaling, HPA): 부하량(예: CPU 사용률)에 따라 포드 인스턴스의 수를 동적으로 늘리거나 줄여 자원을 효율적으로 활용한다.
  • 트래픽/로드 밸런싱: 복제본이 둘 이상인 경우, 인입되는 트래픽을 클러스터 내부의 포드들에 균등하게 분배한다.
  • 롤링 업데이트: 서비스 중단 없이 순차적으로 새로운 버전의 애플리케이션을 배포하여 무중단 서비스를 가능하게 한다.
  • 서비스 디스커버리: 자체 DNS 기반으로 수명이 짧은 포드들에 동적으로 접근할 수 있도록 안정적인 서비스 바인딩 기능을 제공한다.
  • 스토리지 오케스트레이션: PV(Persistent Volume) 및 PVC(Persistent Volume Claim)를 통해 다양한 외부 스토리지 시스템(클라우드 서비스, 물리적 저장 장치 등)을 마운트하고 관리할 수 있다.

4. 핵심 k8s 오브젝트와 구성 요소

k8s는 다양한 오브젝트(Object)를 통해 클러스터의 상태를 관리한다.

오브젝트/개념 설명
Pod (포드) k8s에서 배포하는 가장 작은 단위로, 하나 이상의 컨테이너 묶음이다. 포드는 독립적인 공간과 IP를 가지며, 언제든지 죽을 수 있는(휘발성) 속성을 지닌다.
Deployment (디플로이먼트) 포드와 포드의 복제본 모음인 레플리카셋(ReplicaSet)을 효과적으로 관리한다. 선언된 포드 수와 버전을 유지하며 롤링 업데이트, 롤백 등을 담당하는 핵심 관리 도구이다.
ReplicaSet (레플리카셋) 동일한 포드들의 집합으로, 지정된 수의 복제본을 항상 실행 상태로 유지하는 것을 보장한다.
Service (서비스) 수명이 짧은 포드들을 대신하여 안정적인 접근점을 제공한다. 클러스터 외부 접근을 가능하도록 노출하는 기능을 포함한다.
Volume (볼륨) 포드가 생성될 때 포드 내부에서 사용할 수 있도록 제공되는 영구 저장장치 또는 임시 디렉토리이다.
Namespace (네임스페이스) 하나의 k8s 클러스터 내에서 리소스들을 논리적으로 구분하여 관리하는 그룹 단위이다.

5. k8s 클러스터 지시 및 상태 조회

kubectl은 클러스터에 명령을 내리고 상태를 조회하는 기본 도구이다.

지시(명령):

  • 포드/컨테이너 실행:
    kubectl run <이름> --image=<이미지>
  • 디플로이먼트 실행:
    kubectl create deployment <이름> --image=<이미지>
  • 서비스 노출:
    kubectl expose deployment <이름> --type=NodePort --port=<포트>
  • 스케일링(복제본 수 조정):
    kubectl scale deployment <이름> --replicas=<갯수>
  • 오브젝트 삭제:
    kubectl delete <타입> <이름>

상태 조회:

  • 현재 관리되고 있는 오브젝트의 상태를 확인:
    kubectl get <타입>
  • 추가 옵션:
    • -o wide로 상세 정보 제공.
    • kubectl describe <타입> <이름>은 특정 오브젝트의 자세한 내용을 열람 가능.

6. 선언적 구조 활용: Manifest 파일

k8s의 선언적 특성을 활용하기 위해 YAML 형식의 Manifest 파일을 작성한다. 이 파일은 원하는 오브젝트의 최종 상태를 명시하며, 아래 명령어를 통해 적용된다:

kubectl apply -f <파일 이름>
  • kubectl applykubectl create의 차이:
    • create: 리소스가 이미 존재하면 오류 발생.
    • apply: 존재하는 리소스를 업데이트하며, 존재하지 않는 리소스도 새로 생성.
      버전 관리 및 지속적인 배포 환경에 더 적합하다.

7. 시나리오

7.1 시나리오 1: 웹 애플리케이션 배포 및 상태 확인

Step 1: 디플로이먼트(Deployment) 생성

# 디플로이먼트 생성 (복제본 1개)
kubectl create deployment my-web-app --image=seongkim/flask-app:v1

# 배포 상태 확인 (PO: Pod, DEPLOY: Deployment)
kubectl get deploy,po

Step 2: 서비스(Service) 노출

# 80번 포트로 서비스 노출
kubectl expose deployment my-web-app --type=NodePort --port=80

# 할당된 포트 확인 (예: 31050)
kubectl get svc my-web-app

Step 3: 접속 테스트 및 로그 확인

# 할당된 NodePort로 접속 테스트 (로컬호스트 가정)
curl http://localhost:31050

# 포드의 로그 확인 (접속 기록 확인)
kubectl logs -f deployment/my-web-app

결과: 처리 중인 포드의 HostnameIP가 출력됩니다.


7.2 시나리오 2: 자동 복구(Self-Healing) 검증

Case A: 포드가 삭제되었을 때 (Rescheduling)

kubectl get pods -w   # 실시간 상태 모니터링
kubectl delete pod <포드이름>   # 현재 실행 중인 포드 삭제

결과: 기존 포드는 삭제(Terminating), 새 포드는 생성(Pending -> Running).

Case B: 애플리케이션 프로세스 종료 시 (Restart)

kubectl exec -it <포드이름> -- /bin/bash   # 포드 내부 접속
kill 1   # 내부 프로세스 강제 종료
kubectl get pods   # 포드 상태 확인

결과: 포드는 유지되지만 RESTARTS 카운트가 증가하며 컨테이너만 재시작.


7.3 시나리오 3: 업데이트, 롤백 및 오토스케일링

Rolling Update (무중단 업데이트)

kubectl set image deployment/my-web-app flask-app=seongkim/flask-app:v2
kubectl rollout status deployment/my-web-app

Rollback (배포 롤백)

kubectl rollout undo deployment/my-web-app
kubectl rollout history deployment/my-web-app

Autoscaling (HPA) 부하 테스트

kubectl autoscale deployment my-web-app --cpu-percent=50 --min=1 --max=10
kubectl run -it --rm load-generator --image=busybox /bin/sh   # 부하 생성
while true; do wget -q -O- http://my-web-app; done   # 무한 요청
kubectl get hpa -w   # HPA 상태 모니터링

결과: 부하량 증가 -> REPLICAS 증가 / 부하 제거 -> REPLICAS 감소.