개발 일기

[Kubernetes] 왜 Kubernetes인가? 본문

Back-End/Spring Cloud + MSA + Kubernetes

[Kubernetes] 왜 Kubernetes인가?

개발 일기장 주인 2025. 2. 6. 17:23

현재 프로젝트를 컨테이너 기반의 MSA 환경으로 구축하고, Kubernetes를 활용해 오케스트레이션하려 한다.

단순히 독립적인 배포 및 유지보수를 용이하게 하고, 대용량 트래픽이 발생할 경우 전체 시스템이 아니라 특정 기능만 확장할 수 있도록 하기 위해 도입을 고려 중이다. 다만, 개념적으로만 알고 있어 이를 더 명확히 정리하고자 한다.


우선 컨테이너화는 왜 필요한지 다시 짚고 가자.

Why Container?
Relation과 History를 말끔히 해결해준다.

Relation 문제 해결
기존 가상 머신은 각 VM이 Guest OS를 가지고 있으며, 이를 실행하기 위해 Host OS와 Hypervisor를 거쳐야 한다. 이 과정에서 리소스 오버헤드가 발생하고, 성능 저하가 불가피하다.
반면, Docker 컨테이너는 Host OS의 커널을 공유하면서 Docker Engine을 통해 직접 CPU, 메모리 등의 리소스를 가상화한다. 이 덕분에 오버헤드가 적고 성능적인 불이익 없다.

또한, 컨테이너는 격리된 실행 환경을 제공한다. 일반적으로 서버에 직접 프로그램을 설치하면 서로 의존성을 가지게 되고, 리소스를 공유하면서 충돌이나 성능 저하가 발생할 수 있다.
하지만 리눅스 컨테이너는 프로세스를 분리하여 독립적인 격리 공간을 제공하기 때문에, 각 애플리케이션이 서로 간섭하지 않고 안정적으로 실행될 수 있다.

History 문제 해결

컨테이너는 불변 인프라(Immutable Infrastructure) 개념을 따르며, 각 애플리케이션의 실행 환경을 코드화하여 버전 관리가 용이하다. 즉, 특정 시점의 환경을 그대로 복원할 수 있어 일관된 배포 및 롤백이 가능하다.

 

그렇다면 Container Orchestration Tool은 왜 필요한가?

(좌) 2Apps + 2 AS Groups + 1 ALB / (우) 3Apps + 1 AS Groups

컨테이너화를 위해 도커를 도입하여 여러 컨테이너를 하나의 서버 내에서 실행했지만, 배포 시 각 컨테이너를 직접 관리해야 하므로 단순해졌다고 보기 어렵다.
이에 따라 Container Orchestration Tool을 활용하면 여러 인스턴스에 배포된 다양한 컨테이너를 효율적으로 관리하고, 유연하게 배포 및 확장할 수 있도록 도와준다.

 

