전공영역 공부 기록

pod 우선순위클래스(PriorityClass)

악분 2023. 9. 21. 17:09
반응형

안녕하세요. 이 글은 쿠버네티스 pod의 우선순위클래스를 설명합니다.

 

1. 우선순위클래스란?

우선순위클래스(PriorityClass) pod 우선순위를 설정합니다. 우선순위는 kube-shceduler 이상 pod 스케쥴링 하지 못할 경우에 사용됩니다.  pod 스케쥴링이 불가능한 상황(: 노드 자원이 부족) 생기면, kube-scheduler 우선순위가 낮은 pod 제거하고 새로운 pod를 스케쥴링합니다.

 

2. 우선순위클래스 이해를 돕는 퀴즈

예를 들어, 1024Mi 용량을 갖는 노드가 있다고 가정해봅시다. 노드에는 200Mi 메모리를 사용하는 우선순위가 -1 5개의 pod 있습니다. 상황에서 -1보다 우선순위 높은 pod 생성되면, 새로운 pod 스케쥴링이 될까요? 숫자가 높을수록 우선순위가 높습니다.

 

정답은 새로운 pod 스케쥴링이 가능합니다. kube-shceduler 우선순위 낮은 pod 종료하고 자리에 새로운 Pod 스케쥴링합니다. 제거된 우선순위 낮은 pod 노드에 메모리가 부족하므로 pending상태가 됩니다.

 

3. 우선순위클래스 사용방법

쿠버네티스 PriorityClass 리소스를 생성하고 pod 적용하면 됩니다. Pod 적용할 때는 spec.priorityClassName필드에 설정합니다.

 

우선순위 설정은 PriorityClass리소스 value필드에서 설정하며 숫자가 높을수록 우선순위가 높습니다. PriorityClass 지정하지 않은 pod 디폴트 priorityClass 값이 0으로 설정됩니다.

 

4. 실습 예제

실습코드는 github 공개되어 있습니다.

 

4.1 실습 시나리오

  1. 메모리 1GB갖는 워커 노드에 리소스 200Mi갖는 더미 pod를 4~5개 생성합니다. 더미 pod는 PriorityClass우선순위가 -1로 설정합니다.
  2. 더미 pod 생성 후에 nginx pod를 생성합니다. nginx pod가 스케쥴링 되는지 확인합니다. nginx pod는 PriorityClass를 설정하지 않고 디폴트 값인 0을 갖습니다.

 

4.2 실습환경 구축

실습을 진행하기 위해 1GB 메모리를 갖는 워커 노드 1개가 필요합니다. 그리고 control-plane 노드에 pod 스케쥴링 되지 않도록 설정합니다. 저는 실습환경을 k3d클러스터를 사용했습니다.

k3d cluster create mycluster --agents 1 --agents-memory 1G
kubectl cordon k3d-mycluster-server-0

 

제가 테스트한 노드 최종 설정은 아래 그림과 같습니다. agent노드가 워커 노드입니다.

 

4.3 우선순위클래스 생성

PriorityClass리소스를 생성합니다. 우선순위는 -1 설정했습니다. 디폴트 우선순위인 0보다 낮게 설정하기 위해 -1 설정했습니다.

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: test
value: -1
globalDefault: false

 

4.4 더미 pod생성

더미 pod 생성합니다. pod는 deployment로 생성했습니다. 더미 pod busybox 사용했습니다. pod priorityClassName 생성한 PriorityClass 사용합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dummy-pod
  namespace: default
spec:
  replicas: 5
  selector:
    matchLabels:
      run: dummy-pod
  template:
    metadata:
      labels:
        run: dummy-pod
    spec:
      priorityClassName: test
      containers:
      - name: busybox
        image: busybox
        resources:
          requests:
            cpu: 200m
            memory: 200Mi
          limits:
            cpu: 200m
            memory: 200Mi
        args:
        - sleep
        - "1000000"

 

더미 pod 노드에 스케쥴링 되었는지 확인합니다.

 

4.4 더미 pod 개수 증가

더미 pod 생성합니다.

kubectl scale deployment dummy-pod --replicas=6

 

이상 노드 자원이 없으므로 pod pending상태입니다.

 

descirbe pod 하면 스케쥴링을 못하는지 이벤트 상세내용이 있습니다.

kubectl describe pod {pending상태 pod}

 

4.5 nginx pod 생성

nginx pod 생성하여 스케쥴링이 되는지 확인해보겠습니다. nginx pod 우선순위클래스를 설정하지 않아 디폴트 우선순위인 0 갖습니다. 0 기존 실행중인 pod 우선순위보다 높습니다.

 

nginx pod 생성합니다. pod는 deployment로 생성했습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            memory: "200Mi"
            cpu: "200m"
        ports:
        - containerPort: 80

 

nginx pod 더미 pod보다 우선순위가 높아서 스케쥴링이 됩니다. nginx pod 스케쥴링 노드의 메모리를 확보하기 위해 더미 pod 개를 제거합니다.

 

5. 우선순위 클래스를 언제 사용할까?

우선순위클래스는스케쥴링이안되는상황에서우선순위낮은pod제거된다는특징을이용할사용합니다. 대표적인 사례가 카펜터의 오버프로비저닝(OverProvisioning)입니다. pod 미리 생성하여 카펜터를 실행시키는 방법이 오버프로비저닝입니다.

 

카펜터는 EKS오토스케일링 도구로서 스케쥴링을 못하는 상황이 발생하면, 카펜터가 노드를 추가합니다. 노드가 추가되면 부팅시간과 초기화과정이 필요합니다. 그러므로 추가된 노드를 사용하려면 최소 분이 필요합니다.

 

대기 시간을 최소화 하기 위해 우선순위가 낮은 pod 미리 생성(오버)하여 노드를 추가합니다. 미리 생성한 노드를 사용할 때는 이미 초기화가 끝나 있어 바로 사용이 가능합니다.

 

시간이 지나면서 미리 생성한 노드도 자원이 없는 상황이 생깁니다. 사용자가 요청한 pod 스케쥴링 하기 위해 kube-scheduler 우선순위 낮은 pod 제거합니다. pod 제거되면 해당 pod pending상태가 됩니다. 그리고 카펜터가 pending상태를 감지하여 노드를 생성하고 생성된 노드에 우선순위 낮은 pod 스케쥴링됩니다 . 과정이 반복되면서 새로운 노드 사용대기 시간을 최소화합니다.

출처: https://aws.amazon.com/ko/blogs/containers/eliminate-kubernetes-node-scaling-lag-with-pod-priority-and-over-provisioning/

 

반응형