kubernetes

[따배쿠] Controller - StatefulSet

bbiyak2da 2024. 12. 5. 16:25

StatefulSet

  • Pod의 상태를 유지해주는 Controller
    • Pod 이름
    • Pod의 볼륨 (스토리지)
  • StatefulSet으로 Pod 생성 시, 0번부터 생성된다. ex) ns-nginx-0, ns-nginx-1, ns-nginx-2

 

StatefulSet Definition

 

StatefulSet은 serviceName이라는 Field를 가지고 있다.

 

예시

 

# statefulset-exam.yaml 파일 작성

root@master:~/Getting-Start-Kubernetes/6# cat 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

 

*podManagedPolicy : OrderedReady (Default 값)

pod 생성 시, 순차적으로 0번 만드는게 성공하면 1번 생성, 1번 만드는게 성공하면 2번 생성 …

*podManagedPolicy : Parallel

 

pod 생성 시, 0번 1번 2번을 동시에 생성

 

# 생성 및 확인

root@master:~/Getting-Start-Kubernetes/6# kubectl create -f statefulset-exam.yaml
statefulset.apps/sf-nginx created
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
sf-nginx-0   1/1     Running   0          3s    192.168.104.8     node2   <none>           <none>
sf-nginx-1   1/1     Running   0          3s    192.168.104.7     node2   <none>           <none>
sf-nginx-2   1/1     Running   0          3s    192.168.166.144   node1   <none>           <none>

 

# 삭제 후 확인

root@master:~/Getting-Start-Kubernetes/6# kubectl delete pod sf-nginx-0
pod "sf-nginx-0" deleted
root@master:~/Getting-Start-Kubernetes/6# ^C
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
sf-nginx-0   1/1     Running   0          1s    192.168.104.9     node2   <none>           <none>
sf-nginx-1   1/1     Running   0          85s   192.168.104.7     node2   <none>           <none>
sf-nginx-2   1/1     Running   0          85s   192.168.166.144   node1   <none>           <none>

 

sf-nginx-0 pod를 삭제해도, 똑같은 이름으로 다시 생성된다.

왜냐면 StatefulSet의 속성으로 pod의 이름을 보장해주기 때문이다. ex) sf-nginx-XX

즉 0번이 지워지면 0번이 다시 생성된다.

 

DaemonSet과 다른 점은, StatefulSet은 node당 한 개의 pod만 보장하지 않는다는 점이다.

위의 예시와 같이 한 node에 두 개의 pod가 생성될 수 있다.

 

다른 Controller와 다른 점은, pod name을 지정할 수 있다는 점이다.

예를 들면 ReplicationController로 생성시 pod name이 random hash 값으로 붙는다.  ex) sf-nginx-skdjfd 

 

예시2 (daemonSet scaling)

 

# DaemonSet scale in

root@master:~/Getting-Start-Kubernetes/6# kubectl scale statefulset sf-nginx --replicas=4
statefulset.apps/sf-nginx scaled

 

replicas 수를 3에서 4로 바꿔보자

 

# 확인

root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE     IP                NODE    NOMINATED NODE   READINESS GATES
sf-nginx-0   1/1     Running   0          7m2s    192.168.104.9     node2   <none>           <none>
sf-nginx-1   1/1     Running   0          8m26s   192.168.104.7     node2   <none>           <none>
sf-nginx-2   1/1     Running   0          8m26s   192.168.166.144   node1   <none>           <none>
sf-nginx-3   1/1     Running   0          98s     192.168.166.147   node1   <none>           <none>

 

# DaemonSet scale out

root@master:~/Getting-Start-Kubernetes/6# kubectl scale statefulset sf-nginx --replicas=2
statefulset.apps/sf-nginx scaled

 

# 확인

root@master:~/Getting-Start-Kubernetes/6# kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE     IP              NODE    NOMINATED NODE   READINESS GATES
sf-nginx-0   1/1     Running   0          8m5s    192.168.104.9   node2   <none>           <none>
sf-nginx-1   1/1     Running   0          9m29s   192.168.104.7   node2   <none>           <none>

 

pod 2, 3번이 삭제되었다.

 

예시2 (daemonSet Rolling update)

 

# kubectl edit 으로 이미지 버전 수정

root@master:~/Getting-Start-Kubernetes/6# kubectl edit statefulset.apps sf-nginx

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: "2024-12-05T07:53:49Z"
  generation: 4
  name: sf-nginx
  namespace: default
  resourceVersion: "245455"
  uid: ef624b46-e2dc-402f-b614-c742c1667d3a