쿠버네티스의 구성

  • Cluster
    • 컨테이너화된 애플리케이션을 실행하고 관리하는 전체 환경을 의미한다. (하나의 그룹 단위)
    • Kubernetes에서 클러스터는 여러 개의 노드(Node)로 구성되며, 각 노드는 컨테이너를 실행하는 단위인 Pod(파드)를 포함한다.
    • 애플리케이션의 배포, 확장, 로드 밸런싱 및 장애 복구를 자동화하는 역할을 한다.
  • Node
    • 클러스터를 구성하는 개별 서버로, 컨테이너를 실행하는 실제 단위 (EC2 인스턴스에 1대1 대응)
    • Master Node (마스터 노드): 클러스터를 관리하고, 워커 노드에 작업을 할당한다.
      Worker Node (워커 노드): 컨테이너가 실제로 실행되는 서버로, 여러 개의 Pod을 실행한다.
  • Pod
    • Kubernetes에서 가장 작은 배포 단위로, 하나 이상의 컨테이너를 묶어 실행하는 단위
    • 각 Pod는 하나의 애플리케이션 인스턴스를 실행하며, 내부적으로 같은 네트워크 네임스페이스를 공유
    • 같은 Pod 안에 있는 컨테이너들은 같은 네트워크 환경을 공유
    • 하나의 Pod에는 보통 하나의 컨테이너만 존재하지만, 여러 개의 컨테이너를 포함
    • Kubernetes는 Pod 단위로 배포, 스케일링 및 관리를 수행
    •  Pod는 일회성(임시적) 리소스로, 장애가 발생하면 새로운 Pod가 생성되어 대체
  • ReplicationController (ReplicaSet)
    • 하나의 Pod 상태를 공유하고 있는 Set
    • 지정된 수의 Pod 복제본(Replica)이 항상 실행되도록 보장하는 역할   Scaling
    • 그러나, Pod의 Rolling Update(순차적 업데이트)가 어렵고, 새로운 버전 배포 시 이전 버전의 Pod를 직접 삭제해야 함
      배포 전략이 제한적이며, 애플리케이션의 점진적 업데이트나 롤백 지원하지 않음.
      이를 해결하기 위해 Deployment가 등장
  • Deployment
    • RC를 대체하는 기능으로, 애플리케이션의 배포와 업데이트를 보다 유연하게 관리할 수 있도록
    • 내부적으로 ReplicaSet(RS)을 사용하여 Pod 개수를 관리하며, 새로운 버전이 배포될 때 기존 Pod를 점진적으로 교체하는 Rolling Update를 지원
    • 어떻게 배포할지 설정 가능하다.
  • Service
    •  Kubernetes 클러스터 내에서 실행되는 Pod들에 대한 네트워크 접근을 제공하는 역할
    • Pod는 동적으로 생성되고 삭제되므로 IP가 변경될 수 있는데, Service는 이러한 Pod를 고정된 엔드포인트(Cluster IP)로 접근할 수 있도록 해준다.

Why Kubernetes?

1. Automatic Binpacking

  •  컨테이너를 자동으로 스케줄링하여 최적의 리소스 활용을 보장
  • CPU, 메모리 등의 제약 조건을 고려하여 워크로드를 적절히 분배하며, 가용한 노드에 컨테이너를 효율적으로 배치
  • 수동으로 컨테이너 배포 위치를 결정할 필요 없이, Kubernetes가 자동으로 최적의 위치에 배치하여 리소스를 최대한 활용

2. Horizontal Scaling

  • 애플리케이션의 트래픽 증가 또는 리소스 사용량 증가에 따라 자동으로 컨테이너 개수를 조절
  • Horizontal Pod Autoscaler (HPA)를 활용하면 CPU 사용률, 메모리 사용량, 커스텀 메트릭 등을 기반으로 Auto Scaling
  • 트래픽이 많아지면 Pod 개수를 늘려 부하를 분산하고, 트래픽이 줄어들면 불필요한 Pod을 줄여 리소스를 절약

3. Automated Rollouts and Rollbacks

 

  • Kubernetes는 새로운 애플리케이션 버전 배포 시 점진적으로 롤아웃(배포)하여 서비스 가용성을 보장
  • 문제가 발생하면 자동으로 롤백하여 안정성을 유지
  • Deployment를 사용하면 업데이트 도중 문제가 생길 경우 이전 버전으로 복구 가능

4. Self-Healing

  • Kubernetes는 실패한 컨테이너를 자동으로 감지하고 복구
  • 워커 노드 자체가 죽어도 거기 있던 파드를 다른 워커 노드에 그 파드를 다시 살린다.
  • CrashLoopBackOff 상태인 컨테이너를 재시작하고, 헬스 체크(livenessProbe, readinessProbe)를 통해 상태를 지속적으로 모니터링
  • 문제가 있는 Pod을 자동으로 교체하여 애플리케이션 가용성을 보장

 

5. Service Discovery and Load Balancing