7.2.1 레플리카셋의 역할

앞서 우리는 파드가 쿠버네티스에서 애플리케이션을 실행하는 가장 기본적인 단위임을 배웠습니다. 하지만 단일 파드만으로는 실제 운영 환경에서 요구되는 안정성과 확장성을 확보하기 어렵습니다. 만약 운영 중인 파드에 문제가 생겨 종료된다면, 해당 파드가 제공하던 서비스는 중단될 수밖에 없겠죠. 또한, 갑작스러운 사용자 증가로 인해 더 많은 처리 용량이 필요할 때, 수동으로 파드를 추가하고 관리하는 것은 매우 비효율적입니다.

이러한 문제를 해결하기 위해 등장한 것이 바로 레플리카셋(ReplicaSet)입니다. 레플리카셋은 쿠버네티스 환경에서 항상 지정된 수의 동일한 파드 복제본이 실행되도록 보장하는 역할을 합니다. 마치 분신술처럼, 똑같은 능력을 가진 여러 개의 파드를 만들어주고, 이들의 숫자를 꾸준히 관리해주는 매니저라고 생각하시면 이해하기 쉬울 거예요. 이를 통해 애플리케이션의 고가용성(High Availability)과 확장성(Scalability)을 손쉽게 확보할 수 있게 됩니다.

레플리카셋은 그 자체로도 강력한 기능을 제공하지만, 실제 운영 환경에서는 보통 디플로이먼트(Deployment)라는 더 상위 레벨의 오브젝트를 통해 간접적으로 관리되는 경우가 많습니다. 디플로이먼트는 레플리카셋의 기능을 포함하면서 롤링 업데이트, 롤백 등 더 정교한 배포 전략을 제공하기 때문인데요. 하지만 레플리카셋의 핵심 원리를 이해하는 것은 쿠버네티스의 자동화 및 자기 치유(Self-healing) 메커니즘을 파악하는 데 매우 중요합니다.

이제 레플리카셋이 구체적으로 어떤 역할을 수행하는지, 그리고 그 역할들이 왜 클라우드 네이티브 환경에서 중요한지 자세히 살펴보겠습니다.

7.2.1.1 지정된 수의 파드 복제본 유지

레플리카셋의 가장 핵심적인 역할은 바로 사용자가 원하는 수만큼의 파드 복제본(replica)을 항상 유지하는 것입니다. 우리가 “애플리케이션 A를 실행하는 파드를 3개 유지해줘”라고 레플리카셋에게 요청하면, 레플리카셋은 현재 클러스터 내에 해당 파드가 몇 개 실행 중인지 지속적으로 감시합니다.

이때 레플리카셋은 두 가지 중요한 정보를 바탕으로 동작합니다.

  1. 파드 템플릿(Pod Template): 어떤 모습의 파드를 복제할 것인지에 대한 명세입니다. 여기에는 파드에 포함될 컨테이너 이미지, 필요한 리소스(CPU, 메모리), 환경 변수, 볼륨 마운트 등 파드를 정의하는 모든 정보가 담겨 있습니다. 레플리카셋은 이 템플릿을 기준으로 새로운 파드를 생성합니다. 마치 붕어빵 틀과 같아서, 이 틀을 이용해 똑같은 모양과 맛의 붕어빵(파드)을 여러 개 찍어낼 수 있는 것이죠.
  2. 셀렉터(Selector)와 레이블(Label): 레플리카셋은 자신이 관리해야 할 파드들을 식별하기 위해 셀렉터를 사용합니다. 파드에는 ‘키-값’ 쌍으로 이루어진 레이블을 붙일 수 있는데, 레플리카셋은 특정 레이블을 가진 파드들만을 자신의 관리 대상으로 인식합니다. 예를 들어, app: my-app, tier: frontend 와 같은 레이블이 붙은 파드들을 관리하도록 설정할 수 있습니다. 레플리카셋은 이 셀렉터와 일치하는 레이블을 가진 파드들의 개수를 세어, 자신이 유지해야 할 복제본 수와 비교합니다.

