CKA — 쿠버네티스 관리자 · 워크로드와 스케줄링 · 실습
스케줄링 제어하기
목표
파드가 어느 노드에 뜰지 결정하는 일곱 가지 수단을 전부 써 보고, 마지막에는 앞 단계에서 만든 클러스터 상태(cordon 된 노드, 테인트된 노드)를 고려해 배치를 설계합니다.
왜 중요한가
스케줄링은 CKA 에서 배점이 크지 않지만 트러블슈팅 문제의 절반이 사실 스케줄링 문제입니다. Pending 파드를 보고 filter 단계의 어느 조건에서 걸렸는지 읽어 낼 수 있어야 합니다.
특히 topologySpreadConstraints 는 오해가 많습니다. 편차를 계산할 때 쓰는 후보 도메인은 파드의 nodeAffinity/nodeSelector 를 통과하는 노드들입니다. 테인트는 기본적으로 무시하고 셉니다. 그래서 파드가 쓸 수 없는 노드가 0개짜리 도메인으로 남아 편차를 키우고, DoNotSchedule 이면 나머지 파드가 전부 Pending 이 되는 일이 흔합니다. 후보를 좁히는 열쇠가 노드 어피니티라는 걸 아는 것이 이 실습의 핵심입니다.
단계
1. 네임스페이스 cka-sched 를 만든다. lab-node-0 에 topology.kubernetes.io/zone=zone-a, lab-node-1 에 zone-b, lab-node-2 에 zone-c 라벨을 붙이고, lab-node-0 에 추가로 disktype=ssd 를 붙인다. 그 다음 파드 ssd-pod (이미지 nginx:1.27)를 nodeSelector disktype=ssd 로 만들어 lab-node-0 에 뜨게 한다.
2. lab-node-2 에 disktype=hdd 라벨을 붙이고, 파드 affinity-required 를 required 노드 어피니티(disktype In [hdd])만으로 lab-node-2 에 배치한다. nodeSelector 는 쓰지 않는다.
3. Deployment pref (레플리카 2, 이미지 nginx:1.27)를 만들고 preferred 노드 어피니티를 붙인다. weight 는 50, 조건은 disktype In [ssd].
4. Deployment spread (레플리카 3, 파드 라벨 app=spread)를 만들고, required 파드 안티어피니티를 붙인다. labelSelector 는 app=spread, topologyKey 는 topology.kubernetes.io/zone.
5. Deployment drain-demo (레플리카 2, 이미지 nginx:1.27)를 만든 뒤, lab-node-1 을 cordon 하고 drain 해서 완전히 비운다. drain-demo 는 다른 노드에서 2/2 로 돌아와야 한다.
6. lab-node-2 에 테인트 workload=batch:NoSchedule 을 건다. 파드 batch-pod 에 그 테인트를 견디는 톨러레이션과 nodeSelector disktype=hdd 를 주어 lab-node-2 에 배치한다.
7. PriorityClass cka-high 를 만든다. value 100000, globalDefault false, preemptionPolicy PreemptLowerPriority. 파드 important 에 이 클래스를 지정한다.
8. Deployment evenly (레플리카 4, 파드 라벨 app=evenly)를 만든다. topologySpreadConstraints 는 maxSkew 1, topologyKey topology.kubernetes.io/zone, whenUnsatisfiable DoNotSchedule, labelSelector app=evenly. 여기에 required 노드 어피니티 disktype In [ssd, hdd] 와 workload=batch:NoSchedule 톨러레이션을 함께 붙여, 4개 파드가 두 존에 2:2 로 배치되게 한다.
참고
kubectl get pods -n cka-sched -o wide로 어느 노드에 떴는지 바로 볼 수 있습니다.- drain 은
--ignore-daemonsets --delete-emptydir-data --force를 붙여야 대개 끝까지 진행됩니다. - 흔한 실수 1: 5단계에서 cordon 만 하고 끝내는 것. cordon 은 새 파드만 막습니다.
- 흔한 실수 2: 8단계에서 노드 어피니티를 빼먹는 것. 그러면 cordon 된
lab-node-1이 파드 0개인 존으로 남아 편차가 2가 되고 절반이 Pending 에 머뭅니다.
단계 8개
- 노드 라벨과 nodeSelector
- required 노드 어피니티
- preferred 노드 어피니티
- 파드 안티어피니티로 흩뿌리기
- 노드 비우기
- 테인트와 톨러레이션
- PriorityClass 붙이기
- 종합: 남은 노드에 고르게 흩뿌리기