spec:
  persistentVolumeClaimRetentionPolicy:
    whenDeleted: Retain
    whenScaled: Retain
  podManagementPolicy: Parallel
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: webui
  serviceName: sf-service
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: webui
      name: nginx-pod
    spec:
      containers:
      - image: nginx:1.15
        imagePullPolicy: IfNotPresent
        name: nginx-container
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate
status:
  availableReplicas: 2
  collisionCount: 0
  currentReplicas: 2
  currentRevision: sf-nginx-7c9755b47
  observedGeneration: 4
  readyReplicas: 2
  replicas: 2
  updateRevision: sf-nginx-7c9755b47
  updatedReplicas: 2

 

# 확인

root@master:~/Getting-Start-Kubernetes/6# kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
sf-nginx-0   1/1     Running   0          7s
sf-nginx-1   1/1     Running   0          10s
root@master:~/Getting-Start-Kubernetes/6# kubectl describe pod sf-nginx-0
Name:             sf-nginx-0
Namespace:        default
Priority:         0
Service Account:  default
Node:             node2/10.100.0.102
Start Time:       Thu, 05 Dec 2024 08:07:13 +0000
Labels:           app=webui
                  apps.kubernetes.io/pod-index=0
                  controller-revision-hash=sf-nginx-7c9755b47
                  statefulset.kubernetes.io/pod-name=sf-nginx-0
Annotations:      cni.projectcalico.org/containerID: 7eedc38f202d27206458bf789687d1346cbb9b617247a95f24c30f4cb1c3f171
                  cni.projectcalico.org/podIP: 192.168.104.10/32
                  cni.projectcalico.org/podIPs: 192.168.104.10/32
Status:           Running
IP:               192.168.104.10
IPs:
  IP:           192.168.104.10
Controlled By:  StatefulSet/sf-nginx
Containers:
  nginx-container:
    Container ID:   containerd://d00eb9a5f3515070ee685172a052b02529c9b52814365b98e674ead1d9846e2a
    Image:          nginx:1.15
    Image ID:       docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Thu, 05 Dec 2024 08:07:13 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-mbjzp (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       True
  ContainersReady             True
  PodScheduled                True
Volumes:
  kube-api-access-mbjzp:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  26s   default-scheduler  Successfully assigned default/sf-nginx-0 to node2
  Normal  Pulled     26s   kubelet            Container image "nginx:1.15" already present on machine
  Normal  Created    26s   kubelet            Created container nginx-container
  Normal  Started    26s   kubelet            Started container nginx-container

 

daemonSet도 Rolling update가 가능하다.

 

# rollback

 

root@master:~/Getting-Start-Kubernetes/6# kubectl rollout undo statefulset sf-nginx
statefulset.apps/sf-nginx rolled back
root@master:~/Getting-Start-Kubernetes/6# kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
sf-nginx-0   1/1     Running   0          40s
sf-nginx-1   1/1     Running   0          42s
root@master:~/Getting-Start-Kubernetes/6# kubectl describe pod sf-nginx-0
Name:             sf-nginx-0
Namespace:        default
Priority:         0
Service Account:  default
Node:             node2/10.100.0.102
Start Time:       Thu, 05 Dec 2024 08:10:07 +0000
Labels:           app=webui
                  apps.kubernetes.io/pod-index=0
                  controller-revision-hash=sf-nginx-66f56bb7cb
                  statefulset.kubernetes.io/pod-name=sf-nginx-0
Annotations:      cni.projectcalico.org/containerID: 73b20e501a203566ff88ebe715b5f4a26c3949fa97aca2e87f4b044e4b86074e
                  cni.projectcalico.org/podIP: 192.168.104.11/32
                  cni.projectcalico.org/podIPs: 192.168.104.11/32
Status:           Running
IP:               192.168.104.11
IPs:
  IP:           192.168.104.11
Controlled By:  StatefulSet/sf-nginx
Containers:
  nginx-container:
    Container ID:   containerd://7f4f2d1055da19e23fff29bea7cc41032a25823fb676aa073d683757cecb12dc
    Image:          nginx:1.14
    Image ID:       docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Thu, 05 Dec 2024 08:10:08 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-p7h99 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       True
  ContainersReady             True
  PodScheduled                True
Volumes:
  kube-api-access-p7h99:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  44s   default-scheduler  Successfully assigned default/sf-nginx-0 to node2
  Normal  Pulled     43s   kubelet            Container image "nginx:1.14" already present on machine
  Normal  Created    43s   kubelet            Created container nginx-container
  Normal  Started    43s   kubelet            Started container nginx-container

 

nginx:1.14로 rollback이 된 것을 확인 가능하다.


참고 영상

https://www.youtube.com/watch?v=Mx3y9un1KeI