Kube-Scheduler (스케줄러) - 쿠버네티스의 지능형 테트리스 봇

핵심 인사이트 (3줄 요약)

  1. 본질: Kube-Scheduler(스케줄러)는 쿠버네티스 마스터 노드(Control Plane) 안에서 24시간 눈에 불을 켜고 대기하며, 엔지니어가 "새로운 팟(Pod) 띄워 줘!"라고 요청할 때 수십, 수백 대의 워커 노드(서버) 스펙을 스캔하여 '이 팟이 어느 노드의 빈 공간에 들어가는 것이 가장 완벽할지' 최적의 명당자리를 찍어주는(Binding) 뇌쇄적인 지능형 배치 알고리즘 엔진이다.
  2. 가치: 인간이 "이 앱은 3번 서버에 띄워야지"라고 엑셀로 노가다를 치는 수동 할당(Static Placement)을 완전히 멸망시켰다. 스케줄러는 서버들의 남은 CPU/RAM 잔여량을 계산할 뿐만 아니라, "DB 팟과 웹 팟은 찰싹 붙여놔라(친화성)", "똑같은 팟 3개는 한 서버에 몰빵하지 말고 분산시켜 놔라(반친화성)" 같은 극악의 **아키텍처 제약 조건들을 단 0.1초 만에 수리적으로 계산해 내어 거대 인프라의 극강 가용성(HA)**을 담보한다.
  3. 융합: 스케줄러 자체는 절대 팟을 직접 띄우지(Run) 않는다. 그저 etcd 장부의 nodeName 빈칸에 Worker-Node-4번이라고 이름표(Binding)만 딱 꽂아두고 퇴근하면, 현장 반장인 Kubelet이 그걸 보고 진짜 도커 엔진을 망치질하는 완벽한 디커플링(Decoupling) 마이크로서비스 구조와 융합되어 있다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: 쿠버네티스(K8s) 클러스터라는 거대한 호텔에 새로운 손님(Pod)이 캐리어를 끌고 찾아왔다. 손님은 "난 무조건 오션뷰(GPU 필수)에, 강아지(SSD 볼륨)랑 같이 잘 수 있고, 시끄러운 클럽(다른 무거운 앱) 옆 방은 싫어!"라고 깐깐하게 요구(yaml 스펙)한다. Kube-Scheduler는 이 호텔의 프론트 매니저다. 100개의 빈방 리스트를 스캔한 뒤 조건에 안 맞는 방은 칼같이 쳐내고(필터링), 남은 방 중에서 가장 쾌적하고 완벽한 1개의 방 번호를 뽑아 손님에게 배정해 주는 역할을 한다.

  • 필요성: 클라우드 이전에는 서버(EC2)가 10대 있으면, 개발자가 SSH로 들어가서 1번 서버엔 Nginx, 2번 서버엔 Redis 라고 하나하나 수동으로 띄웠다. 그러다 1번 서버의 CPU가 100%를 치고 터졌다. 남은 9대 서버는 CPU가 텅텅 놀고 있었다. **"서버가 1,000대로 늘어나면 인간의 뇌로는 도저히 팟(앱)들을 예쁘게 분산시켜 넣을 수 없다. 한 서버만 펑 터지는 참사를 막고 클러스터 전체 자원을 빈틈없이 꽉꽉 눌러 짜내는(Packing) 수학적 인공지능 배정 봇"**이 절실했고, 이것이 Kube-Scheduler의 존재 이유다.

  • 💡 비유: 복잡한 물류 창고에서 일하는 **'지게차 배차 반장님'**과 같습니다.

    • 트럭이 엄청 무거운 철근 박스(Pod)를 싣고 왔습니다. 반장님은 무전기를 듭니다.
    • "어이! 1번 창고는 이미 짐 꽉 찼으니 안 돼(CPU 부족). 2번 창고는 철근 옆에 물이 있어서 녹슬 테니 안 돼(반친화성)."
    • "오케이, 3번 창고 구석이 튼튼하고 빈자리도 널널하네! 지게차야, 이 박스 들어서 무조건 3번 창고에만 내려놔!"
    • 반장님(Scheduler)은 직접 짐을 들지 않고, 가장 완벽하고 밸런스가 맞는 창고 번호(Node)를 계산해서 서류에 적어주기만 합니다.
  • 등장 배경 및 발전 과정:

    1. 초기 Static Scheduling (도커 초기): 서버 IP와 포트를 포스트잇에 적어서 사람이 직접 타겟 서버에만 팟을 때려 넣던 미개한 시대.
    2. Borg 스케줄러의 이식 (2015): 구글이 10년간 갈고닦은 "수만 대 서버의 CPU 찌꺼기까지 긁어모아 테트리스 블록을 빈틈없이 꽂아 넣는" 압도적인 빈 패킹(Bin Packing) 알고리즘을 K8s 스케줄러로 오픈소스화.
    3. Custom Scheduler 춘추전국시대 (현재): 기본 스케줄러가 너무 CPU/RAM만 본다는 불만이 터지자, 딥러닝 GPU 전용 스케줄러나 에너지(전력) 최소화 스케줄러 등을 사람들이 직접 코딩해서 K8s 기본 스케줄러 멱살을 잡고 교체(Plug-in)할 수 있는 확장형 아키텍처로 완전 진화함.
  • 📢 섹션 요약 비유: 이삿짐센터 직원들이 장롱(Pod)을 어디에 놓을지 몰라 땀 뻘뻘 흘리고 있을 때, 방 크기와 장롱 크기, 햇빛 들어오는 방향까지 1초 만에 싹 스캔해서 도면에 "장롱은 안방 구석 23cm 띄우고 놔!"라고 정확한 X표를 찍어주는 천재 인테리어 디자이너입니다.


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

