쿠버네티스에서 StatefulSet은 stateful한 애플리케이션을 배포하기 위한 컨트롤러입니다. StatefulSet은 각각의 파드에 고유한 식별자를 할당하고, 일관된 네트워크 식별자를 유지함으로써 stateful한 애플리케이션에 대한 지속적인 데이터 보존성을 제공합니다.
StatefulSet은 다음과 같은 상황에서 사용될 수 있습니다.
데이터베이스 서비스 (MySQL, PostgreSQL 등)
메시징 큐 (Kafka, RabbitMQ 등)
분산 파일 시스템 (Ceph, GlusterFS 등)
반면에 stateless한 애플리케이션은 상태를 유지하지 않는 애플리케이션입니다. Stateless 애플리케이션은 새로운 요청이 들어올 때마다 동일한 응답을 반환하는 것이 목적입니다. 예를 들어, 웹 서버 애플리케이션은 주로 stateless하게 설계됩니다.stateful과 stateless의 차이점은 주로 상태의 유무에 있습니다. stateful한 애플리케이션은 데이터를 유지하고, 일관된 상태를 유지하며, 네트워크 식별자를 유지합니다. 반면에, stateless한 애플리케이션은 데이터를 유지하지 않고, 각 요청에 대해 새로운 응답을 반환합니다. 이러한 차이점으로 인해, stateful한 애플리케이션은 주로 데이터베이스나 분산 시스템과 같은 백엔드 서비스에서 사용되며, stateless한 애플리케이션은 주로 웹 서버와 같은 프론트엔드 서비스에서 사용됩니다.
kubectl apply -f https://raw.githubusercontent.com/kubetm/kubetm.github.io/master/yamls/longhorn/longhorn-1.3.3.yaml
master 노드에 설치하면 됨.
만약 각 노드에 iscsi가 설치 안되어 있다면 , yum install -y iscsi-initiator-utils 설치
그리고 yum install -y iscsi-initiator-utils 명령어를 이용해 확인
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: driver.longhorn.io
parameters:
dataLocality: disabled
fromBackup: ""
fsType: ext4
numberOfReplicas: "1"
staleReplicaTimeout: "30"
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1G
accessModes:
- ReadWriteOnce
hostPath:
path: /hostpath
type: DirectoryOrCreate
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity:
storage: 2G
accessModes:
- ReadWriteOnce
hostPath:
path: /hostpath
type: DirectoryOrCreate
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-01
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
storageClassName: ""
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-02
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
storageClassName: "fast"
pv가 알아서 생성되면서 연결이 됨.
근데 여기에 스토리지 클래스를 아예 지정안해버리면
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-03
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2G
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1G
storageClassName: "fast"
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
spec:
containers:
- name: container
image: ddarahakit2023/hello:8000
volumeMounts:
- name: hostpath
mountPath: /mount1
volumes:
- name : hostpath
persistentVolumeClaim:
claimName: pvc
위의 그림처럼 Volume 카테고리에 들어가 보면 잘 동작하는것을 확인할 수 있다.
서로 다른 노드에서 실행이 되는데, 같은 볼륨을 공유하고 싶다면, ReadWriteMany로 설정.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2G
storageClassName: "fast"
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
spec:
nodeSelector:
kubernetes.io/hostname: node1
containers:
- name: container
image: ddarahakit2023/hello:8000
volumeMounts:
- name: hostpath
mountPath: /mount1
volumes:
- name : hostpath
persistentVolumeClaim:
claimName: pvc
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath2
spec:
nodeSelector:
kubernetes.io/hostname: node2
containers:
- name: container
image: ddarahakit2023/hello:8000
volumeMounts:
- name: hostpath
mountPath: /mount1
volumes:
- name : hostpath
persistentVolumeClaim:
claimName: pvc
kind: Service
metadata:
name: headless1
spec:
selector:
svc: headless
ports:
- port: 8000
targetPort: 8080
clusterIP: None
흔히 웹 서비스는 Stateless한 서비스이다.
하지만 db는 Stateful한 서비스이다.
컨트롤러에서 우리가 흔히 사용한 것이 레플리카 셋으로서, 자동으로 복제품을 만들어 서버를 늘리는 방식을 사용했다.
하지만 이렇게 statefulset으로 만들면 파드를 생성하더라도 이름이 랜덤하게 생기지 않음.
Replicaset은 파드의 이름이 랜덤으로 생성되고 순서가 없지만 Statefulset은 이름에 인덱스 번호가 붙고 순서를 가진다.
Replicaset은 파드가 삭제되고 다시 생성되면 대부분의 정보가 새로 생성되지만 Statefulset은 유지된다.
Replicaset은 PVC로 볼륨을 연결할 때 PVC가 미리 생성되어있어야 하지만 Statefulset은 동적으로 PVC 생성 가능
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replica-test
spec:
replicas: 1
selector:
matchLabels:
type: web
template:
metadata:
labels:
type: web
spec:
containers:
- name: container
image: ddarahakit2023/hello:8000
terminationGracePeriodSeconds: 10
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: statefulset-test
spec:
replicas: 1
selector:
matchLabels:
type: db
template:
metadata:
labels:
type: db
spec:
containers:
- name: container
image: ddarahakit2023/hello:8000
terminationGracePeriodSeconds: 10
이건 statefulset 컨트롤러를 만드는 코드이다.
흔히 레플리카셋 컨트롤러를 이용하는 서버는 웹이다.
statefulset 컨트롤러를 이용하는 서버는 db이다.