이 두 가지 정보를 바탕으로 레플리카셋은 다음과 같은 조정 루프(reconciliation loop)를 끊임없이 실행합니다.

  • 현재 상태 확인: 셀렉터에 지정된 레이블을 가진 파드가 현재 클러스터에 몇 개나 실행 중인지 확인합니다.
  • 원하는 상태와 비교: 이렇게 확인된 실제 파드의 개수와 사용자가 레플리카셋에 설정한 ‘원하는 복제본 수(replicas)’를 비교합니다.
  • 조치 수행:
    • 만약 실제 파드 수가 원하는 수보다 적다면, 레플리카셋은 파드 템플릿을 이용해 부족한 수만큼 새로운 파드를 생성합니다.
    • 반대로 실제 파드 수가 원하는 수보다 많다면, 레플리카셋은 초과된 수만큼 기존 파드 중 일부를 선택하여 종료시킵니다. (일반적으로 가장 오래된 파드부터 종료하지만, 항상 그렇지는 않습니다.)

예를 들어, replicas: 3으로 설정된 레플리카셋이 있다고 가정해봅시다.

  • 처음 레플리카셋이 생성되면, 관리 대상 파드가 0개이므로 템플릿을 사용해 3개의 파드를 생성합니다.
  • 만약 운영 중 관리자가 실수로 이 레플리카셋이 관리하는 파드 중 하나를 직접 삭제했다고 해도, 레플리카셋은 즉시 파드 수가 2개로 줄어든 것을 감지하고, 다시 1개의 파드를 새로 생성하여 총 3개를 유지합니다.
  • 반대로, 어떤 이유에서든 동일한 레이블을 가진 파드가 4개가 되었다면 (예: 다른 컨트롤러가 실수로 생성), 레플리카셋은 1개의 파드를 종료시켜 3개를 유지하려고 시도합니다. (단, 레플리카셋은 자신이 직접 생성하지 않은 파드에 대해서는 소유권(ownerReference)이 없다면 함부로 삭제하지 않을 수 있습니다. 일반적으로는 자신이 생성한 파드 풀 내에서 조절합니다.)

이처럼 레플리카셋은 마치 성실한 정원사처럼, 우리가 원하는 수의 꽃(파드)이 항상 정원에 피어 있도록 꾸준히 관리해주는 역할을 합니다. 이를 통해 우리는 수동으로 파드의 개수를 조절하는 번거로움에서 벗어나, 애플리케이션의 부하에 따라 유연하게 파드 수를 늘리거나 줄일 수 있는 기반을 마련하게 됩니다. 이것이 바로 선언적 API(Declarative API) 의 장점입니다. 우리는 “3개의 파드를 만들어라”가 아니라 “3개의 파드가 존재해야 한다”는 최종 목표 상태를 선언하고, 쿠버네티스(여기서는 레플리카셋)가 그 상태에 도달하고 유지하도록 하는 것입니다.

7.2.1.2 파드 장애 시 자동 복구 (Self-healing)

클라우드 네이티브 환경에서 애플리케이션은 언제든지 예기치 않은 장애에 직면할 수 있습니다. 하드웨어 문제로 인해 특정 노드(서버)가 다운될 수도 있고, 애플리케이션 자체의 버그로 인해 특정 파드가 비정상적으로 종료될 수도 있습니다. 이러한 상황에서 서비스 중단을 최소화하고 안정성을 유지하는 것은 매우 중요합니다.

레플리카셋은 바로 이 자동 복구(Self-healing) 기능을 통해 애플리케이션의 회복탄력성(Resilience)을 크게 향상시킵니다. 앞서 설명드린 ‘지정된 수의 파드 복제본 유지’ 기능이 이러한 자동 복구의 핵심 원리가 됩니다.

