June 
	   7th,
	   
	   2023
	 
	  
	  
		  
		
		
		  
		
		
      
    
    
		
		
	
	
	
스테이트풀셋
기존 레플리카셋
레플리카셋이 파드 복제본을 생성할 때 파드의 이름과 IP만 다를 뿐 모두 똑같은 파드를 생성한다. 만약 파드가 PVC를 참조한다면 역시 똑같은 PVC를 연결하게 된다. 해당 PVC는 특정한 하나의 PV에만 연결되어 있다. 기존 컨트롤러에서 각 파드가 분리된 저장소 볼륨을 사용해야 한다면 스테이트풀셋을 사용할 수 있다.
스테이트풀셋
- 애플리케이션의 스테이트풀을 관리하는데 사용하는 워크로드 API 오브젝트다
 - deployment의 파드 scale을 관리하면서 파드들의 순서를 보장한다
 - deployment와 유사하게 동일한 컨테이너 스펙을 기반으로 둔 파드들을 관리한다.
 - deployment와 다르게 각 파드의 독자성을 유지한다
 - 각 파드들은 동일한 스펙으로 생성되어도 교체는 불가능하다
 - 스케줄링 간에도 지속적으로 유지되는 식별자를 가진다
 - volumeClaimTemplates를 사용해 PVC를 자동으로 생성할 수 있다
 - 각 파드가 순서대로 생성되기 때문에 고정된 이름, 볼륨, 설정을 가질 수 있다
 

- stateful 애플리케이션은 primary 메인 db가 있고 secondary로 primary가 죽으면 대체할 db가 존재하고 이를 감시하는 arbiter가 있다
 - 아비터가 죽으면 아비터 역할을 살려줘야 한다
 - 각각 역할마다 볼륨을 사용하기 때문에 기존에 사용하던 볼륨에 접근해야 해당 역할을 이어갈 수 있다
 
사용처
다음과 같은것에 유용하다
- 유니크한 네트워크 식별자
 - 퍼시스턴트 스토리지
 - graceful 배포와 스케일링
 - 자동 롤링 업데이트
 
위와 같은 식별자 및 순차적인 배포, 삭제 또는 스케일링이 필요하지 않으면 디플로이먼트나 레플리카셋이 더 적절하다고 볼 수 있다.
제한사항
- 파드에 지정된 스토리지는 persistent volume provisioner를 기반으로 하는 storage class를 요청해서 프로비전해야한다.
 - statefulset을 삭제 또는 스케일 다운을 하더라도 스테이트풀셋과 연관된 볼륨이 삭제되지 않는다.
 - 현재 파드의 네트워크 식별자를 책임지고 있는 헤드리스 서비스가 필요하다
 - 롤링 업데이트와 기본 파드 관리 정책을 함께 사용하면 파손상태로 빠질 수 있다.
 
헤드리스 서비스
스테이트풀셋은 헤드리스 서비스가 필요하다
- 일반적인 서비스는 label selector가 일치하는 랜덤한 포드로 트래픽을 전달한다
 - 스테이트풀셋은 포드가 고유하게 식별되야 한다
 - 헤드리스 서비스는 서비스의 이름으로 포드의 접근 위치를 알아내기 때문에 서비스의 이름과 포드의 이름을 통해 포드에 직접 접근한다
 

예제
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp-sts
spec:
  selector:
    matchLabels:
      app: myapp-sts
  serviceName: myapp-svc-headless
  replicas: 2
  template:
    metadata:
      labels:
        app: myapp-sts
    spec:
      containers:
      - name: myapp
        image: ghcr.io/c1t1d0s7/go-myweb
        ports:
        - containerPort: 8080
스테이트 풀셋 yaml 예제이다 kind가 StatefulSet인거를 제외하면 다른 ReplicaSet과 유사하다
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc-headless
  labels:
    app: myapp-svc-headless
spec:
  ports:
  - name: http
    port: 80
  clusterIP: None
  selector:
    app: myapp-sts
스테이트풀셋에서 사용할 헤드리스 서비스다
clusterIP를 None으로 설정해 헤드리스 서비스를 구성한다. 적용은 kubectl create나 apply로 실행하면 된다
이후 curl 파드이름.서비스이름으로 :포트로 요청을 보내면 해당 파드에서만 응답이 오는 것을 확인할 수 있다