스케줄러의 2단계 마법: 필터링(Filtering)과 스코어링(Scoring)

API 서버가 "야, 집 없는 떠돌이 팟(Pending Pod) 하나 나왔어. 방 찾아줘!"라고 던지면, 스케줄러는 0.1초 동안 2단계의 가혹한 오디션을 열어 노드(서버)를 뽑는다.

  ┌───────────────────────────────────────────────────────────────┐
  │         Kube-Scheduler의 최적 워커 노드 배정 (Binding) 파이프라인        │
  ├───────────────────────────────────────────────────────────────┤
  │                                                               │
  │   [ 대기실 ] 떠돌이 팟 (Pod) 생성됨 (nodeName: 비어있음)               │
  │     - 팟 요구사항(yaml): "나 CPU 4개 필요함, 무조건 SSD 달린 서버에 갈거야!" │
  │                                                               │
  │  =============================================================│
  │   [ 1차 오디션: 필터링 (Filtering / Predicates) ] - "자격 없는 놈 탈락!"│
  │     - 클러스터 내의 노드 100대를 일렬로 세움.                         │
  │     - "너 CPU 4개 남아?" ─▶ 노드 30대 탈락! (70대 생존)               │
  │     - "너 SSD 라벨(Taints) 달려있어?" ─▶ 50대 탈락! (20대 생존)       │
  │     ▶ 결과: 살아남은 20대의 노드 ─▶ "합격(Feasible Nodes)"           │
  │                                                               │
  │  =============================================================│
  │   [ 2차 오디션: 스코어링 (Scoring / Priorities) ] - "최고의 명당은?"  │
  │     - 합격한 20대 노드에게 0~100점까지 점수를 매기는 가혹한 뷰티 콘테스트.   │
  │     - "너 이 팟 받아주면 자원(CPU)이 얼마나 예쁘게 꽉 차?" (점수 부여)     │
  │     - "이 팟이 좋아하는 DB 팟이 네 서버 안에 같이 살아?" (보너스 점수 +10) │
  │     - "이 팟이랑 똑같이 생긴 복제본 팟이 이미 네 서버에 있어? 넌 안돼 한 곳에 │
  │        몰빵하면 터져!" (마이너스 점수 -50)                           │
  │                                                               │
  │  =============================================================│
  │   [ 최종 낙찰 (Binding) ]                                       │
  │     - 99점으로 1등을 차지한 [노드 15번] 당첨!                          │
  │     - 스케줄러는 조용히 etcd 장부에 `nodeName: 노드 15번` 이라고 적고 퇴근. │
  │     - 그 후 15번 노드의 십장(Kubelet)이 이걸 보고 진짜로 도커 팟을 띄움.    │
  └───────────────────────────────────────────────────────────────┘

