[k8s] Controller - StatefulSet(sf)

2022. 9. 22. 14:37[ DevOps ]/[ k8s ]

 

 

StatefulSet

StatefulSet은 상태(Pod 이름, Pod 볼륨)를 보존해주는 컨트롤러이다.

 

 

Pod를 생성할 때 NAME 뒤에 추가되는 5자리의 문자는 랜덤으로 생성된 Hash 값이다. 컨트롤러에 의해 만들어진 모든 Pod는 이와 같이 랜덤 해시 값이 붙은 형태로 Pod 이름이 형성된다. 특정 Pod를 지우고 다시 실행되는 Pod의 이름을 보면 이전과 달라진 해시값을 가진다. 즉, Pod의 이름이 보장되지 않는다는 것을 의미한다.

 

이전까지 배운 컨트롤러는 'Pod의 개수를 보장'해주었지만 Pod의 이름을 보장해주지는 않았다. StatefulSet은 다른 컨트롤러와 다르게 아래 두 가지를 보장해주는 컨트롤러이다.

 

1) Pod 이름

2) Pod 저장소 (스토리지, 볼륨)

 

Pod 이름을 어떻게 보장해주는가

StatefulSet 타입으로 Pod를 3개 실행해달라는 요청을 보내면 Pod의 이름은 순서대로 0번부터 시작하여 순차적으로 증가한다. scale-out 시에는 Pod 순서가 순차적으로 증가하고, scale-in을 하면 숫자가 가장 큰 Pod를 먼저 삭제하는 방식으로 동작한다.

 

cf. 특정 Pod에 문제가 생긴다면?

만약 0, 1, 2번 Pod가 운영 중이고 1번 Pod에 문제가 생겼다면 1번 Pod가 완전히 삭제될 때까지 기다렸다가 1번이라는 이름을 가진 Pod를 그대로 다시 실행시킨다. 알아 두어야 할 것은 StatefulSet은 DaemonSet과 다르게 노드 당 1개의 Pod를 보장하지는 않는다는 것이다. 즉, 어느 노드에 Pod가 다시 실행될지는 모른다. StatefulSet은 Pod 이름을 보장하는 역할을 한다는 것을 기억해야 한다. 이렇듯 StatefulSet 컨트롤러를 사용하면 Pod의 이름을 보장해줌으로써 몇 번의 Pod가 생성되고 삭제될 것인지를 쉽게 알 수 있다는 장점이 있다.

 

 

cf. StatefulSet은 Rolling Update도 지원한다.

 

 


 

rs vs sf Definition

 

 


 

 

실습

- statefulset-exam.yaml 파일 

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sf-nginx
spec:
  replicas: 3
  serviceName: sf-service
#  podManagementPolicy: OrderedReady
  podManagementPolicy: Parallel
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14

출처: https://github.com/237summit/Getting-Start-Kubernetes/blob/main/6/statefulset-exam.yaml

 

 

- type 필드에 'StatefulSet'을 사용한다.

- replicas를 사용한다.

- serviceName: 서비스 이름과 Pod 이름을 연결시켜서 CoreDNS를 사용하게 된다. (이 부분은 추후 Service 관련 포스팅에서 다룰 예정)

- podManagementPolicy: 'OrderedReady'가 default 값이다. OrderedReady는 순차적으로 0번 Pod 생성 성공 시 1번을 만들고 이를 반복하는 원리이다. 'Parallel'을 사용할 수도 있는데, 이는 0, 1, 2,... 번 Pod를 병렬적으로 동시에 실행시킨다.

 

 

StatefulSet 실행 후 결과 확인

- 위와 같이 Pod가 0번부터 시작하여 순차적으로 이름이 생성되었다.

 

 

Pod 삭제 후 결과 확인

- 1번 Pod를 삭제한 결과 완전히 삭제된 후, '같은 이름'으로 다시 시작되었음을 확인할 수 있다.

- 특히, 기존에는 node2에서 실행되었으나 지금은 node1에서 실행되었다. 즉, StatefulSet은 노드의 위치는 보장하지 않는다.

 

 

Scale-Out 후 결과 확인

- replicas를 2개 더 늘려주었더니 Pod 이름이 순차적으로 증가했음을 확인할 수 있다.

 

 

Scale-In 후 결과 확인

- replicas를 2로 줄였더니 0번과 1번만 남게 되었다.

- 오해하지 말아야 할 것은 숫자가 큰 것부터 삭제되었다고 해서 가장 최근의 것이 삭제된 것은 아니다. 위에서 1번 Pod를 재시작해서 1번 Pod가 2번 Pod보다 더 최신의 상태이지만 2번 Pod가 삭제되었다. 

- 즉, scale-in 시에는 Pod 번호가 가장 큰 것을 기준으로 삭제한다.

 

 


 

StatefulSet의 Rolling Update

- edit 커맨드로 실행 중인 StatefulSet을 수정한다.

- template -> spec -> containers -> image: nginx:1.15

 

- 정상적으로 Rolling Update가 되었음을 확인할 수 있다.

 

 

StatefulSet의 Rollback

- DaemonSet, Deployment와 마찬가지로 rollout undo 커맨드를 사용한다.

 

 

 

 

 

Reference

- 따배쿠, https://youtu.be/Mx3y9un1KeI

- k8s StatefulSets docs, https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/

 

 

 

 

'[ DevOps ] > [ k8s ]' 카테고리의 다른 글

[k8s] Controller - CronJob  (0) 2022.10.01
[k8s] Controller - Job  (0) 2022.09.27
[k8s] Controller - DaemonSet  (0) 2022.09.16
[k8s] Controller - Deployment와 Rolling Update  (0) 2022.09.11
[k8s] Controller - ReplicaSet(RS)  (0) 2022.09.11