IT/Kubernetes

왜 StatefulSet을 사용할까 (feat. deployment와의 차이점)

엘티엘 2022. 4. 22. 19:19

MSA 에서는 어플리케이션의 stateless 를 강조한다. 그래야 Application 의 의존성이 사라지고, 배포, 확장 등이 용이하기 때문이다. 반면에 Kubernetes 에는 Stateful Pod를 생성하기 위해서 Statefulset 워크로드를 제공한다. 이것은 언제 사용되는지 정리해 봤다.

StatefulSet 이란?

스테이트풀셋은 애플리케이션의 스테이트풀을 관리하는데 사용하는 워크로드 API 오브젝트이다.
파드 집합의 디플로이먼트와 스케일링을 관리하며, 파드들의 순서 및 고유성을 보장한다 .
디플로이먼트와 유사하게, 스테이트풀셋은 동일한 컨테이너 스펙을 기반으로 둔 파드들을 관리한다. 디플로이먼트와는 다르게, 스테이트풀셋은 각 파드의 독자성을 유지한다. 이 파드들은 동일한 스팩으로 생성되었지만, 서로 교체는 불가능하다. 다시 말해, 각각은 재스케줄링 간에도 지속적으로 유지되는 식별자를 가진다.
스토리지 볼륨을 사용해서 워크로드에 지속성을 제공하려는 경우, 솔루션의 일부로 스테이트풀셋을 사용할 수 있다. 스테이트풀셋의 개별 파드는 장애에 취약하지만, 퍼시스턴트 파드 식별자는 기존 볼륨을 실패한 볼륨을 대체하는 새 파드에 더 쉽게 일치시킬 수 있다.
[참조] https://kubernetes.io/ko/docs/concepts/workloads/controllers/statefulset/

주요 특징을 정리하면 아래와 같다.

  • 파드들의 순서 및 고유성을 보장한다. (배포, 업데이트, 스케일링시)
  • 재스케줄링 간에도 지속적으로 유지되는 식별자를 가진다. (네트워크)
  • PV를 유지할 수 있다

언제 StatefulSet을 사용해야 하는가?

공식 홈페이지에서는 아래와 같이 설명한다.

결국 위에 있는 주요 특징과 일맥상통하는 내용인데, 1) 네트워크 식별자가 유지되어야 하거나, 2) 배포/업데이트/스케일링시에 순차적으로 진행이 되어야 하거나 3) 스토리지가 유지되어야 하는 경우이다.

Deployment 와의 주요 차이점

위에 기술한 주요 특징외의 내용을 적어봤다.

  • Service vs Headless Service
    • Deployment는 Service를 통해서 외부에 노출이 되고, Service로 request를 하면 random 하게 Pod가 선택된다
    • StatefulSet은 Headless Service를 통해 외부에 노출이 되고, 각 Pod별 고유한 DNS를 가지며 원하는 Pod를 지정해서 request를 해야 한다. (Service에 request 하는것은 불가능)
  • Rollback 및 ReplicaSet
    • Deployment 는 내부적으로 ReplicaSet을 생성하여 Pod를 관리하며, rollback 이 가능하다 (rolling update시에 새로운 replicaset이 생성되며 기존 ReplicaSet의 개수는 줄고, 새로운 ReplicaSet의 개수가 늘어나는 방식)
    • StatefulSet은 내부적으로 ReplicaSet을 생성하지 않으며 rollback이 불가하다.

[참고] Headless Service

StatefulSet 은 각 Pod의 역할이 다르기 때문에 외부에서 Deployment 처럼 random으로 pod를 선택하는것이 아니라, 특정 Pod와 직접 통신해야 하는 경우가 많다. Pod의 IP는 생성시마다 달라지는데 이를 매번 찾아서 접속할수 없기 때문에, 이럴 경우 Headless Service를 사용한다. Headless Service를 사용하면 Service를 통해 수행되던 로드밸런싱이나 proxy를 하지 않고 Pod마다 고정된 DNS를 생성할 수 있다.

생성 방법은 Service yaml에 spec.clusterIP를 None 으로 정의하면 된다.

Headless Service로 묶인 Pod들은 각각 아래와 같은 고정된 DNS을 가진다.

[pod-name].[svc].[namespace].svc.cluster.local

사실 Headless Service가 없더라도 Pod는 기본적으로 아래와 같은 DNS를 가진다. 다만 DNS에 pod ip주소가 포함되기 때문에 사실상 고정된 DNS가 아니므로 활용이 어렵다. 반면에 Headless Service를 사용하면 pod의 DNS에 ip주소 대신 pod이름을 사용하고, StatefulSet은 고정된 pod 이름을 가지므로 사실상 pod의 DNS는 고정된다고 볼수 있다. 

[pod-ip-address].[namespace].pod.cluster.local

 

반응형