스케줄러 성능 튜닝

스케줄러 성능 튜닝 (Scheduler Performance Tuning)

kube-scheduler는 Kubernetes의 기본 스케줄러예요. 클러스터의 노드(Node)에 Pod를 배치하는 역할을 담당합니다.

클러스터에서 Pod의 스케줄링 요구 사항을 충족하는 노드를 그 Pod의 **적합한 노드(feasible Node)**라고 해요. 스케줄러는 Pod에 적합한 노드를 찾은 뒤, 그 노드들에 점수를 매기는 일련의 함수를 실행해 가장 높은 점수를 받은 노드를 선택해 Pod를 실행합니다. 그 다음 스케줄러는 **바인딩(Binding)**이라는 과정으로 이 결정을 API 서버에 알려요.

이 페이지는 대규모 Kubernetes 클러스터에서 유용한 성능 튜닝 최적화를 설명합니다.

대규모 클러스터에서는 **지연 시간(latency: 새 Pod를 빠르게 배치)**과 정확성(accuracy: 스케줄러가 나쁜 배치 결정을 거의 내리지 않음) 사이에서 균형을 맞추도록 스케줄러 동작을 튜닝할 수 있어요.

이 튜닝 설정은 kube-scheduler의 percentageOfNodesToScore 설정으로 구성합니다. 이 KubeSchedulerConfiguration 설정은 클러스터에서 스케줄링할 노드의 임계값을 결정합니다.

임계값 설정 (Setting the threshold)

percentageOfNodesToScore 옵션은 0과 100 사이의 정수 값을 받아요. 값 0은 특별한 숫자로, kube-scheduler가 컴파일 시 내장된 기본값을 사용하라는 뜻입니다. percentageOfNodesToScore를 100보다 크게 설정하면 kube-scheduler는 100으로 설정한 것처럼 동작해요.

값을 바꾸려면 kube-scheduler 구성 파일을 편집한 뒤 스케줄러를 재시작하세요. 대부분의 경우 구성 파일은 /etc/kubernetes/config/kube-scheduler.yaml에서 찾을 수 있어요.

변경을 마친 뒤 다음을 실행해

kubectl get pods -n kube-system | grep kube-scheduler

kube-scheduler 컴포넌트가 정상인지 확인할 수 있어요.

출처: 문서

노드 점수 계산 임계값 (Node scoring threshold)

스케줄링 성능을 높이기 위해 kube-scheduler는 적합한 노드를 충분히 찾으면 탐색을 멈출 수 있어요. 대규모 클러스터에서는 모든 노드를 고려하는 단순한 방식보다 시간을 아낄 수 있습니다.

얼마나 많은 노드가 충분한지 임계값을 클러스터 전체 노드 수의 정수 백분율로 지정합니다. kube-scheduler는 이를 정수 개수의 노드로 변환해요. 스케줄링 중 kube-scheduler가 설정된 백분율을 넘을 만큼 충분한 적합한 노드를 찾으면, 더 이상 적합한 노드를 찾지 않고 **점수 계산 단계(scoring phase)**로 넘어갑니다.

스케줄러가 노드를 어떻게 순회하는지는 How the scheduler iterates over Nodes에서 자세히 설명해요.

기본 임계값 (Default threshold)

임계값을 지정하지 않으면 Kubernetes는 100노드 클러스터에서 50%, 5000노드 클러스터에서 10%가 되는 선형 공식으로 값을 계산합니다. 자동 값의 하한은 5%예요.

즉, 명시적으로 percentageOfNodesToScore를 5보다 작게 설정하지 않는 한, 클러스터가 아무리 커도 kube-scheduler는 항상 클러스터의 최소 5% 이상에는 점수를 매겨요.

스케줄러가 클러스터의 모든 노드에 점수를 매기게 하려면 percentageOfNodesToScore를 100으로 설정하세요.

예시 (Example)

percentageOfNodesToScore를 50%로 설정하는 예시 구성이에요.

apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
  provider: DefaultProvider

...

percentageOfNodesToScore: 50

percentageOfNodesToScore 튜닝 (Tuning percentageOfNodesToScore)

percentageOfNodesToScore는 1과 100 사이의 값이어야 하며, 기본값은 클러스터 크기에 따라 계산됩니다. 또한 100노드라는 하드코딩된 최솟값도 있어요.

참고: 적합한 노드가 100개 미만인 클러스터에서는 스케줄러의 탐색을 일찍 멈출 만큼 적합한 노드가 충분하지 않으므로 스케줄러가 여전히 모든 노드를 확인합니다. 작은 클러스터에서 percentageOfNodesToScore를 낮게 설정하면 비슷한 이유로 효과가 없거나 거의 없습니다. 클러스터에 수백 개 이하의 노드가 있다면 이 구성 옵션을 기본값으로 두세요. 변경해도 스케줄러 성능이 크게 개선되지 않을 가능성이 높습니다.

