LabHub
배우기 러닝패스 코스

CKA — Kubernetes管理者

スケジューリングを制御する

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

파드가 어느 노드에 뜰지 결정하는 일곱 가지 수단을 전부 써 보고, 마지막에는 앞 단계에서 만든 클러스터 상태(cordon 된 노드, 테인트된 노드)를 고려해 배치를 설계합니다.

왜 중요한가

스케줄링은 CKA 에서 배점이 크지 않지만 트러블슈팅 문제의 절반이 사실 스케줄링 문제입니다. Pending 파드를 보고 filter 단계의 어느 조건에서 걸렸는지 읽어 낼 수 있어야 합니다.

특히 topologySpreadConstraints 는 오해가 많습니다. 편차를 계산할 때 쓰는 후보 도메인은 파드의 nodeAffinity/nodeSelector 를 통과하는 노드들입니다. 테인트는 기본적으로 무시하고 셉니다. 그래서 파드가 쓸 수 없는 노드가 0개짜리 도메인으로 남아 편차를 키우고, DoNotSchedule 이면 나머지 파드가 전부 Pending 이 되는 일이 흔합니다. 후보를 좁히는 열쇠가 노드 어피니티라는 걸 아는 것이 이 실습의 핵심입니다.

단계

  1. 네임스페이스 cka-sched 를 만든다. lab-node-0topology.kubernetes.io/zone=zone-a, lab-node-1zone-b, lab-node-2zone-c 라벨을 붙이고, lab-node-0 에 추가로 disktype=ssd 를 붙인다. 그 다음 파드 ssd-pod (이미지 nginx:1.27)를 nodeSelector disktype=ssd 로 만들어 lab-node-0 에 뜨게 한다.
  2. lab-node-2disktype=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 로 배치되게 한다.

참고

노드 라벨과 nodeSelector

네임스페이스 cka-sched 를 만든다. lab-node-0topology.kubernetes.io/zone=zone-a, lab-node-1zone-b, lab-node-2zone-c 라벨을 붙이고, lab-node-0 에 추가로 disktype=ssd 를 붙인다. 그 다음 파드 ssd-pod (이미지 nginx:1.27)를 nodeSelector disktype=ssd 로 만들어 lab-node-0 에 뜨게 한다.

nodeSelector 는 파드 스펙 최상위에 오는 맵입니다. 라벨이 정확히 일치해야 하며 표현식은 쓸 수 없습니다.

required 노드 어피니티

lab-node-2disktype=hdd 라벨을 붙이고, 파드 affinity-required 를 required 노드 어피니티(disktype In [hdd])만으로 lab-node-2 에 배치한다. nodeSelector 는 쓰지 않는다.

affinity.nodeAffinity 아래 requiredDuringSchedulingIgnoredDuringExecution 안에는 nodeSelectorTerms 배열이 들어갑니다. matchExpressions 의 operator 는 In 입니다. nodeSelector 는 쓰지 마세요.

preferred 노드 어피니티

Deployment pref (레플리카 2, 이미지 nginx:1.27)를 만들고 preferred 노드 어피니티를 붙인다. weight 는 50, 조건은 disktype In [ssd].

preferred 쪽은 배열이고 각 항목이 weight 와 preference 를 갖습니다. 못 맞춰도 배치되므로 어디에 떴는지는 채점하지 않습니다.

파드 안티어피니티로 흩뿌리기

Deployment spread (레플리카 3, 파드 라벨 app=spread)를 만들고, required 파드 안티어피니티를 붙인다. labelSelector 는 app=spread, topologyKey 는 topology.kubernetes.io/zone.

podAntiAffinity 의 항목은 labelSelector 와 topologyKey 를 갖습니다. 노드마다 존 라벨이 다르니 존 단위로 흩으면 결과적으로 노드가 갈립니다.

노드 비우기

Deployment drain-demo (레플리카 2, 이미지 nginx:1.27)를 만든 뒤, lab-node-1 을 cordon 하고 drain 해서 완전히 비운다. drain-demo 는 다른 노드에서 2/2 로 돌아와야 한다.

cordon 은 새 파드만 막고 이미 뜬 파드는 그대로 둡니다. 실제로 비우려면 drain 이 필요하고, 데몬셋과 emptyDir 관련 옵션을 붙여야 진행됩니다.

테인트와 톨러레이션

lab-node-2 에 테인트 workload=batch:NoSchedule 을 건다. 파드 batch-pod 에 그 테인트를 견디는 톨러레이션과 nodeSelector disktype=hdd 를 주어 lab-node-2 에 배치한다.

테인트는 key=value:effect 형식입니다. 톨러레이션은 operator 를 Equal 로 두고 value 까지 맞춰야 합니다. 어느 노드로 갈지는 별도로 지정해야 합니다.

PriorityClass 붙이기

PriorityClass cka-high 를 만든다. value 100000, globalDefault false, preemptionPolicy PreemptLowerPriority. 파드 important 에 이 클래스를 지정한다.

PriorityClass 는 클러스터 스코프입니다. globalDefault 를 true 로 두면 클러스터 전체 파드에 영향을 주니 주의하세요. 파드에 이름만 적으면 spec.priority 는 자동으로 채워집니다.

종합: 남은 노드에 고르게 흩뿌리기

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 로 배치되게 한다.

지금 이 클러스터에서 파드를 받을 수 있는 노드가 몇 개인지 먼저 세어 보세요. cordon 된 노드는 후보에서 빼야 하고, 테인트된 노드는 톨러레이션이 있어야 씁니다. 후보를 줄이는 열쇠는 노드 어피니티입니다.