Stateful Sets

  • Pod template 으로 생성, 스케일업 다운이 가능해서 deployment 와 비슷함
  • Pod에 저장된 데이터 또는 Pod의 설정을 stateful하게 유지해야 하는 경우 사용됨
  • Stateful Set은 스케쥴링 될 Pod에 특정 규칙에 따라 유니크한 인덱스를 부여함
    • 이렇게 생성된 Pod는 재생성 되는 상황에서도 랜덤한 문자열이 아닌 규칙에 따른 이름이 부여됨
  • 따라서 인덱스에 따라 Pod 스케줄링에 순서 또는 특정한 패턴을 부여할 수 있음
  • Stateful Set으로 생성한 Pod의 스토리지는 PVC로만 연결 가능

Stateful Set이 필요한 이유

  • 인스턴스들이 특정 순서로 실행되어야 하는 경우
    • 예) 멀티노드 구조로 데이터베이스를 구축하고자 할 때 - Master 노드 먼저 생성 → Slave 노드 이후 생성
  • Pod 이름, 네트워크 등의 정보를 초기화하지 않고, 유지해야 하는 경우

Stateful Set 생성 방법

ex) statefulset-definition

apiVersion: apps/v1
kind: StatefulSet
metadata:
	name: mysql
	labels:
		app: mysql
		
		
spec:
	template:
		metadata:
			labels:
				app: mysql
		spec:
			containers: 
			- name: mysql
				image: mysql
				
	replicas: 3
	selector:
		matchLabels:
			app: mysql
			
			
	serviceName: mysql-h # 서비스 이름 지정
	
	podManagementPolicy: OrderedReady # default. 순서대로 배포. "Parallel" 일 경우 병렬로 배포

Headless Service

  • 로드밸런싱의 역할로 Service를 연결하는 경우, Service의 역할은 들어온 요청을 여러 개의 Pod 중 하나에만 전달하는 것임.
  • 하지만 요청을 모든 pod에 전달해야 하는 경우에는 적합하지 않음.
    • 예) 멀티노드 데이터베이스에서 read를 할 경우 하나의 Pod에만 접근하면 되지만, 쓰기를 수행하고자 하는 경우에는 모든 Pod에 쓰기를 해야 함
  • 특히 StatefulSet에 의해 생성된 Pod들은 service를 이용해서 로드 밸런싱을 하는 것이 아니기 때문에 로드 밸런서의 역할은 필요없고 논리적으로 pod들을 묶어 줄 수 있는 service만 있으면 되기 때문에 헤드리스 서비스를 사용함.

Headless Service 생성하기

Headless Service 정의

# ex) headless-service-definition.yaml

apiVersion: v1
kind: Service
metadata:
	name: mysql-h
	
spec:
	ports:
		- port: 3306
		
	selector:
		app: mysql
		
	clusterIP: None

Pod 정의

ex) pod-definition.yaml

apiVersion: v1
kind: Pod
metadata:
	name: mysql-pod
	labels:
		app: mysql
		
spec:
	containers:
		- name: mysql
			image: mysql
			
	subdomain: mysql-h
	hostname: mysql-pod

Stateful Set 정의

apiVersion: apps/v1
kind: StatefulSet
metadata:
	name: mysql-deployment
	labels:
		app: mysql
		
spec:
	serviceName: mysql-h  # headless service name 으로 연결
	replicas: 3
	matchLabels:
		app: mysql
		
	template:
		metadata:
			name: mysql-pod
			labels:
				app: mysql
				
		spec:
			containers:
				- name: mysql
					image: mysql
					
  • 클러스터 IP 가 없는 것이 Headless Service의 핵심
  • 대신 Service 에 대한 DNS Lookup 요청이 DNS 서버에 오게 될 때, Service 에 소속된 Pod IP 주소 목록을 전부 반환함
  • 위의 예시에서 spec.hostname과 spec.subdomain 을 통해 DNS 레코드가 생성됨

Stateful Set에서의 Storage

  • StatefulSet 상황에서 StorageClass 를 통해 동적 프로비저닝으로 PV의 생성이 자동화 된 상태에서, PVC또한 마찬가지로 이에 맞게 생성하고자 한다면 VolumeClaimTemplate 을 사용함.
    • VolumeClaimTemplate: PVC의 템플릿화된 PVC 명세로서, Pod template 처럼 StatefulSet에 기재하면 됨
  • 이렇게 생성된 PV/PVC 는 나중에 Pod가 삭제되어도, 해당 Pod가 재생성되었을 때 직전에 사용되었던 Storage를 똑같이 연결해야하기 때문에 Pod 삭제 시 함께 삭제되지 않음

Resource