이 값을 설정할 때 고려해야 할 중요한 세부 사항은, 클러스터에서 더 적은 수의 노드가 적합성 검사를 받으면 주어진 Pod에 대해 점수 계산에 보내지지 않는 노드가 생긴다는 점이에요. 결과적으로 주어진 Pod를 실행하는 데 더 높은 점수를 받을 수 있는 노드가 점수 계산 단계에 아예 전달되지 않을 수도 있습니다. 이는 Pod 배치가 이상적이지 않게 만드는 결과를 낳아요.

kube-scheduler가 자주 나쁜 Pod 배치 결정을 내리지 않도록 percentageOfNodesToScore를 아주 낮게 설정하지 마세요. 스케줄러의 처리량(throughput)이 애플리케이션에 중요하고 노드 점수가 중요하지 않은 경우가 아니라면 백분율을 10% 미만으로 설정하지 마세요. 다시 말해, 적합하기만 하면 어떤 노드든 상관없이 Pod를 실행하고 싶은 경우를 말해요.

스케줄러가 노드를 순회하는 방법 (How the scheduler iterates over Nodes)

이 섹션은 이 기능의 내부 세부 사항을 이해하려는 사람을 위한 것이에요.

클러스터의 모든 노드가 Pod 실행 후보로 공정하게 고려될 기회를 받도록, 스케줄러는 라운드 로빈(round robin) 방식으로 노드를 순회합니다. 노드가 배열에 있다고 상상해보세요. 스케줄러는 배열의 시작부터 시작해 percentageOfNodesToScore가 지정한 만큼 충분한 노드를 찾을 때까지 노드의 적합성을 확인합니다. 다음 Pod에 대해서는 이전 Pod의 적합성 확인을 멈춘 노드 배열 지점부터 계속합니다.

노드가 여러 존(zone)에 있으면, 스케줄러는 서로 다른 존의 노드가 적합성 검사에 고려되도록 다양한 존의 노드를 순회합니다. 예를 들어 두 존에 여섯 개의 노드가 있다고 해볼게요.

Zone 1: Node 1, Node 2, Node 3, Node 4
Zone 2: Node 5, Node 6

스케줄러는 다음 순서로 노드의 적합성을 평가합니다.

Node 1, Node 5, Node 2, Node 6, Node 3, Node 4

모든 노드를 살펴본 뒤에는 다시 Node 1로 돌아갑니다.

기회주의적 배칭 활성화 (Enabling Opportunistic Batching)

대규모 워크로드를 스케줄링할 때 Pod들은 종종 동등한 스케줄링 제약을 가지며 스케줄러가 같은 작업을 반복해서 수행해야 해요. Opportunistic Batching 기능은 스케줄러가 스케줄링 사이클 간에 필터링과 점수 계산 결과를 재사용할 수 있게 해줘서 스케줄링 과정을 크게 빠르게 합니다.

rescoring을 사용하면 그 상황에서도 스케줄러가 배칭을 계속할 수 있어요. 다음 Pod가 이전에 선택한 노드에 여전히 들어갈 수 있으면, 스케줄러는 그 노드의 점수를 갱신하고 캐시된 후보 목록에 다시 넣습니다. rescoring이 성공하지 못하면 스케줄러는 기존 동작으로 돌아가 캐시를 비웁니다.

기본적으로 이 기능은 이렇게 동작해요.

  • 스케줄러가 pod-1을 스케줄하고 스케줄링 결과를 캐시합니다.
  • 스케줄러가 캐시된 결과로 pod-2, 3, ...을 스케줄합니다.
  • 캐시는 0.5초 후에 만료됩니다. 스케줄러는 다음 Pod를 스케줄하며 새로운 캐시를 만듭니다.

동등한 스케줄링 제약을 가진 Pod는 스케줄링 사이클에 연속으로(back to back) 들어와야 해요. 스케줄러가 다른 제약을 가진 Pod를 스케줄할 때는 캐시를 사용하지 않고 새 캐시로 교체합니다.

이 배칭 스케줄링은 다음 조건을 만족하는 Pod에 적용합니다.

  • 파드 간 어피니티/안티-어피니티(inter pod affinity/anti-affinity)가 없음
  • 토폴로지 분배 제약(topology spread constraints)이 없음
  • DRA가 없음(즉 Resource Claim이 없음)
  • DRA가 뒷받침하는 확장 리소스를 요청하지 않음

또한 이 기능을 활성화하려면 스케줄러 구성에서 다음을 해야 해요.

  • 기본 토폴로지 분배를 비활성화(비워 두기)
  • InterPodAffinityArgsIgnorePreferredTermsOfExistingPodstrue로 설정해 배칭을 더 효율적으로 만들기

다음 경우에도 유의하세요.

  • 기존 Pod가 스케줄된 Pod의 레이블과 일치하는 파드 어피니티 제약을 사용하면 이 기능이 이점을 주지 못할 수 있음
  • 사용자 정의 플러그인을 사용한다면 Signature 확장 지점을 구현해야 함

이 제한과 조건은 향후 릴리스에서 진화할 것으로 예상됩니다.

다음 단계 (What's next)

더 알아보기 (Learn more)