Workload Management에 대하여

쿠버네티스 문서 딥다이브 | Deployment, StatefulSet, etc
이민석's avatar
Jun 20, 2024
Workload Management에 대하여

쿠버네티스 문서 딥다이브는 Kubernetes (Docs) | Concepts 문서 전체를 연결고리 순으로 딥다이브하면서 이론적 성숙도를 높이기 위해서 작성되었습니다.

딥다이브 전체 목차 및 인덱싱은 쿠버네티스 문서 딥다이브 — 소개 페이지를 참고해주세요.

개요

  1. 워크로드란 무엇인가?

  2. 워크로드 매니지먼트란 무엇인가?

워크로드란 무엇인가?

Kubernetes Documentation / Concepts / Workloads

워크로드는 쿠버네티스에서 가동 중인 어플리케이션을 의미합니다.

  1. 워크로드는 단일, 복수의 컨테이너로 구성됩니다.

  2. 워크로드는 파드(Pod) 세트 내에서 실행됩니다.

파드정의된 파드 라이프사이클(Pod Lifecycle)에 따라서 작동합니다.

워크로드 매니지먼트란 무엇인가?

Kubernetes Documentation / Concepts / Workloads / Workload Management

쿠버네티스는 기본적으로 선언적 관리(Declarative Management)에 의해서 가동됩니다.

따라서 워크로드/파드에 대한 선언파일이 별도로 존재할 것이며 이를 워크로드 매니지먼트라고 부릅니다.

워크로드 매니지먼트는 아래와 같은 것들이 존재합니다.

  1. Deployments

  2. ReplicaSet

  3. StatefulSets

  4. DaemonSet

  5. Jobs

  6. AUtomatic Cleanup for Finished Jobs

  7. Cronjob

  8. ReplicationController

Deployments

A Deployments provides declarative updates for POds and ReplicaSets.

Deployment는 Pod & ReplicaSet에 대한 선언적인 업데이트를 제공해줍니다.

즉, Deployment에서 원하는 상태를 명시해두면, Pod & ReplicaSet은 거기에 맞춰 조정됩니다. 따라서 다수의 Pod에 대한 부하분산이나 Rollout 등을 위해서 사용합니다.

아래에 싱글 컨테이너에 nginx:1.14.2를 가동하는 Pods를 3개 실행하는 ReplicaSets을 롤아웃하는 Deployment 코드가 존재합니다.

  • 참조

    Deployment → ReplicaSets → Pods

  • 코드

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80

Deployment Update

Deployment가 업데이트 될 때는 새로운 ReplicaSet이 생성됩니다.

그리고 점진적으로 Pods가 생성되면서 궁극적으로 새로운 ReplicaSet으로 교체되게 됩니다.

  1. kubectl apply -f manifest.yaml

  2. kubectl get deployments

  3. kubectl rollout status deployment/nginx-deployment

  4. kubectl get deployment

  5. kubectl get rs

  6. kubectl get pods —show-labels

  7. kubectl describe deployments

Deployment Rollover

만약 Deployment 업데이트가 진행 중일때 새로운 Deplyoment가 업데이트 명령이 떨어지면 어떻게 할까요? 원본 ReplicaSet은 5개의 파드로 구성되어 있으며, 대체 ReplicaSet은 3개까지 생성되었습니다.

이 경우 새로운 업데이트 명령이 들어오면 대체 ReplicaSet 3개가 즉시 종료됩니다.
그리고 새로운 ReplicaSet이 점진적으로 증가하여 ReplicaSet이 5개가 되면 원본이 대체됩니다.

Deployment Rollback

Deployment를 특정 버전으로 롤백할 수 있습니다.

Deployment Cheat Sheet

kubectl create deployment nginx --image=nginx:1.14.2 --replicas=3

kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1

kubectl edit deployment/nginx-deployment

kubectl scale deployment/nginx-deployment --replicas=5

ReplicaSet

A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time. As such, it’s often used to guarantee the availability of a special number of identical pods.

ReplicaSet은 언제든지 실행되는 replica set을 유지하는데 사용됩니다.

따라서 동일한 수의 동일한 파드의 availability을 보장하는데 자주 사용됩니다.

ReplicaSet은 다음 등으로 구성됩니다.

  1. Selector

  2. Number of Replicas

  3. Pod Template

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend

spec:
  replicas: 3
  selector:
    matchLabels:
    tier: frontend

  template:
    metadata:
      labels:
        tier: frontend

    spec:
      containers:
      - name: php-redis
        image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5

