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 스케줄링 지시어를 갱신하는 규칙은 다음과 같아요.

  1. .spec.nodeSelector에 대해서는 추가만 허용돼요. 없던 경우라면 설정하는 것도 허용돼요.
  2. spec.affinity.nodeAffinity가 nil이면 아무 것이나 설정할 수 있어요.
  3. NodeSelectorTerms가 비어 있으면 설정이 허용돼요. 비어 있지 않으면 matchExpressionsfieldExpressionsNodeSelectorRequirements를 추가하는 것만 허용되고, 기존 matchExpressionsfieldExpressions는 변경할 수 없어요. 그 이유는 .requiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms의 용어들은 OR로 결합되는 반면, nodeSelectorTerms[].matchExpressionsnodeSelectorTerms[].fieldExpressions의 표현식들은 AND로 결합되기 때문이에요.
  4. .preferredDuringSchedulingIgnoredDuringExecution에 대해서는 모든 갱신이 허용돼요. 선호(preferred) 용어는 권위적이지 않기 때문에, 정책 컨트롤러가 그 용어들을 검증하지 않아요.

더 알아보기