Pod 우선순위와 선점
Pod 우선순위와 선점 (Pod Priority and Preemption)
Pod는 **우선순위(priority)**를 가질 수 있어요. 우선순위는 다른 Pod에 비해 그 Pod가 얼마나 중요한지 나타냅니다. Pod를 스케줄할 수 없으면 스케줄러는 대기 중인 Pod의 스케줄링을 가능하게 만들기 위해 더 낮은 우선순위의 Pod를 선점(축출)하려고 시도합니다.
경고: 모든 사용자를 신뢰할 수 없는 클러스터에서 악의적인 사용자가 가능한 최고 우선순위로 Pod를 만들어 다른 Pod가 축출되거나 스케줄되지 못하게 할 수 있어요. 관리자는 ResourceQuota를 사용해 사용자가 높은 우선순위로 Pod를 만들지 못하게 막을 수 있습니다. 자세한 내용은 PriorityClass 사용을 기본값으로 제한하기를 참고하세요.
출처: 문서
우선순위와 선점 사용 방법 (How to use priority and preemption)
우선순위와 선점을 사용하려면:
- 하나 이상의 PriorityClass를 추가하세요.
priorityClassName이 추가한 PriorityClass 중 하나로 설정된 Pod를 만드세요. 물론 Pod를 직접 만들 필요는 없어요. 보통 Deployment 같은 컬렉션 객체의 Pod 템플릿에priorityClassName을 추가하면 됩니다.
이 단계들에 대한 자세한 내용을 계속 읽어보세요.
PriorityClass
PriorityClass는 네임스페이스가 없는(non-namespaced) 객체로, 우선순위 클래스 이름을 정수 우선순위 값에 매핑하는 것을 정의합니다. 이름은 PriorityClass 객체의 metadata에 있는 name 필드에 지정됩니다. 값은 필수인 value 필드에 지정됩니다. 값이 높을수록 우선순위가 높아요. PriorityClass 객체의 이름은 유효한 DNS 서브도메인 이름이어야 하며, system- 접두사를 붙일 수 없습니다.
PriorityClass 객체는 10억 이하의 32비트 정수 값을 가질 수 있어요. 즉 PriorityClass 객체의 값 범위는 -2147483648부터 1000000000까지(양쪽 포함)입니다. 더 큰 숫자는 중요 시스템 Pod를 나타내는 내장 PriorityClass용으로 예약되어 있습니다. 클러스터 관리자는 원하는 각 매핑에 대해 PriorityClass 객체를 하나씩 만들어야 해요.
참고: Kubernetes에는 이미
system-cluster-critical과system-node-critical이라는 두 PriorityClass가 포함되어 있어요. 이들은 공통 클래스로, 중요한 컴포넌트가 항상 먼저 스케줄되도록 보장하는 데 사용됩니다. Kubernetes v1.37에서 이들의 우선순위 값은system-cluster-critical이 2000000000,system-node-critical이 2000001000입니다.
PriorityClass에는 globalDefault와 description이라는 선택적 필드도 있어요. globalDefault 필드는 이 PriorityClass의 값을 priorityClassName이 없는 Pod에 사용해야 한다는 것을 나타냅니다. 시스템에는 globalDefault가 true로 설정된 PriorityClass가 하나만 존재할 수 있어요. globalDefault가 설정된 PriorityClass가 없으면 priorityClassName이 없는 Pod의 우선순위는 0입니다.
description 필드는 임의의 문자열입니다. 클러스터 사용자에게 언제 이 PriorityClass를 사용해야 하는지 알려주기 위한 것이에요.
PodPriority와 기존 클러스터에 대한 참고 사항 (Notes about PodPriority and existing clusters)
- 이 기능 없이 기존 클러스터를 업그레이드하면 기존 Pod의 우선순위는 사실상 0입니다.
globalDefault가true로 설정된 PriorityClass를 추가해도 기존 Pod의 우선순위는 바뀌지 않습니다. 그런 PriorityClass의 값은 추가된 후 생성되는 Pod에만 사용됩니다.- PriorityClass를 삭제하면 삭제된 PriorityClass의 이름을 사용하는 기존 Pod는 그대로 유지되지만, 삭제된 PriorityClass의 이름을 사용하는 Pod를 더 이상 만들 수는 없어요.
PriorityClass 예시 (Example PriorityClass)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for XYZ service pods only."
선점하지 않는 PriorityClass (Non-preempting PriorityClass)
preemptionPolicy: Never가 있는 Pod는 낮은 우선순위 Pod보다 앞서 스케줄링 큐에 배치되지만, 다른 Pod를 선점할 수는 없어요. 스케줄을 기다리는 선점하지 않는 Pod는 충분한 리소스가 비워져 스케줄될 수 있을 때까지 스케줄링 큐에 머물러 있어요. 선점하지 않는 Pod는 다른 Pod와 마찬가지로 스케줄러 백오프(back-off)의 대상입니다. 즉 스케줄러가 이들을 시도했지만 스케줄할 수 없으면 더 낮은 빈도로 재시도하여, 더 낮은 우선순위의 다른 Pod가 그들보다 먼저 스케줄될 수 있게 해요.
선점하지 않는 Pod는 여전히 다른 높은 우선순위 Pod에 의해 선점될 수 있습니다.
preemptionPolicy는 기본값이 PreemptLowerPriority이며, 이는 해당 PriorityClass의 Pod가 낮은 우선순위 Pod를 선점할 수 있게 합니다(기존 기본 동작 그대로). preemptionPolicy를 Never로 설정하면 해당 PriorityClass의 Pod는 선점하지 않게 됩니다.
데이터 과학 워크로드가 좋은 예시예요. 사용자가 다른 워크로드보다 우선순위를 높이고 싶지만, 실행 중인 Pod를 선점해 기존 작업을 버리고 싶지는 않은 작업을 제출할 수 있어요. preemptionPolicy: Never가 있는 높은 우선순위 작업은 클러스터 리소스가 "자연스럽게" 충분히 비워지는 즉시 다른 대기 중인 Pod보다 먼저 스케줄됩니다.
선점하지 않는 PriorityClass 예시 (Example Non-preempting PriorityClass)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority-nonpreempting
value: 1000000
preemptionPolicy: Never
globalDefault: false
description: "This priority class will not cause other pods to be preempted."
Pod 우선순위 (Pod priority)
하나 이상의 PriorityClass가 있으면, 그 PriorityClass 이름 중 하나를 스펙에 지정하는 Pod를 만들 수 있어요. 우선순위 승인 컨트롤러(priority admission controller)는 priorityClassName 필드를 사용해 정수 우선순위 값을 채웁니다. 우선순위 클래스를 찾을 수 없으면 Pod는 거부됩니다.
다음 YAML은 앞선 예시에서 만든 PriorityClass를 사용하는 Pod 구성의 예시예요. 우선순위 승인 컨트롤러가 스펙을 확인하고 Pod의 우선순위를 1000000으로 해석합니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: high-priority
스케줄링 순서에 대한 Pod 우선순위의 영향 (Effect of Pod priority on scheduling order)
Pod 우선순위가 활성화되면 스케줄러는 대기 중인 Pod를 우선순위로 정렬하며, 대기 중인 Pod는 스케줄링 큐에서 더 낮은 우선순위의 다른 대기 중인 Pod보다 앞에 배치됩니다. 결과적으로 더 높은 우선순위 Pod는 스케줄링 요구 사항이 충족되면 더 낮은 우선순위 Pod보다 더 일찍 스케줄될 수 있어요. 그런 Pod를 스케줄할 수 없으면 스케줄러는 계속해서 다른 낮은 우선순위 Pod를 스케줄하려고 시도합니다.
PodGroups와 스케줄링 순서 (PodGroups and scheduling order)
이 기능을 사용하려면 사용자(또는 클러스터 관리자)가 클러스터의 모든 관련 컴포넌트에서 GenericWorkload 기능 게이트를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화를 참고하세요.
GenericWorkload 기능 게이트가 활성화되면 PodGroup은 스케줄링 큐에서 독립형 Pod와 함께 인터리브(interleaved)됩니다. PodGroup 객체에는 우선순위 필드가 있어 다른 Pod 및 PodGroup과의 정렬에 사용됩니다. PodGroup의 우선순위를 설정하는 방법에 대한 자세한 내용은 Pod Group Disruption and Priority 페이지에서 확인할 수 있어요.
CompositePodGroups와 스케줄링 순서 (CompositePodGroups and scheduling order)
이 기능을 사용하려면 클러스터의 모든 관련 컴포넌트에서 CompositePodGroup 기능 게이트를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화를 참고하세요.
CompositePodGroup 기능 게이트가 활성화되면 스케줄러는 다음 객체를 큐에 넣을 수 있는 스케줄링 단위로 취급합니다.
- 독립형 Pod (Standalone Pods) — 어떤 PodGroup에도 속하지 않는 Pod
- 독립형 PodGroups (Standalone PodGroups) —
ParentCompositePodGroup을 지정하지 않는 PodGroup - 루트 CompositePodGroups (Root CompositePodGroups) —
ParentCompositePodGroup을 지정하지 않는 CompositePodGroup
이 객체들은 활성 스케줄링 큐에서 자신의 위치를 결정하는 데 사용되는 우선순위 필드 값을 지정합니다.
선점 (Preemption)
Pod가 생성되면 큐로 가서 스케줄되기를 기다립니다. 스케줄러는 큐에서 Pod를 선택해 노드에 스케줄하려고 시도합니다. Pod의 모든 지정된 요구 사항을 충족하는 노드를 찾지 못하면 대기 중인 Pod에 대해 선점 로직이 촉발됩니다. 그 대기 중인 Pod를 P라고 부를게요. 선점 로직은 P보다 낮은 우선순위의 Pod 하나 이상을 제거하면 P가 스케줄될 수 있는 노드를 찾으려고 합니다. 그런 노드를 찾으면 낮은 우선순위 Pod 하나 이상이 노드에서 축출됩니다. Pod들이 사라진 후 P는 그 노드에 스케줄될 수 있어요.
PodGroup 선점 (PodGroup preemption)
이 기능을 사용하려면 클러스터의 모든 관련 컴포넌트에서 GenericWorkload 기능 게이트를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화를 참고하세요.
GenericWorkload 기능 게이트가 활성화되면 PodGroup은 선점에서 시작자(initiator) 또는 희생자(victim)로 참여할 수 있어요. PodGroup이 선점을 촉발하면 워크로드 인지 선점 로직을 따라 다른 Pod와 PodGroup을 선점해 자신을 위한 공간을 만듭니다. Pod가 선점을 촉발하면 PodGroup이 희생자가 될 수 있어요. 이 경우 PodGroup의 priority 필드는 다른 잠재적 희생자에 대한 정렬에 사용되고, disruptionMode 필드는 PodGroup 중단 동작을 지시하는 데 사용됩니다. 이 필드들의 자세한 설명은 Pod Group Disruption and Priority 페이지에서 확인할 수 있어요.
사용자에게 노출되는 정보 (User exposed information)
Pod P가 노드 N에서 하나 이상의 Pod를 선점하면, Pod P의 status에 있는 nominatedNodeName 필드가 노드 N의 이름으로 설정됩니다. 이 필드는 스케줄러가 Pod P를 위해 예약된 리소스를 추적하는 데 도움이 되고, 사용자에게 클러스터의 선점에 대한 정보를 제공합니다.
Pod P가 반드시 "지명된 노드(nominated Node)"에 스케줄되는 것은 아니라는 점에 유의하세요. 스케줄러는 항상 다른 노드를 순회하기 전에 "지명된 노드"를 먼저 시도합니다. 희생자 Pod가 선점된 후 그들은 우아한 종료 기간을 받습니다. 스케줄러가 희생자 Pod가 종료되기를 기다리는 동안 다른 노드가 사용 가능해지면, 스케줄러가 그 다른 노드를 사용해 Pod P를 스케줄할 수 있어요. 결과적으로 nominatedNodeName과 Pod 스펙의 nodeName이 항상 같지는 않습니다. 또한 스케줄러가 노드 N에서 Pod를 선점했지만 Pod P보다 높은 우선순위 Pod가 도착하면, 스케줄러가 노드 N을 그 새로운 높은 우선순위 Pod에 줄 수 있어요. 그런 경우 스케줄러는 Pod P의 nominatedNodeName을 지웁니다. 이렇게 하면 스케줄러는 Pod P가 다른 노드의 Pod를 선점할 자격을 갖게 만듭니다.
선점의 제한 사항 (Limitations of preemption)
선점 희생자의 우아한 종료 (Graceful termination of preemption victims)
Pod가 선점되면 희생자들은 우아한 종료 기간을 받습니다. 그들은 그 시간 동안 작업을 끝내고 종료할 수 있어요. 그러지 못하면 강제로 종료됩니다. 이 우아한 종료 기간은 스케줄러가 Pod를 선점한 시점과 대기 중인 Pod(P)가 노드(N)에 스케줄될 수 있는 시점 사이에 시간 간격을 만듭니다. 그동안 스케줄러는 다른 대기 중인 Pod를 계속 스케줄합니다. 희생자가 종료되거나 강제 종료되면 스케줄러는 대기 큐의 Pod를 스케줄하려고 시도합니다. 따라서 보통 스케줄러가 희생자를 선점한 시점과 Pod P가 스케줄되는 시점 사이에 시간 간격이 있습니다. 이 간격을 최소화하려면 낮은 우선순위 Pod의 우아한 종료 기간을 0이나 작은 숫자로 설정할 수 있어요.
PodDisruptionBudget은 지원되지만 보장되지는 않음 (PodDisruptionBudget is supported, but not guaranteed)
PodDisruptionBudget(PDB)은 애플리케이션 소유자가 자발적 중단으로 인해 복제된 애플리케이션의 Pod 여러 개가 동시에 다운되는 것을 제한할 수 있게 해줍니다. Kubernetes는 Pod를 선점할 때 PDB를 지원하지만, PDB를 존중하는 것은 최선 노력(best effort)입니다. 스케줄러는 선점으로 PDB를 위반하지 않는 희생자를 찾으려고 하지만, 그런 희생자를 찾지 못하면 PDB가 위반되더라도 선점이 여전히 발생하고 낮은 우선순위 Pod가 제거됩니다.
낮은 우선순위 Pod의 파드 간 어피니티 (Inter-Pod affinity on lower-priority Pods)
한 노드는 다음 질문에 대한 답이 "예"일 때만 선점 후보로 간주됩니다: "대기 중인 Pod보다 낮은 우선순위의 모든 Pod가 노드에서 제거되면, 대기 중인 Pod가 그 노드에 스케줄될 수 있는가?"
참고: 선점이 반드시 모든 낮은 우선순위 Pod를 제거하는 것은 아닙니다. 대기 중인 Pod가 모든 낮은 우선순위 Pod보다 적은 수의 제거로 스케줄될 수 있다면 낮은 우선순위 Pod의 일부만 제거됩니다. 그럼에도 앞선 질문에 대한 답은 "예"여야 합니다. 답이 "아니요"라면 그 노드는 선점 후보로 간주되지 않습니다.
대기 중인 Pod가 노드의 낮은 우선순위 Pod 하나 이상과 파드 간 어피니티(inter-pod affinity)가 있다면, 그 낮은 우선순위 Pod가 없을 때 파드 간 어피니티 규칙을 충족할 수 없습니다. 이 경우 스케줄러는 노드의 어떤 Pod도 선점하지 않습니다. 대신 다른 노드를 찾습니다. 스케줄러가 적합한 노드를 찾을 수도 있고 못 찾을 수도 있어요. 대기 중인 Pod가 스케줄될 수 있다는 보장은 없습니다.
이 문제에 대한 권장 해결책은 같거나 더 높은 우선순위 Pod에 대해서만 파드 간 어피니티를 만드는 것입니다.
교차 노드 선점 (Cross node preemption)
대기 중인 Pod P를 노드 N에 스케줄하기 위해 노드 N이 선점 후보로 고려된다고 가정해봅시다. P는 다른 노드의 Pod가 선점돼야만 N에서 적합해질 수 있습니다. 예시를 들어볼게요.
- Pod P가 노드 N에 대해 고려되고 있습니다.
- Pod Q가 노드 N과 같은 Zone의 다른 노드에서 실행 중입니다.
- Pod P는 Pod Q와 Zone 전체 안티-어피니티(
topologyKey: topology.kubernetes.io/zone)를 가집니다. - Zone 안의 다른 Pod와 Pod P 사이에 다른 안티-어피니티 사례는 없습니다.
- Pod P를 노드 N에 스케줄하려면 Pod Q를 선점할 수 있지만, 스케줄러는 교차 노드 선점을 수행하지 않습니다. 따라서 Pod P는 노드 N에서 스케줄 불가능한 것으로 간주됩니다.
Pod Q가 자신의 노드에서 제거되면 Pod 안티-어피니티 위반이 사라지고 Pod P가 노드 N에 스케줄될 수 있을 것입니다.
충분한 수요가 있고 합리적인 성능의 알고리즘을 찾게 되면 향후 버전에서 교차 노드 선점 추가를 고려할 수 있어요.
제자리 Pod 리사이즈를 위한 선점 (Preemption for in-place Pod resize)
이 기능을 사용하려면 클러스터의 모든 관련 컴포넌트에서 InPlacePodVerticalScalingSchedulerPreemption 기능 게이트를 활성화해야 해요.
자세한 내용은 기능 게이트 활성화/비활성화를 참고하세요.
InPlacePodVerticalScalingSchedulerPreemption 기능 게이트가 활성화되면, 실행 중인 Pod의 제자리 리사이즈 요청이 노드 용량 부족으로 인해 Deferred(요청된 리사이즈가 일시적으로 불가능하지만 나중에 가능해질 수 있음) 상태일 때에도 선점이 적용됩니다. 리사이즈 상태에 대한 자세한 내용은 Pod resize status를 참고하세요.
더 높은 우선순위 Pod가 노드에 사용 가능한 CPU나 메모리가 없어 제자리 리사이즈를 할 수 없으면, kube-scheduler는 그 노드의 낮은 우선순위 Pod를 선점해 필요한 용량을 확보하려고 시도합니다.
제자리 Pod 리사이즈를 위한 선점은 표준 Pod 배치 선점과 몇 가지 중요한 점에서 다릅니다.
- 노드 제한 (Node restriction): 선점은 엄격히 Pod가 현재 할당된 노드로 제한됩니다. 스케줄러는 클러스터 전체의 다른 후보 노드를 평가하지 않습니다.
- 리소스 델타 계산 (Resource delta calculation): 필요한 선점 용량은 총 Pod 요청이 아니라 리소스 델타(원하는 리소스와 현재 할당된 리소스의 차이)를 기반으로 계산됩니다.
- 리소스 차단 (Resource blocking): 리사이즈 중인 Pod의 요청된 리소스는 그 노드에서 스케줄러 리소스 회계에 이미 소비된 것으로 간주되어, 리사이즈가 결국 수행되거나 Kubelet이 deferred 상태를 제거할 때까지 다른 낮은 우선순위 Pod가 이를 사용하지 못하게 막습니다.
- 지명 노드 상태 (Nominated node status): Pod가 이미 대상 노드에 할당되어 실행 중이므로 Pod의
status에 있는nominatedNodeName필드는 설정되지 않습니다. - Kubelet 실행 (Kubelet actuation): 스케줄러는 노드 용량을 확보하기 위해 선점을 촉발하지만 Pod를 다시 바인딩하지는 않습니다. Kubelet이 노드의 새로 확보된 용량을 감지하고 실제 제자리 리사이즈 실행을 수행합니다.
- 노드 수준 선점 정책 (Node-level preemption policy): Node 스펙의
spec.podPreemptionPolicy.disableResizePreemption필드를 사용해 특정 노드에서 제자리 리사이즈에 대한 선점을 구체적으로 비활성화할 수 있어요. 표준 선점이preemptionPolicy: Never로 우선순위 클래스별로만 비활성화할 수 있는 것과 달리, 이는 운영자나 오토스케일링 시스템이 개별 노드에서 선점을 비활성화할 수 있게 해줍니다.
제자리 Pod 리사이즈에 대한 자세한 내용은 컨테이너에 할당된 CPU와 메모리 리소스 리사이즈를 참고하세요.
노드 수준에서 제자리 Pod 리사이즈 선점 비활성화 (Disabling preemption for in-place Pod resize at the Node level)
클러스터 운영자와 컨트롤러는 특정 노드에서 제자리 Pod 리사이즈 요청으로 인해 촉발되는 스케줄러 선점을 비활성화할 수 있어요. 이는 리사이즈 가능한 노드나 사용자 정의 오토스케일링 솔루션이 있는 노드에 유용하며, 기존 워크로드를 중단으로부터 보호하고 노드 업사이징(node-upsizing)이 리소스 부족을 처리하게 할 수 있어요.
이것은 Node 스펙의 spec.podPreemptionPolicy 필드로 구성됩니다. disableResizePreemption 목록이 비어 있지 않으면 그 노드에서 리사이즈 유발 선점이 비활성화되고, kube-scheduler는 그 노드에서 실행되는 deferred 리사이즈에 대한 선점 시도를 건너뜁니다.
다음은 노드 구성 예시입니다.
apiVersion: v1
kind: Node
metadata:
name: resizable-node
spec:
podPreemptionPolicy:
disableResizePreemption:
- autoscaling.k8s.io/cluster-autoscaler
- autoscaling.k8s.io/vpa-updater
제약과 검증 규칙:
- 라벨 형식 (Label format):
disableResizePreemption목록의 각 항목은 표준 Kubernetes 라벨 키 형식(예:/로 구분된 DNS 서브도메인 접두사와 이름)을 따라야 합니다. - 최대 항목 수 (Max items): 목록은 최대 20개 항목을 포함할 수 있습니다.
- 비어 있지 않은 목록 (Non-empty list): 목록에 항목이 최소 하나 있으면 정책이 적용됩니다(선점 비활성화). 목록이 비어 있거나
podPreemptionPolicy필드가 생략되면 해당 노드에서 제자리 리사이즈 선점이 활성화됩니다.
문제 해결 (Troubleshooting)
Pod 우선순위와 선점은 원치 않는 부작용을 가질 수 있습니다. 잠재적 문제와 이를 처리하는 방법의 몇 가지 예시를 볼게요.
Pod가 불필요하게 선점됨 (Pods are preempted unnecessarily)
선점은 리소스 압박이 있을 때 더 높은 우선순위의 대기 중인 Pod를 위한 공간을 만들기 위해 클러스터에서 기존 Pod를 제거합니다. 실수로 특정 Pod에 높은 우선순위를 주면, 의도치 않게 높은 우선순위의 Pod가 클러스터에서 선점을 유발할 수 있어요. Pod 우선순위는 Pod 스펙의 priorityClassName 필드를 설정해 지정합니다. 그런 다음 정수 우선순위 값이 해석되어 podSpec의 priority 필드에 채워집니다.
이 문제를 해결하려면 그 Pod들의 priorityClassName을 더 낮은 우선순위 클래스로 바꾸거나 그 필드를 비워 둘 수 있어요. 빈 priorityClassName은 기본적으로 0으로 해석됩니다.
Pod가 선점되면 선점된 Pod에 대한 이벤트가 기록됩니다. 선점은 클러스터에 Pod를 위한 충분한 리소스가 없을 때만 발생해야 해요. 그런 경우 선점은 대기 중인 Pod(선점자)의 우선순위가 희생자 Pod보다 높을 때만 발생합니다. 대기 중인 Pod가 없거나, 대기 중인 Pod의 우선순위가 희생자와 같거나 낮을 때 선점이 발생해서는 안 됩니다. 그런 시나리오에서 선점이 발생하면 이슈를 제기해 주세요.
Pod는 선점됐지만 선점자가 스케줄되지 않음 (Pods are preempted, but the preemptor is not scheduled)
Pod가 선점되면 요청된 우아한 종료 기간을 받으며, 기본값은 30초입니다. 희생자 Pod가 이 기간 안에 종료되지 않으면 강제로 종료됩니다. 모든 희생자가 사라지면 선점자 Pod가 스케줄될 수 있어요.
선점자 Pod가 희생자가 사라지기를 기다리는 동안, 같은 노드에 들어맞는 더 높은 우선순위 Pod가 생성될 수 있어요. 이 경우 스케줄러는 선점자 대신 더 높은 우선순위 Pod를 스케줄합니다.
이것은 예상된 동작입니다: 더 높은 우선순위를 가진 Pod가 더 낮은 우선순위의 Pod 자리를 차지해야 하니까요.
높은 우선순위 Pod가 낮은 우선순위 Pod보다 먼저 선점됨 (Higher priority Pods are preempted before lower priority pods)
스케줄러는 대기 중인 Pod를 실행할 수 있는 노드를 찾으려고 합니다. 노드를 찾지 못하면 대기 중인 Pod를 위한 공간을 만들기 위해 임의의 노드에서 낮은 우선순위 Pod를 제거하려고 시도합니다. 낮은 우선순위 Pod가 있는 노드가 대기 중인 Pod를 실행하기에 적합하지 않으면, 스케줄러는 선점을 위해 다른 노드(다른 노드의 Pod보다 높은 우선순위 Pod가 있는 노드)를 선택할 수 있어요. 희생자는 여전히 선점자 Pod보다 낮은 우선순위여야 합니다.
선점에 사용 가능한 노드가 여러 개 있을 때 스케줄러는 가장 낮은 우선순위의 Pod 집합을 가진 노드를 선택하려고 합니다. 그러나 그런 Pod가 선점되면 위반될 PodDisruptionBudget이 있으면, 스케줄러는 더 높은 우선순위 Pod가 있는 다른 노드를 선택할 수 있어요.
선점에 여러 노드가 있고 위의 시나리오 중 어느 것도 적용되지 않으면, 스케줄러는 가장 낮은 우선순위의 노드를 선택합니다.
Pod 우선순위와 서비스 품질(QoS) 간의 상호작용 (Interactions between Pod priority and quality of service)
Pod 우선순위와 QoS 클래스는 상호작용이 거의 없는 두 개의 직교 기능이며, QoS 클래스에 따라 Pod 우선순위를 설정하는 것에 대한 기본 제한은 없습니다. 스케줄러의 선점 로직은 선점 대상을 선택할 때 QoS를 고려하지 않습니다. 선점은 Pod 우선순위를 고려하며 가장 낮은 우선순위의 대상 집합을 선택하려고 합니다. 더 높은 우선순위 Pod는 가장 낮은 우선순위 Pod의 제거만으로는 스케줄러가 선점자 Pod를 스케줄할 수 없거나, 가장 낮은 우선순위 Pod가 PodDisruptionBudget으로 보호될 때만 선점 후보로 간주됩니다.
kubelet은 노드 압력 축출을 위한 Pod 순서를 결정할 때 우선순위를 사용합니다. QoS 클래스를 사용해 Pod가 축출될 가능성이 가장 높은 순서를 추정할 수 있어요. kubelet은 다음 요인을 기반으로 축출할 Pod 순위를 매깁니다.
- 갈급한(starved) 리소스 사용량이 요청을 초과하는지 여부
- Pod 우선순위
- 요청 대비 리소스 사용량
자세한 내용은 kubelet 축출을 위한 Pod 선택을 참고하세요.
kubelet의 노드 압력 축출은 Pod의 사용량이 요청을 초과하지 않으면 Pod를 축출하지 않습니다. 더 낮은 우선순위 Pod가 요청을 초과하지 않으면 축출되지 않아요. 요청을 초과하는 더 높은 우선순위의 다른 Pod는 축출될 수 있습니다.
다음 단계 (What's next)
- PriorityClasses와 함께 ResourceQuotas 사용하기 읽어보기: PriorityClass 소비를 기본값으로 제한하기
- Pod 중단 (Pod Disruption) 알아보기
- API 시작 축출 (API-initiated Eviction) 알아보기
- 노드 압력 축출 (Node-pressure Eviction) 알아보기