스테이트풀셋 (Statefulset)

niyu·2022년 8월 3일
0

쿠버네티스 기초

목록 보기
12/15
post-thumbnail

레플리카셋, 디플로이먼트는 모두 상태가 없는 파드들을 관리하는 용도였다. 스테이트풀셋은 상태가 있는 파드들을 관리하는 컨트롤러이다.

스테이트풀셋을 사용하면 볼륨을 사용해서 특정 데이터를 저장한 후 파드를 재시작했을 때 해당 데이터를 유지한다.

스테이트풀 파드 복제

스테이트풀 파드를 복제할 때 레플리카셋을 이용한다면 어떨까? 레플리카셋을 사용해 데이터베이스 파드를 복제할 수 있을까?

레플리카셋은 하나의 파드 템플릿에서 여러 개의 파드 복제본을 생성한다. 여러 개의 파드 복제본을 복제하는 데 사용하는 파드 템플릿에는 특정 퍼시스턴트볼륨클레임에 관한 참조가 있기 때문에 각 복제본은 별도의 퍼시스턴트볼륨클레임을 사용하도록 만들 수가 없다.

동일한 레플리카셋의 모든 파드는 항상 동일한 PVC와 PV를 사용
동일한 레플리카셋의 모든 파드는 항상 동일한 PVC와 PV를 사용 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/10)

각 복제본이 고유한 퍼시스턴트볼륨클레임을 사용하도록 설정할 수 없다.

스테이트풀셋

스테이트풀셋과 레플리카셋 비교

🐮 레플리카셋: 가축
레플리카셋으로 관리하는 파드 복제본은 가축과 같다. 농부가 병이 든 소를 대체하는 것처럼 이름을 정확히 알고 있을 필요가 없고 몇마리가 있는지만 중요하다.

복제본은 stateless하기 때문에 언제든지 완전히 새로운 파드 복제본으로 교체할 수 있다.

🐶 스테이트풀셋: 애완동물
스테이트풀셋으로 관리하는 파드 복제본은 애완동물과 같다. 애완동물이 죽으면 새 애완동물을 사러갈 수 없고 새 애완동물은 기존 애완 동물과 다르다.

스테이트풀셋은 각 인스턴스에 이름을 부여하고 개별적으로 관리한다. 또한 스테이트풀 파드 인스턴스가 종료되면 새로운 파드 인스턴스는 교채되는 이름, 네트워크 ID, 상태 그대로 다른 노드에서 되살아난다. 스테이트풀셋으로 복제된 파드는 자신만의 볼륨 상태를 가지기때문에 스토리지는 다른 스토리지와 구별된다.

레플리카셋과 스테이트풀셋
레플리카셋과 스테이트풀셋 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/10)

레플리카셋의 파드의 이름은 임의의 이름을 가지지만, 스테이트풀셋의 파드의 이름은 예측가능하다.

스테이트풀셋 교체

스테이트풀셋에 의해 관리되는 파드 인스턴스가 사라지면 스테이트풀셋은 새 인스턴스로 교체한다. 이때 대체 파드는 사라진 파드와 동일한 이름 및 호스트 이름을 갖는다. 파드가 다른 노드로 재스케줄링되더라도 같은 클러스터 내에서 동일한 호스트 이름으로 접근이 가능하다.

레플리카셋과 스테이트풀셋의 파드 교체
레플리카셋과 스테이트풀셋의 파드 교체 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/10)

PVC 생성과 삭제

스테이트풀셋은 파드를 생성하는 것과 동일한 방법으로 퍼시스턴스볼륨클레임을 생성한다. 스테이트풀셋은 볼륨 클레임 템플릿을 하나 이상 가질 수 있고, 이를 통해 각 파드 인스턴스는 자신만의 퍼시스턴스볼륨클레임을 가지면서 생성된다.

스테이트풀셋의 파드와 PVC 생성
스테이트풀셋의 파드와 PVC 생성 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/10)

생성할 때는 파드와 퍼시스턴스볼륨클레임 등 2개 이상의 오브젝트가 생성되는데, 스케일 다운을 할 때는 파드만 삭제하고 클레임은 남겨둔다. 클레임이 삭제되면 바인딩된 퍼시스턴트볼륨이 재사용되거나 삭제되고 내용이 손실될 수 있기 때문이다. 만약 퍼시스턴트볼륨을 해제하려면 퍼시스턴트볼륨클레임을 수동으로 삭제해야 한다.

스테이트풀셋은 스케인 다운되었을 때 기존에 있던 퍼시스턴스볼륨클레임을 유지했다가 스케일 업될 때 바인딩된 퍼시스턴트볼륨과 그 내용을 새 파드 인스턴스에 다시 연결한다. 실수로 스케일 다운했다면 다시 스케일 업해서 실수를 되돌릴 수 있고, 새 파드는 동일한 이름은 물론 동일한 지속된 상태를 다시 가져올 수 있다.