[다이어그램 해설] 스케줄러는 자기가 직접 컨테이너를 실행(Run)하지 않는다. 이것이 쿠버네티스의 위대한 '디커플링(Decoupling, 결합 끊기)' 철학이다. 스케줄러는 오직 API Server에게 "저기 빈칸(nodeName)에 노드 15번이라고 글씨 좀 써주세요"라고 부탁(Binding 요청)만 할 뿐이다. 그러면 각 노드에 파견 나가 있는 행동대장(Kubelet)이 1초마다 API 서버 장부를 쳐다보다가 "어라? 15번 노드(내 땅)에 새로 배정된 팟이 생겼네? 당장 도커 엔진 돌려라!"라며 망치질을 시작한다. 뇌(스케줄러)와 손발(Kubelet)이 완벽히 쪼개져 서로 알 필요가 없으니 시스템이 뻗어도 연쇄 폭발이 일어나지 않는다.


노드 통제 무기: Node Affinity vs Taints & Tolerations

개발자가 스케줄러의 멱살을 잡고 내가 원하는 서버로 강제 배정시키는 두 가지 마법 주문서.

무기 종류주체 (누가 튕겨내나)작동 원리 및 비유
Node Affinity
(노드 친화성)
Pod (손님)손님이 "나는 창가 자리(GPU 노드) 아니면 안 앉아!"라고 고집을 부리는 룰. 스케줄러는 손님의 입맛에 맞는 노드만 골라서 배정한다. (끌어당김의 힘)
Taints & Tolerations
(얼룩과 용인)
Node (방주인)방주인(노드)이 문 앞에 똥(Taint)을 뿌려놓고 "내 방에 들어오지 마!"라고 차단벽을 친다. 단, 이 똥 냄새를 참을 수 있는 특수 방독면(Toleration)을 쓴 VVIP 팟만 스케줄러가 들여보내 준다. (밀어냄의 힘)

Ⅲ. 실무 적용 및 기술사적 판단

