[Kubernetes] Priority Classes


서론

Kubernetes는 파드를 실행시킬 때 서로 다른 우선순위를 가지도록 실행한다.

예를 들어, Kubernetes의 control plane components 들도 클러스터 내에서 파드로 실행되는데

이러한 컴포넌트들은 어떤 상황에서도 항상 실행되어야 한다.

즉 클러스터내에서 중요한 애플리케이션들은 우선순위가 높고 백그라운드 작업 같은 낮은 우선순위의 파드들도 있다.

이때 높은 우선순위의 파드들이 낮은 우선순위 파드들에 방해받지 않고 항상 스케줄되도록 보장할 수단이 필요하다.

여기서 Kubernetes의 워크로드 간 우선순위를 정해주는 객체인 클래스(Priority Class)가 사용된다.

Priority Class

만약 더 높은 우선순위의 파드가 스케줄될 수 없는 상황이면, 스케줄러는 이를 위해 낮은 우선순위의 워크로드를 종료하려고 시도한다.

클러스터 전체(Global) 리소스로, 네임스페이스에 종속되지 않는다.

  • +10억에서 -20억 사이의 숫자는 클러스터에 배포되는 일반 애플리케이션 및 워크로드용이다.
  • Kubernetes control plane component 중요 컴포넌트를 위한 별도의 숫자 범위가 존재하는데 이들은 최대 20억까지의 우선순위를 가질 수 있다.
  • 쿠버네티스는 기본적으로 우선순위 클래스를 가지고 있으며 이를 확인하기 위해서는 아래 명령어를 입력하면 된다.
 kubectl get priorityclass

우선순위 클래스 만들기

  • metadata.name: 우선순위 클래스 이름을 지정한다. 나중에 워크로드에서 이 이름을 통해 우선순위를 부여한다.
  • value: 우선순위 값을 정의한다
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority 
value: 100000000
description: "Priority class for mission critical pods"

파드 정의 파일에는 아래와 같이 작성하여 사용한다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  priorityClassName: high-priority
  containers:
  - name: nginx
    image: nginx
    ports:
      - containerPort: 8080
  

아래와 같이 파드 정의 파일로 정의하면 priorityClassName을 쓰지 않은 모든 Pod는 우선순위가 자동으로 0으로 설정된다.

만약 이 기본값 0을 변경하고 싶다면 globalDefault: true로 PriorityClass를 설정해주면 기본값이 변경된다.

globalDefault: true 옵션은 오직 하나의 PriorityClass에만 사용할 수 있다.

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority 
value: 100000000
description: "Priority class for mission critical pods"
globalDefault: true
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  containers: #   priorityclassName가 없으면 기본값으로 설정됨
  - name: nginx
    image: nginx
    ports:
      - containerPort: 8080
  

동작방식

우선순위가 7의 우선순위를 갖는 워크로드와 우선순위가 5인 워크로드가 노드에 전부 배치되어 남은 사용할 자원이 없게 되었다.

우선순위 6인 새로운 높은 우선순위 작업이 들어왔는데, 클러스터에는 더 이상 리소스가 없다. 그러면 기존 워크로드를 제거해야하는지 아니면 리소스를 반환할때 까지 기다려야하는지는 preemptionPolicy 에 의해 결정된다.

preemptionPolicy가 설정되지 않으면 기본값은 PreemptLowerPriority이다.

이는 기존의 낮은 우선순위 작업을 제거하고 새로운 워크로드가 그 자리를 차지한다.

만약 기존 워크로드를 종료하거나 퇴출시키고 싶지 않고 리소스를 반환할 때까지 기다리는 방식을 택하려면 preemptionPolicy: Never로 설정해야 한다.

따라서 스케줄링 큐에서 대기한다.

같은 스케줄링 큐에서 대기 중인 워크로드 중 우선순위가 높은 것들은 먼저 스케줄될 우선권을 갖는다.

따라서 스케줄러가 어느 Pod를 먼저 배치할 것인가를 결정하는 스케줄링 시점에서만 적용된다.