스테이트풀셋의 스케일다운 및 스케일 업 시의 PVC 연결
스테이트풀셋의 스케일다운 및 스케일 업 시의 PVC 연결 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/10)

최대 한개의 파드 인스턴스 보장

스테이트풀셋은 두 개의 스테이트풀 파드 인스턴스가 동일한 ID로 실행되지 않고 동일한 퍼시스턴스볼륨클레임에 바인드되도록 보장한다. 즉, 노드가 실패한 경우 동일한 ID와 스토리지를 가진 두 개의 파드가 절대 실행되지 않는 것을 보장하기 때문에 스테이트풀셋은 파드가 더 이상 실행되지 않는다는 것을 확실할 때까지 대체 파드를 생성할 수 없으며 생성해서도 안된다.

스테이트풀셋 생성

스테이트풀셋을 통해 어플리케이션을 배포하려면 다음의 객체들을 만들어야 한다.

  • 데이터 파일을 저장하는 퍼시스턴트볼륨
  • 스테이트풀셋에 필요한 관리 서비스
  • 스테이트풀셋

🧩 퍼시스턴트볼륨 생성

kind: List  # 여러개의 리소스를 정의할때 List를 사용할 수 있다
apiVersion: v1
items:
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: pv-a  # 영구 볼륨의 이름은 pv-a, pv-b, pv-c
  spec:
    capacity:
      storage: 1Mi  # 각 영구 볼륨의 용량은 1Mebibyte
    accessModes:
      - ReadWriteOnce
    persistentVolumeReclaimPolicy: Recycle  # 클레임이 볼륨을 해제하면 다시 사용하기 위해 재사용된다
    gcPersistentDisk:  # GCE 영구 디스크를 기본 스토리지 매커니즘으로 사용
      pdName: pv-a
      fsType: nfs4
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: pv-b
...

pv-a, pv-b, pv-c 라는 영구 볼륨을 만든다.

🧩 관리 서비스 생성

apiVersion: v1
kind: Service
metadata:
  name: kubia
spec:
  clusterIP: None  # 스테이트풀셋의 관리 서비스는 헤드리스여야 한다
  selector:
    app: kubia
  ports:
  - name: http
    port: 80

clusterIP 필드를 None으로 설정하면 헤드리스 서비스가 된다. 헤드리스 서비스는 클러스터 IP가 할당되지 않고 kube-proxy가 서비스를 처리하지 않으며 로드 밸런싱이나 프록시 동작을 수행하지 않는다. DNS가 자동으로 구성되는 방법은 서비스에 셀렉터가 정의되어 있는지 여부에 달려있다. 헤드리스 서비스에 셀렉터 필드를 설정하면 쿠버네티스 API로 확인할 수 있는 엔드포인트가 만들어진다.

🧩 스테이트풀셋 생성

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: kubia
spec:
  serviceName: kubia
  replicas: 2
  template:
    metadata:
      labels:  # 스테이트풀셋에 의해 생성된 파드는 app=kubia 레이블을 갖는다
        app: kubia
    spec:
      containers:
      - name: kubia
        image: luksa/kubia-pet
        ports:
        - name: http
          containerPort: 8080
        volumeMounts:  # 파드 내부의 컨테이너는 이 경로에 pvc 볼륨을 마운트한다
        - name: data
          mountPath: /var/data
  volumeClaimTemplates:  # 이 템플릿으로 영구 볼륨 클레임이 작성된다
  - metadata:
      name: data
    spec:
      resources:
        requests:
          storage: 1Mi
      accessModes:
      - ReadWriteOnce

data라는 볼륨 클레임 템플릿 하나를 정의하고 있으며 각 템플릿에 대한 영구 볼륨 클레임을 만드는데 사용된다. 파드는 이 매니페스트에 영구 볼륨 클레임을 포함함으로써 클레임을 참조한다. 파드 템플릿에서는 이러한 볼륨이 없다.

스테이트풀셋은 자동으로 파드 스펙에 추가되고 특정 파드에 생성된 스테이트풀셋의 요청에 바인딩되는 볼륨을 구성한다.

스테이트풀셋을 통한 파드 생성 과정을 보면, 첫번째 파드가 생성되고 준비가 완료되어야만 두 번째 파드가 생성된다. 두 개 이상의 멤버가 동시에 생성되면 레이스 컨디션에 빠질 가능성이 있기 때문에 스테이트풀셋은 순차적으로 하나씩만 처리된다.


References

0개의 댓글