ReplicaSet Create to Describe

  1. kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml

  2. kubectl get rs

  3. kubectl describe rs/frontend

  4. kubectl get pods

  5. kubectl get pods frontend-** -o yaml

    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: "2024-02-28T22:30:44Z"
      generateName: frontend-
      labels:
        tier: frontend
      name: frontend-**
      namespace: default
      ownerReferences:
      - apiVersion: apps/v1
        blockOwnerDeletion: true
        controller: true
        kind: ReplicaSet
        name: frontend
        uid: e129deca-f864-481b-bb16-b27abfd92292
    # ...

ReplicaSet Cheat Sheet

kubectl get rs
kubectl get replicaset

kubectl describe rs/frontend
kubectl edit rs/frontend

kubectl create -f replicaset.yaml
kubectl apply -f replicaset.yaml
kubectl replace -f replicaset.yaml
kubectl scale --replicas=6 -f replicaset.yaml
kubectl scale --replicas=6 replicaset myapp

StatefulSets

StatefulSet is the workload API object used to manage stateful applications.
Manages the deployment and scaling of a set of Pods, and provide guarantees about the ordering and uniqueness of these Pods.

StatefulSet은 stateful applications을 관리하기 위해 사용되는 workload API object입니다. StatefulSet은 Deployment와 동일하게 파드의 크기를 조절할 뿐만 아니라, 파드들의 순서와 고유성을 보장해줍니다.

  1. StatefulSets

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx-statefulset
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2

        ports:
        - containerPort: 80
          name: web

        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html

  volumeClaimTemplates
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
    resources:
      requests:
        stoarge: 1Gi

  1. StatefulSets에 필요한 Headless Service

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx

spec:
  ports:
  - port: 80
    name: web

  clusterIP: None
  selector:
    app: nginx

Deployment와의 차이점

  1. 모든 파드가 각각 고유하며 영구적인 식별자를 갖는다.

  2. 모든 파드는 삭제 후 재생성시 해당 식별자를 그대로 유지한다.

  3. 모든 파드의 식별자 끝에는 번호가 붙는다. 이 번호는 레플리카의 수(N)를 기준으로 0에서 N-1까지 존재한다.

  4. 모든 파드의 생성과 스케일링, 업데이트, 그리고 삭제는 위에서 부여된 번호에 따라 순서대로 이루어진다. 생성, 스케일링, 업데이트 등은 순차적으로, 삭제는 역순으로 진행된다.

  5. 각각의 파드에는 각각의 영구적인 스토리지(볼륨)가 할당된다. 파드가 삭제되어도 볼륨은 남으며, 그 자리에 새로 생성된 파드는 해당 볼륨을 다시 이어 받는다.

StatefulSet 사용시 주의점

  1. 스테이트풀셋을 만들면 각 파드마다 퍼시스턴트 볼륨(PV; Persistent Volume)도 함께 만들어진다. 그러나 스테이트풀셋이 삭제될 때 이 볼륨은 삭제되지 않고 남는다.

  2. 스테이트풀셋의 파드에 사용할 스토리지는 오직 PVC(Persistent Volume Claim)를 통해서만 가능하다. 만약 파드가 늘어나면 그때마다 볼륨이 동적으로 붙어줘야 하기 때문이다. 이를 위해 클러스터에 미리 PV(Persistent Volume)을 만들어 놓거나, StorageClass를 이용해 동적으로 프로비저닝을 해줘야 한다.

  3. 스테이트풀셋의 특정 파드에 요청(Request)을 전달하기 위한 매개체로 헤드리스 서비스(Headless Service)필요하다. 이 서비스는 오직 해당 파드의 고유한 네트워크 위치를 파악하기 위해서만 쓰이므로 별도의 IP가 부여되지 않으며, 그렇기 때문에 헤드리스(Headless)라 불린다.

  4. 스테이트풀셋은 일반적으로 노드에 장애가 발생하더라도 파드를 다른 노드로 옮기지 않는다. 볼륨에 탑재된 데이터의 보호를 우선시하기 때문이다.

참고 자료

  1. Kubernetes (Docs) | Workload

  1. Kubernetes (Docs) | Workload Management

  2. Kubernetes (Docs) | Workload Management - Deployment

  3. Kubernetes (Docs) | Workload Management - ReplicaSet

  4. Kubernetes (Docs) | Workload Management - StatefulSets

  5. Kubernetes (Docs) | Workload Management - DaemonSet

  6. Kubernetes (Docs) | Workload Management - Jobs

  7. Kubernetes (Docs) | Workload Management - Automatic Cleanup for Finished Jobs

  8. Kubernetes (Docs) | Workload Management - ReplicationController

  9. Seongjiin (Docs) | 쿠버테니스의 워크로드 리소스 살펴보기

Share article

Unchaptered