Cloud Native/K8s

k8s 이론: 스케줄링

lys4321 2026. 2. 23. 19:03

스케줄링 - k8s 스케줄러

  • kube-scheduler 란?
    • k8s 클러스터에서 어떤 Pod를 어떤 노드에 배치할지 결정하는 기본 스케줄러
    • Control Plane의 일부로 실행
    • 기본 스케줄러이기 때문에 사용자 정의 스케줄러를 생성해서 사용할 수 있다.
    • 새로 생성되었거나 아직 노드가 할당되지 않은 Pod를 감지하여 이 파드를 실행할 노드를 선택
  • 작동원리-노드 선택 과정
    • 2단계를 거쳐 선택하게 됨
    • Filtering
      • Pod의 요구를 만족하는 가능 후보 노드들을 걸러냄
      • 만약 하나도 없다면 Pod는 대기상태(pending)
    • Scoring
      • 후보 노드 중 어떤 노드가 제일 적합한지 평가하기 위해 각각에 점수를 매김, 여러 기준으로 점수가 매겨짐
      • 스코어가 가장 높은 노드에 Pod를 바인딩
      • 만약 스코어가 같다면 그 노드들 중 무작위로 선택
  • 스케줄러의 구조
    • kube-scheduler는 기본 스케줄링 로직을 core라는 것에 두고 많은 스케줄링 기능들을 플러그인 형태로 구현하게 끔 설계 됨
      => 스케줄링 프레임워크(Scheduling Framework)
    • 여러 Extension Point를 제공하며 다양한 단계에 플러그인을 부착한다.

스케줄링 - 노드에 파드 할당하기

  • 노드에 Pod를 할당하는 방법(노드 선택 제약 방식)
    • nodeSelector
      • Pod Spec에 nodeSelector 필드를 써 노드 Label과 일치하는 노드만 후보에 포함되도록 지정
    • Anffinity/Anti-Affinity
      • Node Affinity 로 특정 노드 Label을 조건으로 하거나 Pod Affinity/Anti-Affinity로 같은 노드나 토폴로직 도메인 안에 있거나 피하거나 같은 조건을 설정 가능
        • soft rule
          • 우선선호
        • hard rule
          • 반드시 만족
    • nodeName
      • Pod Spec에 직접 NodeName 필드를 써 정확히 이 노드에만 스케줄 하도록 지정
      • 이 경우엔 스케줄러를 우회하여 지정 노드를 kubelet이 직접 시도
    • Pod Toplogy Spread Constraint(토폴로지 분산 제약조건)
      • Pod들이 클러스터 내 노드/존/도메인에 걸쳐 고르게 분산되도록 제약을 주는 방식
      • 노드 지정이 아닌 균형 맞추기에 중점

스케줄링 - Pod Overhead

  • Pod가 내부 컨테이너들을 실행하는 것 이상으로 추가 시스템 리소스를 소비하는 것을 반영하기 위한 기술
  • 설정법
    • RuntimeClass + overhead 필드
      • 해당 Pod가 속한 RuntimeClass가 overhead 필드를 정의해야함
      • Admission 시점에 이 overhead값이 Pod의 spec.overhead 필드로 설정
      • Pod Overhead는 사용자가 직접 overhead를 지정하는게 아닌, RuntimeClass 레벨에서 정의한 Pod 인프라 비용에 대한 고정값을 기반으로 동작
  • 스케줄링, 리소스 쿼터, croup에 미치는 영향
    • 스케줄러가 Pod를 노드에 스케줄하기 전, 컨테이너들의 리소스 요청 총합 + Pod Overhead 를 더한 값을 보고 여유가 있는지 판단
    • 클러스터에 ResourceQuota 가 설정되어있다면 컨테이너 요청만이 아닌 Pod Overhead도 quota 계산에 포함
    • Pod가 실제 할당된 후, 노드의 kubelet은 이 추가 오버헤드를 고려해 Pod 단위 cgroup 의 리소스 제한을 설정
    • 이로 인하여 Pod 인프라 + 실제 워크로드 리소르를 기준으로 노드 리소스 사용량이 산정

스케줄링 - Scheduling Framework

  • k8s 의 기본 스케줄러를 플러그인 가능하도록 만든 아키텍쳐
  • Scheduling Cycle & Binding Cycle 워크 플로우
    • Scheduing Cycle
      • 어떤 노드로 Pod 를 보낼지 결정하는 단계
      • 순차적으로 실행
    • Binding Cycle
      • 이전 단계에서 선택된 노드에 실제로 Pod를 바인딩하는 단계
      • 병렬적으로 실행
    • 둘 중에 하나라도 오류거나 Pod가 스케줄 불가능(inschedulable)하다고 판단될 시, 그 Pod는 내부 큐로 되돌아가 재시도 됨

