Pod 스케줄링 준비 상태
Pod 스케줄링 준비 상태 (Pod Scheduling Readiness)
FEATURE STATE: Kubernetes v1.30 [stable]
Pod는 일단 생성되면 스케줄링 준비가 된 것으로 간주됐어요. Kubernetes 스케줄러는 대기 중인 모든 Pod를 배치할 노드를 찾기 위해 최선을 다해요. 하지만 실제 세상에서는 어떤 Pod가 오랫동안 "필수 리소스 누락(miss-essential-resources)" 상태에 머물 수도 있어요. 그런 Pod들은 실제로 스케줄러(그리고 Cluster AutoScaler 같은 하위 통합 도구)를 불필요하게 뒤흔들어 놓죠.
Pod의 .spec.schedulingGates를 지정하거나 제거해서, Pod가 언제 스케줄링 후보가 될 준비가 됐는지를 제어할 수 있어요.
Pod schedulingGates 구성하기
schedulingGates 필드는 문자열 목록이에요. 각 문자열 리터럴은 Pod가 스케줄링 가능하다고 간주되기 전에 충족해야 하는 기준으로 인식돼요. 이 필드는 Pod가 생성될 때만 초기화할 수 있어요(클라이언트가 하든, 어드미션 과정에서 변형되든). 생성 이후에는 각 schedulingGate를 임의의 순서로 제거할 수 있지만, 새 scheduling gate를 추가하는 것은 허용되지 않아요.
사용 예시
Pod를 스케줄링 준비 안 됨으로 표시하려면, 다음과 같이 하나 이상의 스케줄링 게이트를 넣어서 생성하면 돼요.
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
schedulingGates:
- name: example.com/foo
- name: example.com/bar
containers:
- name: pause
image: registry.k8s.io/pause:3.6
Pod 생성 후에 상태를 확인해 볼게요.
kubectl get pod test-pod
출력에서 SchedulingGated 상태인 걸 확인할 수 있어요.
NAME READY STATUS RESTARTS AGE
test-pod 0/1 SchedulingGated 0 7s
schedulingGates 필드도 확인해 볼게요.
kubectl get pod test-pod -o jsonpath='{.spec.schedulingGates}'
출력은 이렇게 나와요.
[{"name":"example.com/foo"},{"name":"example.com/bar"}]
이 Pod가 스케줄링 준비가 됐다는 걸 스케줄러에 알리려면, 수정된 매니페스트를 다시 적용해서 schedulingGates를 완전히 제거하면 돼요.
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.6
schedulingGates가 지워졌는지 확인해 볼게요.
kubectl get pod test-pod -o jsonpath='{.spec.schedulingGates}'
출력은 비어 있을 거예요. 그리고 최신 상태는 이렇게 확인해요.
kubectl get pod test-pod -o wide
test-pod는 CPU/메모리 리소스를 요청하지 않으므로, 이 Pod의 상태가 이전 SchedulingGated에서 Running으로 바뀌는 걸 볼 수 있을 거예요.
NAME READY STATUS RESTARTS AGE IP NODE
test-pod 1/1 Running 0 15s 10.0.0.4 node-2
관측성
scheduler_pending_pods 메트릭에는 새 레이블 "gated"가 붙어 있어요. 이 레이블로 Pod가 스케줄링을 시도했지만 스케줄링 불가로 분류된 건지, 아니면 명시적으로 스케줄링 준비 안 됨으로 표시된 건지를 구분할 수 있어요. scheduler_pending_pods{queue="gated"}로 메트릭 결과를 확인할 수 있어요.
변경 가능한 Pod 스케줄링 지시어
Pod에 스케줄링 게이트가 있는 동안에도 스케줄링 지시어를 변경할 수 있어요. 단, 몇 가지 제약이 있어요. 크게 보면 Pod의 스케줄링 지시어를 더 조이는 방향으로만 변경할 수 있어요. 바꿔 말하면, 갱신된 지시어 때문에 Pod가 이전에 매칭됐던 노드의 부분집합에서만 스케줄링될 수 있게 된다는 뜻이에요. 좀 더 구체적으로, Pod 스케줄링 지시어를 갱신하는 규칙은 다음과 같아요.
.spec.nodeSelector에 대해서는 추가만 허용돼요. 없던 경우라면 설정하는 것도 허용돼요.spec.affinity.nodeAffinity가 nil이면 아무 것이나 설정할 수 있어요.NodeSelectorTerms가 비어 있으면 설정이 허용돼요. 비어 있지 않으면matchExpressions나fieldExpressions에NodeSelectorRequirements를 추가하는 것만 허용되고, 기존matchExpressions와fieldExpressions는 변경할 수 없어요. 그 이유는.requiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms의 용어들은 OR로 결합되는 반면,nodeSelectorTerms[].matchExpressions와nodeSelectorTerms[].fieldExpressions의 표현식들은 AND로 결합되기 때문이에요..preferredDuringSchedulingIgnoredDuringExecution에 대해서는 모든 갱신이 허용돼요. 선호(preferred) 용어는 권위적이지 않기 때문에, 정책 컨트롤러가 그 용어들을 검증하지 않아요.
더 알아보기
- PodSchedulingReadiness KEP에서 자세한 내용을 읽어 보세요.