상황을 가정해 보겠습니다. replicas: 3으로 설정된 레플리카셋이 3개의 파드를 정상적으로 운영하고 있다고 합시다. 그런데 갑자기 이 3개의 파드 중 하나가 실행 중이던 노드에 장애가 발생하여 해당 노드가 다운되었다고 가정해봅시다. 이 경우, 해당 노드에서 실행되던 파드는 더 이상 정상적으로 작동할 수 없게 됩니다.

이때 레플리카셋의 조정 루프가 마법을 부립니다.

  1. 장애 감지: 쿠버네티스 시스템은 노드 장애를 감지하고, 해당 노드에서 실행되던 파드가 비정상 상태(예: Terminating 또는 Unknown 상태)가 되었음을 인지합니다. 레플리카셋은 자신이 관리하는 파드 중 하나가 사라졌거나 비정상 상태임을 감지하게 됩니다.
  2. 상태 불일치 확인: 레플리카셋은 자신이 관리해야 할 파드의 ‘원하는 상태(desired state)’는 3개인데, 현재 ‘실제 상태(actual state)’는 2개(또는 정상 작동하는 파드가 2개)임을 파악합니다.
  3. 자동 복구 수행: 상태 불일치를 해소하기 위해, 레플리카셋은 즉시 파드 템플릿을 사용하여 새로운 파드 1개를 클러스터 내의 사용 가능한 다른 건강한 노드에 스케줄링하여 생성합니다.
  4. 정상 상태 복원: 새로운 파드가 성공적으로 실행되면, 다시 총 3개의 파드가 정상적으로 운영되는 상태로 복구됩니다.

이 모든 과정은 관리자의 개입 없이 자동으로 이루어집니다. 마치 불사조처럼, 하나의 파드가 쓰러지면 레플리카셋이 즉시 다른 파드를 되살려내는 것이죠. 이러한 자기 치유 능력 덕분에, 간헐적인 파드 또는 노드의 장애가 발생하더라도 전체 서비스의 중단을 막거나 최소화할 수 있습니다.

이 자동 복구 기능은 클라우드 환경의 본질적인 특성, 즉 인프라의 변동성과 잠재적인 장애 가능성을 고려할 때 매우 중요합니다. 레플리카셋은 “파드는 언제든 죽을 수 있는 소모품(cattle, not pets)”이라는 클라우드 네이티브 철학을 구현하는 핵심 요소 중 하나입니다. 개별 파드의 생존에 연연하기보다는, 전체 서비스의 가용성을 보장하는 데 초점을 맞추는 것이죠.

물론, 레플리카셋의 자동 복구는 애플리케이션 자체가 상태를 가지지 않는 스테이트리스(Stateless) 애플리케이션에 가장 적합합니다. 만약 파드가 종료될 때 중요한 상태 정보(예: 데이터베이스의 미완료 트랜잭션)를 가지고 있다면, 단순히 새 파드를 띄우는 것만으로는 완전한 복구가 어려울 수 있습니다. 이러한 경우에는 스테이트풀셋(StatefulSet)과 같은 다른 컨트롤러나, 퍼시스턴트 볼륨(Persistent Volume)을 통한 데이터 영속화 전략을 함께 고려해야 합니다.

하지만 대부분의 웹 애플리케이션, API 서버 등은 스테이트리스하게 설계될 수 있으며, 이러한 애플리케이션들에게 레플리카셋의 자동 복구 기능은 운영 부담을 크게 줄여주고 서비스 안정성을 획기적으로 높여주는 강력한 도구임이 틀림없습니다.

지금까지 레플리카셋의 두 가지 핵심 역할, 즉 지정된 수의 파드 복제본 유지와 파드 장애 시 자동 복구 기능에 대해 자세히 알아보았습니다. 이 두 기능은 서로 밀접하게 연관되어 있으며, 쿠버네티스가 어떻게 애플리케이션의 안정성과 확장성을 보장하는지 이해하는 데 중요한 기초가 됩니다. 다음 장에서는 이러한 레플리카셋을 더욱 효과적으로 활용할 수 있게 해주는 디플로이먼트에 대해 알아보도록 하겠습니다.