스케줄링 - Dynamic Resource Allocation(DRA)

  • k8s 클러스터에서 GPU, FPGA, NIC, 특수 디바이스 등과 같은 노드에 부착된 디바이스를 Pod가 요청하고 실행 시점에 자동 할당되도록 하는 기술
    • 할당이 가능한 장치 전체를 다루는 표준화된 자원 요청 및 할당 API를 제공
  • 디바이스 드라이버가 DRA를 지원해야하며 구현이 올바르게 설정 되어있어야 한다.
  • 만약 Pod를 직접 spec.nodename 으로 노드를 지정한 상태로 생성 시, 스케줄러가 우회될 수 있어 이 경우 ResourceClaim이 없거나 할당되지 않으면 Pod 실행 실패나 지연이 될 수 있다.
  • API 오브젝트 종류
    • DeviceClass
      • 클러스터에 존재하는 디바이스의 카테고리를 정의
      • ResourceSlice
        • 실제 노드에 붙어있는 디바이스 풀 정보를 나타냄
      • ResourceClaim
        • 워크로드가 디바이스를 요청 시, 사용하는 리소스 창구(resource Claim) 오브젝트
        • 이 Claim이 승인되면 특정 디바이스 할당
      • ResourceClaimTemplate
        • StatefulSet, Deployment 같이 여러 Pod 생성 시, 사용할 템플릿
        • 각 Pod 마다 자동으로 ResourceClaim을 생성하도록 함
  • DRA 워크플로우
    • 클러스터 관리자 또는 드라이버가 클러스터에 DeviceClass 와 ResourceSlice를 설정
      • 어떤 노드에 어떤 디바이스를 붙일지 선언
    • 워크로드 작성자는 Pod Spec에 resourceClaims 나 ResourceClaimTemplate를 사용해 원하는 디바이스를 요청
    • 스케줄러는 클러스터의 ResourceSlices 정보를 읽고 요청에 맞는 디바이스가 남아있는지 확인
      • 조건이 맞는 디바이스가 있다면 해당 ResouceClaim에 할당(allocation) 정보를 기록하고, 그 정보를 바탕으로 Pod를 노드에 스케줄
    • Pod가 해당 노드에서 실행이 되며 드라이버 + kubelete이 디바이스를 실제로 컨테이너에 바인딩하고 설정
  • DRA 의 장점
    • 유연한 디바이스 요청/필터링
    • 공유 자원/효율적 리소스 활용
    • 표준화된 API & 스케불링 통합
    • Pod 기반 자원 관리

스케줄링 - 파드 우선순위와 선점

  • k8s 에선 Pod에 우선순위(priority)를 붙일 수 있다.
  • PriorityClass-우선순위 설정 방법
    • 우선순위는 PriorityClass 라는 non-namespaced 오브젝트를 통해 정의
      • 이 객체는 name과 value를 매핑
      • priorityClassName 필드를 Pod Spec에 지정하면 해당 우선순위 값이 Pod에 할다
    • PriorityCalss 의 value 필드는 32비트 정수이며 클러스터 내에서 우선순위 비교 기준이 된다.
    • globalDefault 옵션을 true로 설정한 PriorityClass 가 있다면 만약에 Pod에 priorityClassName이 지정되지 않았을 때 그 우선순위가 기본값으로 적용
      • globalDefault는 1개만 존재 가능
    • PriorityClass 를 삭제해도 이미 그 클래스를 사용한 Pod 가있다면 그 Pod의 우선순위는 유지가 된다.
  • 선점(Preemption) 동작 방식
    • Pod 생성 시, 스케줄러에 대기열에 들어가고 우선순위에 따라 대기열 내 순서가 정해짐
    • 만약 스케줄링이 가능한 노드가 없거나 Pod의 요구를 만족시키는 노드가 없다면 스케줄러는 선점 로직을 실행
    • 선점 로직은 삭제 가능한(lower-prioiry) Pod를 찾아 제거 시, 보류 중인 우선수위 Pod가 들어갈 여유가 생기는지 확인하는 것
    • 만약 생긴다면 해당 낮은 우선순위 Pod를 축출(Evict)하고 높은 우선순위를 가진 Pod를 스케줄
    • 선점(축출, Evict)된 Pod는 graceful termination period(기본값:30초)를 가지고 종료된다.
      • 만약 이 시간안에 종료가 되지 않다면 강제 종료
  • Non-preempting-PriorityClass
    • PriorityClass의 반대 버전
    • Pod Spec의 preemptionPolicy 필드의 값을 PreemptLowerPriority로 설정 시 사용 가능
      • Nerver로 설정 시, 선점은 하지 않게 되며 이 경우에는 리소스 여유가 생길 때가지 Pending함

스케줄링 - Node-Pressure Eviction

  • 클러스터의 각 노드에서 메모리, 디스크 등 시스템의 자원이 부족할 시 자동으로 일부 Pod를 축출(Evict)하여 자원을 회수하는 것
  • Runtime의 자원 관리를 위한 Clean-up 기술 사용
    • 스케줄러에 의한 할당 실패 + 재스케줄과는 다름
  • 목적
    • 노드의 자원이 고갈되어 시스템이 불안해지는걸 방지
    • 클러스터가 노드 전체가 죽거나 kubelet에 오류가 발생하는 사태를 막고 가능한 graceful 하게 자원을 회수하는 시도
  • Eviction 의 워크플로우
    • 노드-수준의 자원 회수를 시도
    • 시도를 하였으나 공간이 부족 시, Pod 선택 & 축출(Eviction)
    • 노드 상태 표시 및 taint 적용
    • 재스케줄링 및 자기 치유(self-Healing)

'Cloud Native > K8s' 카테고리의 다른 글

k8s 실전: 리소스 업데이터 및 기본 조작 명령어  (0) 2026.02.23
k8s 실전: 리소스 관련 명령어  (0) 2026.02.23
k8s 이론: 보안  (0) 2026.02.23
k8s 이론: 구성  (0) 2026.02.23
k8s 이론: 스토리지  (0) 2026.02.23