emeraldgoose / kubernetes_study

Kubernetes In Action
0 stars 0 forks source link

10장. 스테이트풀셋: 복제된 스테이트풀 애플리케이션 배포하기 #10

Open emeraldgoose opened 8 months ago

emeraldgoose commented 8 months ago

10.1 스테이트풀 파드 복제하기

동일 레플리카셋의 모든 파드는 항상 같은 퍼시스턴트볼륨클레임과 퍼시스턴트볼륨을 사용하게 되는데 각 인스턴스가 별도의 스토리지를 필요로 하는 분산 데이터 저장소를 실행하려면 레플리카셋을 사용할 수 없다. 파드 인스턴스별로 하나의 레플리카셋을 사용하는 방법이 있지만 번거롭다. 사용할 수 있는 한 가지 방법은 모든 파드가 동일한 퍼시스턴트볼륨을 사용하고 볼륨 내부에 별도의 디렉토리를 갖게 하는 것이다. 그러나 인스턴스 간 조정이 필요하고 공유 스토리지 볼륨에 병목 현상이 발생한다.

emeraldgoose commented 8 months ago

10.2 스테이트풀셋 이해하기

스테이트풀셋은 애플리케이션의 인스턴스가 각각 안정적인 이름과 상태를 가지며 개별적으로 취급돼야 하는 애플리케이션에 맞게 만들어졌다. 스테이트풀셋은 파드가 아이덴티티와 상태를 유지하면서 다시 스케줄링되게 한다.

스테이트풀셋으로 생성된 파드는 서수 인덱스(0부터 시작)가 할당되고 파드의 이름과 호스트 이름, 안정적인 스토리지를 붙이는 데 사용된다. 스테이트풀셋은 거버닝 헤드리스 서비스(governing headless service)를 생성해서 각 파드에게 실제 네트워크 아이덴티티를 제공한다. 이 서비스를 통해 각 파드는 자체 DNS 엔트리를 가지며 클러스터의 피어 혹은 클러스터의 다른 클라이언트가 호스트 이름을 통해 파드의 주소를 지정할 수 있다.

스테이트풀셋을 스케일링하면 사용하지 않는 다음 서수 인덱스를 가진 새로운 파드 인스턴스를 생성한다. 스케일 다운을 하면 가장 높은 서수 인덱스를 가진 파드를 먼저 제거한다. 만약 인스턴스 중 하나라도 비정상인 경우 스케일 다운 작업을 허용하지 않는다. 인스턴스 하나가 정상적으로 동작하지 않는 시점에 인스턴스 하나를 스케일 다운하는 경우, 두 개의 클러스터 멤버를 잃기 때문이다.

스테이트풀셋이 파드를 생성하는 것과 같은 방식으로 퍼시스턴트볼륨클레임 또한 생성해야 한다. 각 파드와 함께하는 퍼시스턴트볼륨클레임을 복제하는 하나 이상의 볼륨 클레임 템플릿을 가질 수 있다. 스테이트풀셋을 스케일 업하면 파드와 클레임을 생성하지만 스케일 다운하면 파드만 삭제한다. 클레임이 삭제된 경우 바인딩됐던 퍼시스턴트볼륨은 재활용되거나 삭제돼 콘텐츠가 손실될 수 있기 때문이다. 이런 이유로 기반 퍼시스턴트볼륨을 해제하려면 퍼시스턴트볼륨클레임을 수동으로 삭제해야 한다. 스케일 다운 후 다시 스케일 업하면 퍼시스턴트볼륨에 바인딩된 동일한 클레임을 다시 연결할 수 있다.

쿠버네티스는 두 개의 스테이트풀 파드 인스턴스가 절대 동일한 아이덴티티로 실행되지 않고 동일한 퍼시스턴트볼륨클레임에 바인딩되지 않도록 보장한다. 이것은 스테이트풀 파드 인스턴스의 최대 하나의 의미(at-most-one semantics)를 보장해야 한다. 스테이트풀셋은 교체 파드를 생성하기 전에 파드가 더 이상 실행 중이지 않는다는 점을 확신해야 한다.

emeraldgoose commented 8 months ago

10.3 스테이트풀셋 사용하기

스테이트풀셋을 통한 애플리케이션을 배포하려면 오브젝트 두 가지 또는 세 가지를 생성해야 한다.

만약 스테이트풀셋을 세 개의 레플리카까지 스케일링하려면 세 개의 퍼시스턴트볼륨이 필요하다. 다음은 퍼시스턴트볼륨을 생성하는 예제이다.

apiVersion: v1
kind: List
items:
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name:
  spec:
    ...
  persistentVolumeReclaimPolicy: Recycle # 클레임에서 볼륨이 해제되면 다시 사용해 재사용된다.
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name:
  spec:
    ...
- ...

스테이트풀셋을 배포하기 전에 먼저 헤드리스 서비스를 생성해야 한다.

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

이제 스테이트풀셋을 생성한다.

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name:
spec:
  serviceName:
  replicas:
  template:
    metadata:
      labels:
        ...
    spec:
      containers:
        ...
        volumeMounts:
        - name: data
          mountPath: /var/data
volumeClaimTemplates:
- metadata: # 이 템플릿으로 퍼시스턴트볼륨클레임이 생성된다
    name:  data
  spec:
    resources:
  ...
emeraldgoose commented 8 months ago

10.4 스테이트풀셋의 피어 디스커버리

스테이트풀셋의 각 멤버는 모든 다른 멤버를 쉽게 찾을 수 있어야 한다. SRV 레코드는 특정 서비스를 제공하는 서버의 호스트 이름과 포트를 가리키는 데 사용된다. 쿠버네티스는 헤드리스 서비스를 뒷받침하는 파드의 호스트 이름을 가리키도록 SRV 레코드를 생성한다. 스테이트풀셋을 스케일 업하거나 스케일 다운하더라도 클라이언트 요청을 서비스하는 파드는 항상 그 시점에 모든 피어를 찾을 수 있다.

emeraldgoose commented 8 months ago

10.5 스테이트풀셋이 노드 실패를 처리하는 과정 이해하기

스테이트풀셋은 노드가 실패한 경우 동일한 아이덴티티와 스토리지를 가진 두 개의 파드가 절대 실행되지 않는 것을 보장하므로, 스테이트풀셋은 파드가 더 이상 실행되지 않는다는 것을 확신할 때까지 대체 파드를 생성할 수 없다.

노드의 네트워크가 끊어지면 노드에 실행 중인 Kubelet이 더 이상 쿠버네티스 API서버와 연결할 수 없고, 노드는 모든 해당 파드가 여전히 실행 중임을 알릴 수 없다. 컨트롤 플레인은 노드를 NotReady로 표시하고 노드의 있는 모든 파드의 상태를 Unknown으로 표시한다. 노드가 다시 온라인 상태로 돌아오면 파드는 다시 Running으로 표시되지만 몇 분이 지나도 Unknown 상태라면 마스터(컨트롤 플레인)는 자동으로 노드에서 제거한다. 파드를 수동으로 삭제할 때 삭제되지 않는다면 강제 삭제 옵션인 --force --grace-period 0을 사용해본다.