StatefulSet이란

노재원·2023년 4월 10일
0

Kubernetes

목록 보기
7/8
post-thumbnail

쿠버네티스 인 액션 책 내용 요약 + 제 생각을 녹여냈습니다.

StatefulSet의 필요성

디플로이먼트로 생성한 파드들은 다음과 같은 특징이 있다.

  • 모든 파드들은 같은 PVC를 공유
  • 파드가 재시작되면 파드 이름, 네트워크 등의 모든 것이 초기화 됨

stateful한 어플리케이션은 일정한 호스트 이름, 독립된 볼륨을 필요로 하기 때문에, 디플로이먼트로 이러한 어플리케이션을 띄우는 데는 한계가 있다. 따라서 StatefulSet이라는 리소스로 띄워서 사용해야 한다.

StatefulSet 특징

  • 각 파드들은 자기만의 PVC를 가질 수 있다.
  • 파드가 재시작되도 파드 이름, 호스트 이름 등 파드의 원래 속성이 그대로 유지된다.
  • 스케일링해도 생성될 파드 이름을 알 수 있고, 삭제될 때도 어떤 파드가 삭제될 지 알 수 있다.

인스턴스 스케일링

스케일 업할 땐 파드 인스턴스와 이에 대응하는 PVC가 같이 생성된다. 하지만 문제는 스케일 다운할 때이다.
stateful한 어플리케이션은 빠른 스케일 다운을 처리하지 못한다. 그리고 데이터의 엔트리마다 두 개의 복제본을 저장하도록 구성되어 있다면 여러 인스턴스가 한번에 죽으면 어플리케이션이 대응을 하지 못하고 데이터 손실이 발생한다.
이를 예방하기 위해 파드는 한 순간에 하나만 삭제될 수 있으며, 만약 어떤 파드의 상태가 비정상이라면 삭제를 할 수 없도록 되어 있다.

데이터 안정성

파드들은 자기만의 PVC를 가질 수 있다고 했다. 이게 가능한 이유는 StatefulSet 리소스의 스펙으로 VolumeClaimTemplate 이라는게 있고, 마치 PodTemplate 처럼 PVC의 템플릿을 정의할 수 있다. VolumeClaimTemplate 으로 파드가 새로 만들어질 때마다 그에 맞는 PVC도 같이 생성된다.

파드가 삭제될 때 PVC는 삭제되지 않고 남아있는다. 스케일 다운이 아주 단순한 것에 비해 PVC가 삭제되면 아주 큰 문제가 발생할 수 있기 때문이다. 만약 삭제가 필요하다면 수동으로 삭제해야 한다.

덕분에 다시 스케일 업을 하면 모든 것이 동일한 파드가 다시 생성되며 동일한 데이터가 있는 PVC에 바인딩 되기 때문에, 삭제되기 전 그대로 복구가 가능하다.

유일 아이덴티티 보장

StatefulSet의 파드들은 고유의 아이덴티티가 있음을 봐왔다. 우리가 스케일 업/다운을 별 생각없이 하지만, 이것은 아이덴티티가 같은 파드가 없다는 것이 보장되어야 가능하다. StatefulSet은 이렇게 파드의 유일 아이덴티티를 보장하고 있다.
하지만 파드가 실행되고 있던 노드가 갑자기 죽어버리면 어떻게 될까. 노드가 죽어버리면 더이상 파드의 상태를 알 수가 없다. StatefulSet은 유일함을 보장해야 하므로 함부로 대체 파드를 생성할 수 없다. 이렇게 상태를 알 수 없게 된 파드는 UNKNOWN 상태에 접어들며, 이 상태가 몇 분이상 지속되면 마스터 노드가 해당 파드를 삭제한다. 그러면 수동으로 삭제해도 파드는 계속 Terminating 상태로 남아있으며, 나중에 노드가 다시 복구되면 삭제가 진행되고 새로운 파드가 다시 시작될 것이다.
만약 노드가 복구될 수 없다고 판단되면 kubectl delete --force --grace-period=0 옵션을 추가해서 강제로 삭제시킨다.

거버닝 서비스

StatefulSet 파드는 각 파드마다 다르게 다뤄질 수 있으며, 이 때문에 각 파드마다 안정적인 네트워크를 보장해야 하며 거버닝 헤드리스 서비스를 이용해 이를 지원한다.
StatefulSet의 serviceName에 값을 적으면 된다. 만약 test라고 적고, 파드이름이 pod-0이라면 파드의 dns는 pod-0.test.네임스페이스.svc.cluster.local이 된다. 기존에 파드 DNS(pod-id-address.namespace.pod.cluster.local)와 비교하면 변하지 않는 안정적인 네트워크를 보장하고 있음을 알 수 있다.

💡거버닝 서비스를 사용하려면 StatefulSet을 생성하기 전에 헤드리스 서비스가 먼저 생성되어 있어야 한다.

이렇게 생성된 파드 DNS는 Peer Discovering할 때 이용된다. StatefulSet의 파드들은 서로 쉽게 찾을 수 있어야 한다. 파드 DNS로 접근하면 쿠버네티스 API 서버를 거치지 않는다.

파드 업데이트

새로운 버전의 이미지를 업데이트 한다고 해보자. 단순한 업데이트라면 상관없지만 큰 업데이트라면, 데이터의 스키마 변경되는 등의 변화가 있을 수 있다. 이런 상황에서 기존에 실행되고 있는 파드의 이미지를 교체해버리면, PVC에 있는 데이터는 이전 버전 스키마가 계속 있는데 어플리케이션 버전은 업데이트가 되버렸으므로 에러가 발생하고 심각하면 데이터 손실까지 이어질 수 있다.
따라서 업데이트해도 기존에 실행되던 파드들은 영향이 없으며, 새로 생성될 파드만 업데이트된 이미지가 쓰인다. 만약 기존 파드를 삭제하고 다시 띄운다면 새로운 이미지로 뜨게 된다.

0개의 댓글