[Week15] 웹 개발 파이프라인 구축 (2) - 04/21

Kyulee·2026년 4월 24일

TIL 

목록 보기
73/90
post-thumbnail

지난 시간에 도커에 대해 알아보고 실습을 진행했습니다. 이번 시간에는 컨테이너 오케스트레이션 도구인 쿠버네티스(Kubernetes, k8s)에 대해 정리했습니다.


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

쿠버네티스 클러스터는 크게 마스터 노드(컨트롤 플레인)워커 노드로 나뉩니다.

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

구성 요소역할
API 서버, etcd클러스터의 중심 역할을 담당하며 모든 상태 데이터를 저장합니다.
컨트롤러 매니저클러스터의 상태를 지속적으로 모니터링하고 제어합니다.
스케줄러새로 생성된 포드(Pod)를 어떤 워커 노드에 배치할지 결정합니다.
kubectl클러스터와 통신하기 위한 CLI 도구입니다 (필수 구성 요소는 아닙니다).

워커 노드

구성 요소역할
컨테이너 런타임 (CRI)포드를 구성하는 실제 컨테이너를 실행합니다.
kubeletAPI 서버로부터 포드 명세서를 받아 CRI에 전달하고 컨테이너 동작 상태를 모니터링합니다.

2. 주요 기능

쿠버네티스가 제공하는 핵심 기능들입니다.

  • 트래픽 로드 밸런싱: 복제본이 여러 개인 경우 트래픽 부하를 클러스터 내부에 적절히 분배합니다.
  • 동적 수평 스케일링 (HPA): 부하량에 따라 포드 수를 유동적으로 조절해 자원을 효율적으로 활용합니다.
  • 자동 복구: 포드와 노드를 지속적으로 모니터링하여 장애 발생 시 새 포드를 실행해 지정된 복제본 수를 유지합니다.
  • 롤링 업데이트: 서비스 지연 시간을 최소화하며 새로운 버전을 순차적으로 업데이트합니다.
  • 스토리지 오케스트레이션: AWS EBS, Google Persistent Disk 등 다양한 스토리지 시스템을 자동으로 마운트합니다.
  • 서비스 디스커버리: IP가 동적으로 변하는 포드들을 자체 DNS 기반으로 쉽게 찾아 바인딩할 수 있게 합니다.

3. 쿠버네티스의 선언적 구조와 포드의 생명 주기

쿠버네티스는 절차적 구조가 아닌 선언적 구조를 가지고 있습니다. 사용자가 원하는 최종 상태를 선언하면, 쿠버네티스가 현재 상태와 비교하여 지속적으로 그 상태를 유지하려고 합니다.

포드가 생성되는 과정은 다음과 같습니다.

  1. 포드 생성 요청
  2. 포드 생성 및 API 서버에 상태 전달
  3. 스케줄러가 적절한 워커 노드에 포드 실행 요청
  4. 워커 노드의 kubelet이 CRI에 컨테이너 실행을 요청해 포드가 사용 가능한 상태가 됨

4. 쿠버네티스 주요 오브젝트

오브젝트설명
Pod한 개 이상의 컨테이너가 모여 단일 목적을 수행하는 최소 배포 단위입니다. 독립적인 IP를 가지며 언제든지 삭제·재생성될 수 있습니다.
Namespace클러스터 내 리소스들을 논리적으로 구분하여 관리하는 그룹입니다.
Volume포드 내부 컨테이너들이 데이터를 영구적으로 저장하거나 공유할 수 있도록 제공되는 디렉터리입니다.
Service동적으로 변하는 포드들에 안정적으로 접근할 수 있도록 네트워크를 노출하는 기능입니다.
IngressHTTP/HTTPS 트래픽을 여러 서비스로 라우팅하는 규칙 모음입니다.
Deployment레플리카셋과 포드의 배포 및 롤링 업데이트를 관리하는 상위 오브젝트입니다.

Service는 접근 범위에 따라 세 가지 타입으로 나뉩니다.

  • ClusterIP: 클러스터 내부에서만 접근 가능한 기본 타입입니다.
  • NodePort: 워커 노드의 특정 포트를 열어 외부 요청을 내부로 전달합니다.
  • LoadBalancer: 클라우드 제공자의 로드밸런서를 이용해 부하를 분산합니다.

5. 쿠버네티스 실습

기본 명령어

# 현재 상태 확인 (pods, nodes, deployment, svc 등)
kubectl get <타입>

# 더 자세한 정보 확인
kubectl get <타입> -o wide

# 상세 정보 확인
kubectl describe <타입> <이름>

# 삭제
kubectl delete <타입> <이름>

매니페스트(YAML)를 이용한 오브젝트 생성

명령어 방식 대신 YAML 파일을 작성한 뒤 kubectl apply -f <파일명>을 실행하면 설정한 상태 그대로 오브젝트가 생성됩니다. apply는 리소스가 없으면 생성하고, 이미 있다면 변경된 내용을 덮어씌워 적용합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

장애 복구 확인

실행 중인 포드 내부에 접속한 뒤 프로세스를 강제로 종료해 보았습니다.

kubectl exec -it <포드 이름> -- /bin/bash
kill -9 <PID>

결과: 일시적인 에러가 발생하지만, 쿠버네티스가 상태를 감지하고 자동으로 포드를 재시작해 정상 동작을 복구하는 것을 확인할 수 있었습니다.

롤링 업데이트와 롤백

# 이미지 업데이트
kubectl set image deployment <이름> <컨테이너명>=<새 이미지>

# 업데이트 히스토리 확인
kubectl rollout history deploy <이름>

# 이전 버전으로 롤백 (ImagePullBackOff 에러 발생 시)
kubectl rollout undo deploy <이름>

HPA (동적 수평 스케일링) 실습

Metrics Server를 설치한 뒤, CPU 사용률이 50%를 넘을 때 포드 개수를 최대 10개까지 늘리도록 HPA를 설정했습니다.

kubectl autoscale deploy php-apache --cpu-percent=50 --min=1 --max=10

결과: 테스트용 컨테이너로 강제로 트래픽 부하를 주면, CPU 사용률이 올라감에 따라 포드 개수가 자동으로 증가하고, 부하가 줄어들면 다시 감소하는 것을 kubectl get hpa --watch 명령어로 실시간 확인할 수 있었습니다.

profile
안녕하세요 매일의 배움을 기록으로 자산화하는 개발자 이규현입니다 😊

0개의 댓글