실무 시나리오

  1. 시나리오 — 스케줄링 붕괴를 부른 자원 한계(Requests/Limits) 미설정: 스타트업 개발팀이 스프링 부트(Spring Boot) 팟 50개를 K8s에 배포했다. yaml 파일에 CPU/RAM을 얼마나 먹을지(resources.requests) 적어주는 걸 깜빡했다. Kube-Scheduler는 "오! 이 녀석들은 밥을 0(Zero)만큼 먹는 애들이군!"이라며 1번 워커 노드 1대에 50개 팟을 무식하게 다 욱여넣어 배정(Schedule)해 버렸다. 1시간 뒤 유저 트래픽이 몰리자 50개 파드가 일제히 램(RAM)을 빨아먹기 시작했고, 1번 노드는 결국 OOM (Out Of Memory) 킬러의 낫을 맞고 펑 터지며 클러스터가 마비되었다.

    • 판단: 스케줄러는 점쟁이가 아니다. 개발자가 미리 알려준 requests 명세서를 기반으로 테트리스를 꽂는다. 이 명세서를 빼먹어 스케줄러의 필터링 오디션 자체를 무력화시킨 치명적 장애다.
    • 해결책: 무조건(Must-have) Deployment yaml 파일에 **Requests (최소 보장 밥그릇)**와 **Limits (최대 폭식 제한선)**를 강제 하드코딩해야 한다. 만약 requests: cpu: 1, memory: 2Gi라고 적어주면, 스케줄러는 "이 놈은 등치가 크군. 1번 노드는 이미 꽉 찼으니 탈락(Filter)! 널널한 3번 노드에 넣어라"라며 기가 막히게 분산 배치를 때려 넣는다. 더 나아가 클러스터 어드미션 컨트롤러에 LimitRange 정책을 걸어, Requests를 안 적고 오는 싸가지 없는 팟은 스케줄링 대기실(Pending)에 아예 들어오지도 못하게 걷어차 버려야 인프라가 생존한다.
  2. 시나리오 — 다중화(HA) 붕괴를 막아내는 Anti-Affinity (반친화성) 튜닝: 대형 금융사에서 결제 API 파드를 3개 복제(Replica=3)해서 K8s에 띄웠다. Kube-Scheduler는 빈 공간이 가장 많았던 "5번 워커 노드"에 3개 파드를 나란히 예쁘게 다 꽂아넣었다(Score 1등). 그런데 다음 날, AWS 5번 노드가 낙뢰를 맞아 통째로 사망했다. 결제 파드 3개가 한 서버에서 한방에 동반 자살(SPOF)하며 전국 결제망이 다운되었다. 사장님이 "아니 복제(Replica)를 3개나 했는데 왜 다 죽어?"라며 노발대발했다.

    • 판단: 스케줄러는 "같은 종류의 파드를 한 바구니에 담지 마라"는 비즈니스 고가용성(HA) 원칙을 스스로 알아서 깨우치진 못한다. 스코어링의 패배다.
    • 해결책: 배포 yaml에 PodAntiAffinity (파드 반친화성) 룰을 영혼까지 끌어 모아 박아 넣어야 한다. "나랑 똑같은 라벨(Label)을 가진 쌍둥이 파드가 이미 살고 있는 노드(서버)에는, 절대 나를 배정하지 마라!"라고 선언한다. 이 룰을 본 스케줄러는 식은땀을 흘리며 첫 번째 팟은 1번 노드에, 두 번째 팟은 2번 노드에, 세 번째 팟은 3번 노드에 강제로 멀찍이 떨어뜨려 찢어놓는다(Scheduling). 이제 1번 노드 서버가 벼락에 맞아 불타도, 2번 3번 노드에 숨어있는 결제 파드가 멀쩡히 살아남아 트래픽을 완벽하게 방어해 내는 진정한 클라우드 다중화의 기적이 달성된다.

도입 체크리스트

  • Custom Scheduler (커스텀 스케줄러)의 유혹: "K8s 기본 스케줄러가 너무 바보같이 CPU만 봐! 넷플릭스처럼 우리는 '네트워크 통신이 가장 빠른 노드'에 팟을 배정하는 딥러닝 스케줄러 파이썬으로 직접 짜서 얹자!" 할 수 있다. K8s는 스케줄러를 갈아 끼울 수 있다. 하지만 스타트업에서 이 짓을 하면 100% 후회한다. 스케줄러를 직접 짜면 클러스터 업그레이드 때마다 충돌(Dependency Hell)이 나고 팟들이 허공에 떠서 Pending 지옥에 빠진다. 웬만하면 기본 Kube-Scheduler가 제공하는 엄청난 수준의 Taint, Toleration, Affinity 옵션을 영혼까지 쥐어짜서 사용하는 것이 인프라 운영자의 장수 비결이다.

Ⅳ. 기대효과 및 결론

정량/정성 기대효과

구분인간의 수동 배정 (Static Placement)Kube-Scheduler 자율 배정 알고리즘클라우드 인프라 파괴적 혁신
정량 (서버 가동률 / 비용)"이 서버는 웹만, 저긴 DB만" (자원 50% 낭비)1,000대 서버의 빈틈에 팟 테트리스 압축 박기서버 고집적화(Bin Packing)로 AWS 요금 40% 절약
정량 (스케일 아웃 속도)관리자가 SSH 들어가서 IP 찍고 띄우는 데 5분1초 만에 최적 서버 100군데 찍고 동시 폭격 띄움트래픽 폭발 시 오토 스케일링 민첩성 극대화
정성 (다중화 보장 HA)실수로 한 서버에 핵심 모듈 다 때려 박음 (SPOF)Anti-Affinity로 무조건 물리적 격리 보장 찢기클라우드 AZ(가용 영역) 붕괴 시에도 서비스 100% 생존 보장

