
오늘은 Multiple Schedulers를 실습했다. 개념 이해 후 kind 클러스터에서 커스텀 스케쥴러를 직접 배포하고, 이벤트 없는 Pending이 왜 생기는지, schedulerName이 왜 immutable인지를 몸으로 경험했다.
기본 kube-scheduler는 CPU/메모리, taint/toleration, affinity 정도를 고려한 범용 스케쥴러다. 하지만 아래 상황에서는 부족하다:
파드 spec에 schedulerName만 지정하면 해당 파드는 그 스케쥴러가 처리한다.
spec:
schedulerName: my-custom-scheduler # 생략하면 default-scheduler
schedulerName: my-custom-scheduler로 생성된 파드가 Pending이었다.
kubectl describe pod pending-app
# Events: <none>
일반 Pending(자원 부족, taint 거부)은 kube-scheduler가 시도하다 실패한 거라 이벤트가 남는다. schedulerName이 존재하지 않는 스케쥴러를 가리키면 아무도 이 파드를 건드리지 않아서 이벤트 자체가 없다.
kubectl get pod pending-app -o yaml | grep schedulerName
# schedulerName: my-custom-scheduler ← 여기서 원인 발견
grep 결과가 두 곳에서 나오는데, metadata.managedFields에도 같은 필드명이 찍히기 때문이다. 실제로 스케쥴러를 결정하는 건 spec.schedulerName 하나다.
원인을 알았으니 kubectl edit으로 고치려 했더니 막혔다.
spec: Forbidden: pod updates may not change fields other than
`spec.containers[*].image`, `spec.activeDeadlineSeconds`, ...
파드는 한번 생성되면 schedulerName을 포함한 대부분의 spec 필드가 불변이다. yaml 저장 후 삭제 재생성이 유일한 방법이다.
kubectl get pod pending-app -o yaml > pod.yaml
# pod.yaml에서 schedulerName 줄 삭제
kubectl delete pod pending-app --force --grace-period=0
kubectl apply -f pod.yaml
커스텀 스케쥴러가 kube-system에 올라온 상태에서 schedulerName: my-custom-scheduler로 파드를 만들고 Running 확인했다.
kubectl run custom-scheduled-pod --image=nginx --dry-run=client -o yaml > pod.yaml
# pod.yaml에 schedulerName: my-custom-scheduler 추가
kubectl apply -f pod.yaml
kubectl describe pod custom-scheduled-pod | grep -i scheduler
# Successfully assigned ... by my-custom-scheduler
kubectl get pods default-pod custom-pod \
-o custom-columns='NAME:.metadata.name,SCHEDULER:.spec.schedulerName,STATUS:.status.phase'
NAME SCHEDULER STATUS
default-pod default-scheduler Running
custom-pod my-custom-scheduler Running
이벤트로도 검증할 수 있다.
kubectl get events --field-selector reason=Scheduled
| 증상 | 원인 | 디버깅 포인트 |
|---|---|---|
| 이벤트 없이 Pending | schedulerName이 없는 스케쥴러를 가리킴 | kubectl get pod -o yaml \| grep schedulerName |
| 스케쥴러 Running인데 Pending | 스케쥴러 자체 문제 | kubectl logs <scheduler-pod> -n kube-system |
| kubectl edit 실패 | schedulerName은 immutable | yaml 저장 → 삭제 → 재생성 |
Q. Pod pending-app이 이벤트 없이 Pending 상태다. 원인을 찾고 default-scheduler로 수정하라.
→ spec.schedulerName이 존재하지 않는 스케쥴러를 가리킬 때 이벤트 없이 Pending. schedulerName은 immutable이므로 yaml 저장 후 삭제 재생성
Q. kube-system에 my-custom-scheduler가 running 중이다. 해당 스케쥴러를 사용하는 파드 custom-scheduled-pod를 생성하고 Running 상태를 확인하라.
→ spec.schedulerName: my-custom-scheduler 지정 후 kubectl describe의 Events에서 배치한 스케쥴러 확인
Q. default-scheduler와 my-custom-scheduler가 running 중이다. 각각을 사용하는 파드를 만들고 어느 스케쥴러가 배치했는지 확인하라.
→ schedulerName 지정 후 -o custom-columns로 spec.schedulerName 출력 or kubectl get events --field-selector reason=Scheduled