포스트

[CKA] 쿠버네티스 스케줄링

[CKA] 쿠버네티스 스케줄링

본 글은 Udemy Certified Kubernetes Administrator (CKA) 강의를 참조해 정리한 내용을 기록했습니다.

Manual Scheduling

앞서 배운 kube-scheduler는 자동으로 pod를 적절한 노드에 배치한다.

image.png

어떤 Node가 적합한지 점수를 측정해 판단하는 kube-scheduler

하지만 실제 운영 환경 구축을 위해 어떠한 Node가 정상적으로 해당 Pod를 실행할 수 있는지 또는 Node↔Pod에 있어 호환성 등을 테스트 하기 위해 특정 Node에 Pod를 수동으로 배치하는 디버깅 목적으로 필요할 수 있다.

이럴 때 사용되는 것이 Manual Scheduling으로 kube-scheduler로 인해 배치하지 않고 사용자가 직접 Node를 선택해야한다.

이때 사용할 Node는 nodeName 으로 지정한다.

Manual Scheduling을 사용는 경우 YAML

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Pod
metadata:
  name: manually-scheduled-pod
spec:
  nodeName: worker-node-1  # 특정 노드에 직접 할당
  containers:
  - name: nginx
    image: nginx

이렇게 Node를 직접 이름으로 지정하는 방법 이외에도 k8s는 다양한 방법을 지원한다. 아래에서는 어떤식으로 k8s에서 pod의 Node 할당을 제어하는지 알아보겠다.

Taints & Tolerations

Taints는 오염 이라는 뜻을 가지고 Tolerations는 관용이라는 뜻을 가진다. 왜 쿠버네티스를 공부하는데 이러한 개념에 굳이 이러한 명칭을 가지는지는 잘 모르겠지만 이러한 개념들은 특정 Taints(오염) 된 Node에 Toleration(관용)되지 않은 Pod가 들어가지 않게 하는… 조금 더 쉽게 표현하자면 특정 Node에 Pod rule을 추가하는 것으로 의미할 수 있겠다.

이제부터 이러한 오염과 관용을 어떤식으로 제어할 수 있는지 알아보도록 하겠다.

Taints를 Node에 적용하기

taints를 적용하기 위해서는 Node에 명령줄을 추가 하여 적용하는다 일반적인 형식은 아래와 같다.

1
kubectl taint nodes <노드명> <>=<>:<효과>

일반적으로 키:값 형태로 매핑을 하고 이와 같은 Node가 있을 경우 <효과> 의 형태를 가지게 설정한다.

Tolerations를 Pod에 적용하기

더렵혀진 Node(taintsed Node)에 할당 되기 위해서는 pod의 spec 에 아래와 같은 toleration항목을 추가해줘야한다.

1
2
3
4
5
tolerations:
- key: "<키>"
  operator: "Equal"  # 또는 "Exists"
  value: "<값>"
  effect: "<효과>"

여기서 operator는 Equal 또는 Exists를 사용할 수 있으며, 각각 키와 값이 일치하거나 키만 존재하는 경우를 의미한다.

Taint가 Blue이고 Node의 Value에 Blue를 설정 한 경우

image.png

kube-schedulerKey=blue 가 아닌 Pod은 Node1에 할당하지 않고 tolerations가 blue인 Pod D만 Node1에 할당 한 것을 볼 수 있다.

이걸 왜 쓰는거지?

작업을 하다보면 특정 워크로드를 Node에 설정할 때가 있다. 예를 들어 데이터베이스 수정 같은 작업을 특정 노드에서만 할당 했다면 이 작업을 시작할 Pod는 toleration을 설정이 가능하다.

또한 이외에도 Node를 유지보수 한다거나(디버깅), 특정 Pod를 격리 시킬 때 이러한 개념을 사용할 수 있다.

Node Selector

pod는 별다른 제약이 없는한 어떠한 Node로도 할당 될 수 있다. 만약 Node간의 성능이 다르고 사양이 높은 pod가 저 사양의 Node에 할당이 된다면 서비스 운영에 제약이 발생할 수 있다.

이를 제한하기 위해 nodeSelector라는 개념을 사용해서 Key-Value 형식으로 어떠한 Node에 pod를 고정할지 지정이 가능하다.

image.png

일반적으로 Node에 label을 붙이기 위해서는 아래와 같은 형식을 따른다.

1
kubectl label nodes <node-name> <label-key>=<label-value>

예시

1
kubectl label nodes node-1 size=Large

이러한 방식은 간단하고 쉽게 도달되지만 더 높은 요구사항을 높이기 위해 Node Affinity라는 개념이 등장한다.

Node Aiffinity

label 기반 스케줄링 결정에 있어 강력한 효과를 낸다. 기존의 Node Selector에 비해 표현식(expression)을 사용해 더 복잡한 규칙을 만들 수 있다.

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values:
            - us-east1

  • requiredDuringSchedulingIgnoredDuringExecution (필수 규칙)

    pod가 스케줄링 되어질 때 반드시 해당하는 규칙의 Node에만 할당된다.

    위의 예제에서는 disktype **ssd인 node에만 스케줄링이 되도록 지정한다.

  • preferredDuringSchedulingIgnoredDuringExecution (선호 규칙)

    pod에 이러한 규칙이 우선적으로 적용되지만 반드시 만족하지 않아도 할당된다.

    zoneus-east1 인 node를 우선적으로 선호한다.

  • Operator (연산자)

    In: 지정한 값 중 하나와 일치

    NotIn: 지정한 값 중 어느 것도 일치하면 안된다.

    Exists: 지정한 Key가 Node에 존재해야 한다.

    DoesNotExist : 지정된 Key가 Node에 없어야한다.

Node Affinity의 동작 방식은 Pod가 스케줄링 될 때에만 적용된다는 것을 명심하자. 즉 Pod가 한번 Node에 배치가 된다면 label 이 변경되더라도 Pod는 지속적으로 실행된다. 또한 이러한 규칙의 우선순위에 따라 스케줄링 방식이 꼬일 수 있음을 인지하고 요구 사항에 맞게 적절하게 조합해야 한다.

Taints & Tolerations vs Node Affinity

해당 개념들은 모두 Pod의 스케줄링을 제어하는 기능으로 각자 다른 방식으로 동작한다.

Taints & Tolerations

  • 특정 Node에서 Pod를 거부하거나 허용함

Node Affinity

  • Pod의 배치에 있어 선호도를 사용 가능
  • Label을 통해 제한함

일반적으로 Taints & Tolerations는 특정 Node에서 Pod를 퇴출하는데 사용되고 Node에 특정 Pod를 배치하는데는 Node Affinity가 선호된다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.