Kubernetes

[k8s] Scheduling, Binding 개념

코딩 못하는 감자 2025. 2. 4. 01:44

쿠버네티스 스케줄링 과정

1️⃣ 스케줄러가 새로운 파드 탐색

  • kube-scheduler는 Pending 상태의 파드를 스캔하여 아직 배정되지 않은 (nodeName이 없는) 파드를 찾음.

2️⃣ 적절한 노드 선택 (스케줄링 알고리즘 수행)

  • 기본적으로 2단계의 프로세스를 거쳐 적절한 노드를 선택함.
    1. 필터링 (Filtering, Predicate Phase)
      • 리소스 부족, taint/toleration, nodeSelector 등의 조건을 만족하지 않는 노드는 제외.
    2. 점수 매기기 (Scoring, Priority Phase)
      • 남은 후보 노드 중에서 가장 적절한 노드를 선택.

3️⃣ Binding 객체 생성

  • kube-scheduler가 적절한 노드를 찾으면, Binding 객체를 생성하여 kube-apiserver에 요청.

4️⃣ kube-apiserver가 바인딩 요청을 저장 및 전달

  • kube-apiserver는 해당 요청을 받아 ETCD에 저장하고, 해당 노드의 kubelet에게 전달.

5️⃣ kubelet이 파드 생성 요청 처리

  • kubelet은 컨테이너 런타임(Container Runtime, 예: Docker, containerd 등) 을 통해 컨테이너를 실행.

6️⃣ 파드 상태 업데이트

  • kubelet이 파드의 상태를 Running 으로 변경하여 kube-apiserver에 보고.
  • 이후 kube-apiserver가 이를 ETCD에 저장.

7️⃣ 클라이언트에 상태 반환

  • 클라이언트(kubectl get pods 등)에서 조회하면 업데이트된 상태(Running 등)를 확인 가능.

✅ 정리 

kube-scheduler가 Pending 상태의 파드를 검색적절한 노드를 찾기 위해 필터링 & 점수 매기기 수행바인딩 객체를 생성하여 kube-apiserver에 요청kube-apiserver가 요청을 ETCD에 저장하고, kubelet에 전달kubelet이 컨테이너 런타임을 사용해 파드 생성kubelet이 상태 업데이트 후 kube-apiserver에 보고kube-apiserver가 클라이언트 요청에 대한 응답 반환


💡 추가 보완 사항

스케줄러는 파드를 직접 배치하지 않는다.

  • 스케줄러는 단순히 적절한 노드를 찾아 바인딩 요청을 보낼 뿐, 직접 파드를 실행하지 않음.
  • 파드를 생성하는 실제 작업은 kubelet과 컨테이너 런타임이 수행.

스케줄링 알고리즘의 중요성

  • Predicate(필터링) + Priority(우선순위 매기기) 단계를 통해 노드를 선택.
  • Node Affinity, Taints & Tolerations, Resource Requests 등이 영향을 미칠 수 있음.

스케줄링 과정에서 ETCD가 중요한 역할을 함

  • 모든 상태 변경 사항은 kube-apiserver를 통해 ETCD에 저장됨.
  • 따라서 kubectl get pods 등을 실행할 때 항상 최신 상태를 가져올 수 있음.

스케줄러가 없는 경우

kube-system namespace에 스케줄러가 존재하지 않는 경우 두가지 방법을 통해 node에 pod를 할당할 수 있다.

  1. Pod를 생성할 때 node 지정
  2. Binding Api 를 통해 node 지정

Pod를 생성할 때 Node 지정

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx
  nodeName: node01  # 특정 노드 지정

Binding Json 요청

{
  "apiVersion": "v1",
  "kind": "Binding",
  "metadata": {
    "name": "my-pod"
  },
  "target": {
    "apiVersion": "v1",
    "kind": "Node",
    "name": "node01"
  }
}

kubectl을 사용해 Binding API에 요청 전송:

kubectl create -f binding.json