본문 바로가기
K8S/Scheduling

[Scheduling] Pod Scheduling Process, nodeName

by HH_g 2024. 1. 18.

파드가 노드에 배포되기까지

스케쥴러는 쿠버네티스 시스템 컴포넌트 중 하나이며, 클러스터 내의 노드 간에 파드를 균등하게 분산시키고 리소스를 효과적으로 활용하기 위해 노력합니다. 또한, 스케쥴러는 사용자가 지정한 제약 조건과 우선순위를 고려하여 파드를 적절한 노드에 배치함으로써 클러스터의 안정성과 효율성을 유지합니다.

 

  1. Pod 생성 요청
  2. 스케쥴러는 Api Server를 통해 노드가 할당되지 않은 파드 감지
  3. 스케쥴러가 파드를 스케쥴링 큐에 추가
  4. 스케쥴러는 파드가 어느 노드에서 실행될지를 결정하기 전에 노드에 대한 우선순위 및 제약 조건을 평가
    • 이러한 우선순위 및 제약 조건은 스케쥴링 알고리즘에 의해 설정될 수 있으며, 예를 들어 리소스 요구 사항, 라벨 선택, 노드의 부하 등이 고려됩니다.
  5. 스케쥴러는 파드를 적절한 노드에 바인드(bind) 하고 kube-apiserver에 알림 (직접 생성x)
  6. kubelet이 노드에 할당된 파드를 감지하고 실행
    • 배치된 파드는 노드에서 실행되기 시작하고, 해당 파드의 상태가 "Running" 으로 변경됩니다.

 

#pod definition file (yaml) 
apiVersion: v1
kind: Pod
metadata:
	name: simple-webapp-color
spec:
	priorityClassName: high-priority
	containers:
		- name: simple-webapp-color
			image: simple-webapp-color
			resources:
				requests:
					memory: "1Gi"
					cpu: 10

위의 pod 를 스케쥴러가 처리하는 과정에 대해서 생각해봅시다.

Scheduling Queue -> Filtering -> Scoring -> binding 의 단계를 거쳐서 노드에 파드가 배치됩니다.

 

1. Scheudling Queue

위의 pod 뿐 아니라 다른 pod들도 생성되어야 하므로 먼저 모든 생성 대기 pod는 Scheduling Queue에서 대기하게 됩니다. 이 queue 에서 pod들은 먼저 priority에 따라 정렬됩니다.

 

PriorityClass

파드에 우선순위를 부여하는 데 사용됩니다.

각 PriorityClass는 priority 값과 함께 정의되며, 이 값이 높을수록 높은 우선순위를 의미합니다.
파드는 해당 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"

2. Filtering

priority로 sort 되면 가장 높은 priority를 가지는 pod가 filtering 스테이지로 진입합니다.

여기서 pod가 배치될 수 없는 node를 걸러내기 위해 pod의 요구사항과 node 상태를 취합하여 배포 가능한 노드의 목록을 추출합니다.

 

ex) pod가 요청하는 resource가 충분한지, pod가 지정하는 nodeselector에 일치하는지

3. Scoring

node가 filter 되면 다음 스테이지인 Scoring으로 이동합니다.

filter 조건에 부합하는 node가 여러 개일 때, 여기서 각 노드들의 weight 가 매겨집니다.

weight는 다양한 기준으로 매겨지는데, 예를 들면 해당 pod를 해당 노드에 배치하게될 시 남는 여유공간의 정도를 기준으로 할 수 있습니다. 더 많은 여유공간을 가지는 노드가 더 높은 weight를 가집니다.

4. Binding

Binding 단계에서는 파드가 가장 높은 가중치를 가진 노드에 할당됩니다.
이 단계에서 파드와 노드 간의 매핑이 확정되고 파드가 실행될 노드가 정해집니다.

 

Scheduling Plugins

위의 과정은 모두 어떠한 plugin 으로 동작하는데, 해당 단계에서 여러개의 plugin이 사용될 수 있습니다.

어떤 plugin을 사용할 지도 정할 수 있는데, 스케쥴러는 다양하고 복잡한 요구조건에 유연하게 대응할 수 있도록, 확장 기능을 구현하기 위한 scheduling framework를 제공합니다.

 

 

NodeName 필드로 노드 직접 지정하기

처음 리소스 생성 때 yaml의 spec.nodeName 에 node를 직접 지정해 줄 수 있습니다.

 

이미 리소스가 생성 되었으면 이 필드는 변경 불가합니다.

이미 존재하는 리소스에 노드를 직접 배정해주고 싶으면 binding을 이용해야 합니다.

 

어떤 노드에 배정된 pod를 다른 노드로 옮길 수는 없습니다.

이 경우에는 기존에 존재하는 pod를 삭제한 후 새로 생성해야 합니다.

kubectl replace --force -f nginx.yaml

을 사용해도 됩니다.

 

 

Pod가 생성되지 않을 시 스케쥴러 의심하기

 

만약 pod가 pending 상태인데 describe 했을 때 별다른 메세지 확인할 수 없다면 스케쥴러 문제임을 의심해 봐야 합니다.

kubectl get pods -n kube-system

kube-system 네임스페이스에서 스케쥴러 파드가 있는지 확인합니다.

 

 

 

 

참고

(1) 스케줄러 동작 원리와 Scheduling Framework 이해 - DeepDivers

'K8S > Scheduling' 카테고리의 다른 글

Daemon Sets  (0) 2024.01.19
[Scheduling] Resource Requirements and Limits  (0) 2024.01.19
Node Selectors & Node Affinity⭐⭐⭐  (0) 2024.01.19
Taints and Tolerations⭐⭐⭐  (0) 2024.01.18
Labels & Selectors  (1) 2024.01.18