쿠버네티스가 클라우드 제국의 황제가 된 이유는 화려한 컨테이너 때문이 아니다. 보이지 않는 지하실에서 수만 대의 컴퓨터 CPU 찌꺼기 용량까지 싹싹 긁어모아 가장 완벽하고 이상적인 위치에 블록을 꽂아 넣는 이 'Kube-Scheduler의 미친 테트리스(Bin Packing) 알고리즘' 덕분이다. 기술사는 아무 생각 없이 파드 갯수만 늘리는 하수에서 벗어나야 한다. 팟이 Pending(대기) 상태에 빠져 허공에 둥둥 떠 있을 때, 스케줄러의 1차 오디션(CPU 부족)에서 탈락했는지, 2차 뷰티 콘테스트(Affinity 꼬임)에서 감점을 먹었는지를 꿰뚫어 보고, Taint와 Toleration이라는 몽둥이와 당근을 휘둘러 팟들을 내가 원하는 영토에 예쁘게 안착시키는 클러스터의 마에스트로(지휘자)로 각성해야 한다.


📌 관련 개념 맵 (Knowledge Graph)

개념 명칭관계 및 시너지 설명
Kube-API Server스케줄러의 유일한 상전이자 우체국. 스케줄러는 자기가 일거리를 직접 찾지 않고, API 서버가 "야, 아직 집(Node) 배정 못 받은 백수 팟 1개 나왔어!"라고 알려줘야 비로소 움직인다.
Pending (대기 상태)스케줄러가 팟을 띄워줄 빈 서버(CPU/RAM)를 찾지 못했거나, Affinity 조건이 너무 빡세서 실패했을 때 팟이 빠지는 무한 대기 지옥. 장애의 90%는 여기서 터진다.
Taints & Tolerations노드(방주인)가 특정 파드가 못 들어오게 똥(Taints)을 뿌려 차단막을 치고, 오직 이 똥 냄새를 견딜 수 있는 특수 방독면(Toleration)을 쓴 VIP 파드만 쏙 들여보내는 스케줄러의 문지기 스킬.
Bin Packing (빈 패킹)스케줄러의 핵심 수학 알고리즘. 빈 박스(노드 자원) 안에 각기 다른 크기의 물건(파드 CPU)들을 버리는 공간 1도 없이 꽉꽉 눌러 담아 테트리스를 끝내는 인프라 비용 절약의 궁극기.
Kubelet (큐블릿)스케줄러가 etcd 장부에 "이 팟은 5번 노드 당첨!"이라고 글씨만 쓰고 퇴근하면, 5번 노드에 사는 현장 십장(Kubelet)이 그걸 보고 자기가 진짜로 망치질을 해 도커 컨테이너를 띄운다.

👶 어린이를 위한 3줄 비유 설명

  1. 거대한 기차(클러스터)에 1,000명의 손님(파드)이 한꺼번에 표를 끊으러 몰려왔어요! 빈자리는 많은데 누가 어디 앉을지 몰라 엉망진창이 되겠죠?
  2. 이때 번개처럼 빠른 **'자리 배정 컴퓨터(스케줄러)'**가 짠! 나타납니다. 1초 만에 손님들의 요구사항을 쫙 스캔해요. "뚱뚱한 손님(CPU 많이 먹음)은 넓은 자리! 싸운 친구(반친화성)는 멀리 떨어뜨려!"
  3. 절대 사람들을 직접 끌고 가지는 않아요. 기차표에 "너는 3호 차 15번 좌석!"이라고 정확한 자리 번호(Node)만 쾅쾅 찍어주고 사라지면, 승무원(Kubelet)들이 표를 보고 안내해 주는 세상에서 제일 똑똑한 자리 배치 마법이랍니다!