1. 개요

Kubernetes의 Scheduler에 대해 알아본다.


2. 원리

  • Kubernetes는 kube-scheduler가 Pod에 할당할 노드를 결정한다. 
  • kubectl apply 등을 통해 kube-apiserver에 Pod 생성요청이 전잘되면 kube-apiserver는 etcd에 Pod 정보를 저장하는데 아직은 Pod의 노드 정보인 NodeName이 설정되어 있는 상태는 아니다.
  • 이때 kube-schedler는 watch하고 있다가 Pod의 NodeName이 없는 것을 감지한다. 그리고 kube-scheduler는 Pod 할당에 적절한 노드를 찾는다.
  • 적절한 노드를 찾으면 kube-schedler가 kube-apiserver에 적합한 노드를 알린다. 다시 말해 kube-scheduler가 Pod를 생성하는 것은 아니고 단지 찾고 알리며, 최종적으로는 할당될 노드의 kubelet이 Pod를 생성한다.

3. Pod 할당에 가장 적절한 노드 선택

Pod에 할당할 가장 적절한 노드 선택은 노드 필터링과 노드 가중치 점수를 계산하여 결정한다.

3.1. 노드 필터링

Pod 할당에 필요한 조건(예, CPU, 메모리 등)을 충족하는 노드를 선택하는 과정이다. 이러한 조건을 predicates라고 부른다. 이 조건들을 predicates.go 파일이나 scheduler_algorithm.md 파일에서 확인 가능하다.

  • 노드가 Running 상태이다.
  • Pod가 요구하는 리소스를 수용할 수 있어야 한다.
  • Pod에 설정된 Node Selector와 Node Label이 일치한다.
  • 노드의 Paints와 Pod의  Toleration이 일치한다.
  • 노드 Affinity, Pod Anti/Affinity를 고려한다.

3.2. 노드 가중치 점수 계산

3.1.의 노드 필터링을 통해 feasible 노드를 선정한 후에는, 그 노드 가운데 최종적으로 어떤 노드를 선택한지 고른다. 여기서는 스코어 방식이 사용되며 여러 가중치를 계산하는 함수를 통해 최종 점수가 나온다.

그런데 노드 수가 엄청 많으면 계산을 위한 Scheduler의 성능 저하가 발생할 수 있기 때문에 Kubernetes 버전에 따라서는 percentageOfNodesToScore라는 기능을 통해 일정 수의 노드만큼만 점수를 부여한다.

3.3. NodeSelector

특정 노드에 스케줄링되도록 nodeSelector를 설정할 수 있다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd