Kubernetes: 스케줄러 비헤이비어

14898 단어 kubernetes
Kubernetes에서 Pod을 노드에 분배하는 스케줄러kube-scheduler의 동작을 정리했습니다.kubernetes v1.9.2 인증 행위와 인용 소스 코드를 사용합니다.

스케줄러의 일


Kubernetes 스케줄러는 Pod을 새로 만들 때 가장 좋은 노드를 선택하고 분배하는 작업을 합니다.스케줄러에서 중요한 것은 어떻게 최적 노드를 선택하여 각종 필터와 우선순위 설정을 실현하는가이다.
스케줄러는 독립된 바이너리 프로그램kube-scheduler이다.정책 파일을 통한 유연한 사용자 정의, 필터와 우선 순위를 선택할 수 있으며, 우선 순위를 가중할 수 있으며, WebHook을 통해 확장할 수 있습니다.
대략적인 동작은 다음과 같다.
  • 새 Pod 만들기
  • 스케줄러가 API 서버를 모니터링하여 이 이벤트를 감지합니다
  • 스케줄러가 최적의 노드를 선택하여 노드에 할당
  • 노드 이름을 Pod로 설정.spec.NodeName
  • 노드에 있는kubelet이 자신의 노드에 분배된Pod
  • 을 검출하고 생성합니다

    프로세스


    스케줄러는 시작 후 탐색기 선택 --leader-elect 이나 감시 (이동기) Pod을 준비하고 Scheduler.scheduleOne() 방법을 주 순환으로 호출합니다.
    소스 코드: main() -> Options.Run() -> SchedulerServer.Run() -> Scheduler.Run() -> Scheduler.scheduleOne()
    scheduler.go
    // Scheduler.Run() のメインループの設定
    func (sched *Scheduler) Run() {
        // ... 省略
        // StopEverything チャネルが閉じられるまで shced.ScheduleOne を繰り返す
        go wait.Until(sched.scheduleOne, 0, sched.config.StopEverything)
    
    Scheduler. scheduleOne() 다음과 같이 대기열에서 분배되지 않은 Pod을 하나씩 꺼내서 가장 적합한 노드를 연결합니다.할당할 Pod이 없으면 대기열에서 검색NextPod()이 차단됩니다.InformerFramework를 사용하여 Pod 변경 사항을 감지하고 대기열에 Pod을 비동기적으로 추가합니다(참조: podInformer 이벤트 처리 프로그램.
    **

    최적 노드 선택


    Pod에 대한 최적 노드를 선택하는 것은 다음 조건(아래 그림 참조)을 통해 노드와 우선권(priorities)을 선별하는 것입니다.정책 파일을 통한 유연한 사용자 정의.

  • predicates: 노드를 필터하는 조건입니다.예를 들어 노드에 대한 nodeSelector 기반 선택 또는 리퀘스트 자원에 대한 빈 상태가 있는 필터

  • 우선 순위: 노드 우선 순위.예를 들어, Pod이 노드, 영역을 최대한 분산시킬 수 있는 우선 순위가 있습니다.
  • 또한 Pod / Node Affinity 과 같이 반드시 requiredDuringSchedulingIgnoredDuringExecution우선preferredDuringSchedulingIgnoredDuringExecution과 둘 다predicates,priorities에서 이루어진다.
    소스 코드: Scheduler.scheduleOne() -> Scheduler.schedule() -> genericScheduler.Schedule()

    노드 필터


    사전 할당은 노드를 필터링하는 기준입니다.모든 Predicate의 처리는 다음과 같은 FitPredicate 인터페이스를 실현하는 함수입니다. 이 인터페이스는bool에서 노드가 조건을 충족하는지 되돌려줍니다.가속predicate의 필터는 각 노드에 따라 병렬적으로 계산됩니다.
    // FitPredicate is a function that indicates if a pod fits into an existing node.
    // The failure information is given by the error.
    type FitPredicate func(pod *v1.Pod, meta PredicateMetadata, nodeInfo *schedulercache.NodeInfo) (bool, []PredicateFailureReason, error)
    
  • 소스 코드(전체 처리): genericScheduler.Schedule() -> findNodesThatFit()
  • 소스 코드(Predicate당): predicates.go(정의), defaults.go(등록)
  • Predicates
    설명PodFitsResources노드의 빈 자원이Pod가 요청한 자원의 request 값에 부합되는지 여부입니다.참조: How Pods with resource requests are scheduledPodFitsHostPortsPod에서 hostPort를 사용할 때 노드의 포트가 비어 있는지 여부HostNamePodSpecnodeName의 지정이 일치하는 경우 노드의 호스트 이름과 일치하는지 여부MatchNodeSelectornodeSelector 에 지정된 레이블 및 노드 일치 여부NoDiskConflictPod이 다른 디스크를 마운트했는지 확인NoVolumeZoneConflictPod에서 요청한 볼륨이 같은 영역에 있는지 여부MatchInterPodAffinityPred부합 여부 확인Pod 사이의 affinityCheckNodeMemoryPressure메모리 공간이 부족하면 노드를 피하십시오(NodeCondition의 MemoryPressure 보기)CheckNodeDiskPressure디스크 공간이 부족하면 이 노드를 피하십시오 (노드 설정의 디스크 압력 보기)MaxGCEPDVolumeCount , MaxAzureDiskVolumeCount , MaxEBSVolumeCount모든 지속 부피의 부착 제한을 검사하다

    우선 순위 (노드 우선 순위)


    우선 순위는 노드 우선 순위의 과정이다.각 우선 순위 처리는 노드에 대해 0~10의 우선 순위를 설정합니다.모든 우선순위는 권중을 설정할 수 있으며, 모든 우선순위 처리가 끝나면 노드의 점수를 계산합니다. 아래와 같습니다.
    NodeA のスコア = (prioritiesA のスコア * 重み付け) + (prioritiesB のスコア * 重み付け) ....
    
    Priorities도 속도를 높이기 위한 것이다노드별 병렬 계산.Predicates와 달리 일부 노드는 독립적으로 계산할 수 없기 때문에 두 개의 맵/중복 함수로 구성되어 있습니다.(참조: Change interface of priority functions for easier "framework-based" parallelization #24246
    // PriorityMapFunction is a function that computes per-node results for a given node.
    // TODO: Figure out the exact API of this method.
    // TODO: Change interface{} to a specific type.
    type PriorityMapFunction func(pod *v1.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (schedulerapi.HostPriority, error)
    
    // PriorityReduceFunction is a function that aggregated per-node results and computes
    // final scores for all nodes.
    // TODO: Figure out the exact API of this method.
    // TODO: Change interface{} to a specific type.
    type PriorityReduceFunction func(pod *v1.Pod, meta interface{}, nodeNameToInfo map[string]*schedulercache.NodeInfo, result schedulerapi.HostPriorityList) error
    
  • 소스 코드(전체 처리): genericScheduler.Schedule() -> PrioritizeNodes()
  • 소스 코드(Priority당): scheduler/algorithm/priorities/(정의), defaults.go(등록)
  • 가중치는 NodePreferAvoidPodsPriority 을 제외하고 모두 1입니다.
    Priority
    설명SelectorSpreadPriority가능한 한 같은 유형의 Pod을 노드나 영역에 분포합니다InterPodAffinityPriority부합 여부 확인Pod 사이의 affinityLeastRequestedPriority자원 요청 값 총계가 비교적 적은 노드를 우선적으로 고려하다BalancedResourceAllocation프로세서 및 메모리 활용도 균형NodePreferAvoidPodsPriority preferAvoidPods의 Node 주석에 대한 고려 사항다른 우선을 위해서는 이것우선 순위 설정 10000밖에 없다.NodeAffinityPriorityNode Affinity 우선 순위TaintTolerationPriorityTaintPreferNoSchedule고려

    총결산


    Kubernetes 스케줄러는 다양한 필터와 우선 순위를 사용하여 Pod을 최상의 노드에 할당합니다.관심 있으면 노드나 구역에 PodSelectorSpreadPriority을 분포하는 등 스케줄러의 원본 코드를 볼 수 있습니다.

    참고 자료

  • https://github.com/kubernetes/community/blob/master/contributors/devel/scheduler.md
  • https://github.com/kubernetes/community/blob/master/contributors/devel/scheduler_algorithm.md
  • 기록 시간의 최근 소스 코드 이동plugin/pkg/scheduler -> pkg/scheduler이 있기 때문에 향후 버전에서 디렉터리가 달라질 것입니다. 

    좋은 웹페이지 즐겨찾기