Cloud/k8s-CKA

[CKA] 8. schedule (Node Selector, Node Affinity)

jinkwon.kim 2023. 2. 11. 09:41
728x90
반응형

개요

Node Selector와 Node Affinity 기능에 대하여 알아보겠습니다. 

용도

두 기능의 용도는 Pod를 내가 원하는 Node에 배치하고 싶을 때 사용합니다. 

Node Selector

동작 방식 

특정 node에 Label을 설정 한 다음 node와 동일한 Label을 소유한 Pod만 특정 Node에 배치하는 것입니다. 

 

다음 그림은 Node1에  size: Large라는 Label를 설정 후 size: Large를 가진 Pod만 Node1에 배포하는 그림입니다.

Node에 Label 확인

#kubectl get nodes --show-labels
#kubectl get node worker1 --show-labels

Node에 Label 설정

kubectl label node <nodename> <label-name>=<label-value>

#kubectl label node worker1 size=Large

Node에 Label 제거 

설정할 때 사용한 명령에서  <label-name>=<label-value> 를 <label-name>- 으로 변경하면 됩니다. 

kubectl label node <node-name> <label-name>-

Pod에 NodeSelector 설정

pod를 어느 node에 배포 할 지를 설정 합니니다.

nodeSelector를 추가하면 됩니다. 

nodeSelector:

    key: Value

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: node-selector
  name: node-selector
spec:
  containers:
  - image: nginx
    name: node-selector
  nodeSelector:
    size: Large

NodeSelector의 한계

"or 조건" 또는 "Not 조건" 으로 Label을 설정할 수가 없습니다.

예를 들어 Node가 아래 왕같이 size: medium을 가진 node4가 추가되어 Pod들 중 size: large를 가진 Pod에 size: mdium을 추가하여 node1 또는 node4에 배포하고 싶지만 Node Selector는 1개의 Label만을 지원하기 때문에 이를 할 수가 없습니다.

Pod의 Node Selector에 2개의 Label을 넣으면 Pod가 생성은 되나 scheduling 되지 았습니다. 

Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  52s   default-scheduler  0/3 nodes are available: 1 node(s) had untolerated taint 
  {node-role.kubernetes.io/control-plane: }, 3 node(s) didn't match Pod's node affinity/selector. 
  preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.

 

이렇기 때문에 이를 해결하기 위해서 나온 것이 Node Affinity입니다. 

Node Affinity

https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity

개념

Node affinity는 NodeSelector와 개념적으로 유사하나, Node labels을 사용하여 여러 조건을 설정하여 Node에 설정한 조건에 맞는 Pod만을 배포 하고 싶을때 사용합니다. 

단순히 node label과 pod label일 같냐 아니냐로 동작하는 것은 아닙니다.

nodeAffinity types 

node의 label이 변화하면 Pod를 어떻게 처리할지를 결정합니다. 

2개의 type이 존재하며 type을 분석하면 아래와 같습니다.

type 분석

nodeAffinity 에서는 Pod에 대하여 node label maching 검사 시기를 를 2가지로 분류하고 있습니다.

DuringScheduling : 스케쥴링 하려는 Pod를 검사

DuringExecution : 이미 스케쥴링 된 Pod를 검사

그리고 Pod의 node label matching 통과 조건을 3가지로 분류 하고 있습니다.

required : 전부 일치prefered : node label과 일치하는게 있으면 해당 node를 선택하지만 없으면 기존 scheduling 방식으로 node선택ignored  : node label matching을 무시

2개 type의 nodeAffinity

requiredDuringSchedulingIgnoredDuringExecution

preferredDuringSchedulingIgnoredDuringExecution

node Appty type DuringScheduling (Pod의 sheduling시 영향줌) DuringExcution (실행중인 pod에 영향줌)
type 1 required (규칙과 일치 시) Ignored (규칙을 무시)
type 2 preferred (규칙을 선호) Ignored (규칙을 무시)
type 3 (not supported) required (규칙과 일치 시) required (규칙과 일치 시)

적용 우선 수위는 requiredDuringSchedulingIgnoredDuringExecution가 더 높습니다. 

type1 : requiredDuringSchedulingIgnoredDuringExecution

- 규칙과 일치하지 않으면 pod를 scheduling 하지 않습니다.

- 이미 실해 중인 pod에 대해서는 규칙을 적용하지 않습니다.

- nodeselect와 기능을 동일 하지만 좀 더 복잡하게 사용가능 합니다.

type2 : preferredDuringSchedulingIgnoredDuringExecution

- scheduler는 규칙을 충족하는 노드를 찾으려고 시도합니다. 

- 일치하는 노드를 사용할 수 없는 경우 schedule는 원래 방식대로 동작하여 node에 Pod를 배치합니다

- weight를 사용하여 pod 배치 우선순위를 결정합니다. 

Pod에 추가 방법

node affinity type : requiredDuringSchedulingIgnoredDuringExecution

규칙과 일치시

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: size
              operator: NotIn
              values:
                - Large

node affinity type :preferredDuringSchedulingIgnoredDuringExecution

규칙과 일치 및 선호도(weight) 반영

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
            - key: size
              operator: In
              values:
                - large
      - weight: 50
        preference:
          matchExpressions:
            - key: size
              operator: In
              values:
                - medium

nodeAffinity type 세부 항복

nodeSelectorTerms (requiredDuringScheduling 전용)

matchExpressions를 array로 가집니다.

weight (preferredDuringScheduling 전용)

어떤 matchExpressions을 먼저 적용하지 우선 순위를 선택 합니다. 

 

matchExpressions (공통)

node selector와 동일한 역할을 합니다. 다만 operator가 추가되었습니다.

operator 설명
In values 에 나열된 값들중 하나를 가진 Node에 Pod를 배치하게 합니다.
NotIn values에 나열이 안된 Node에 Pod를 배치하게 합니다.
Exists key 값을 가진 Node에 Pod를 배치하게 합니다.
DoesNotExit key 값이 없는 Node에 Pod를 배치하게 합니다. node taints로 대체 가능

weight

weight가 높은 곳에 pod를 먼저 배치합니다. 

weight는 1부터 100까지의 정수 값을 가질 수 있습니다. 그리고 높은 weight 값이 선호도가 높습니다.

최종 yaml 파일

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: node-affinity
  name: node-affinity
spec:
  replicas: 2
  selector:
    matchLabels:
      app: node-affinity
  strategy: {}
  template:
    metadata:
      labels:
        app: node-affinity
    spec:
      containers:
      - image: nginx
        name: nginx
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: size
                operator: In
                values:
                  - large
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 1
              preference:
                matchExpressions:
                  - key: size
                    operator: In
                    values:
                      - large
            - weight: 50
              preference:
                matchExpressions:
                  - key: size
                    operator: In
                    values:
                      - medium

nodeAffinity 우선 순위

1 순위 : requiredDuringSchedulingIgnoredDuringExecution

2 순위 : preferredDuringSchedulingIgnoredDuringExecution

동작 방식 

  1. 스케줄러는 먼저 requiredDuringSchedulingIgnoredDuringExecution 조건을 만족하는 모든 노드를 찾습니다. 이 단계에서 조건을 만족하지 못하는 노드는 후보군에서 제외됩니다.
  2. 그 다음, preferredDuringSchedulingIgnoredDuringExecution 조건에 따라 점수를 매겨 후보 노드들을 평가합니다. 이 점수는 노드가 파드에 얼마나 적합한지를 나타냅니다.
  3. 최종적으로, 가장 높은 점수를 받은 노드(들) 중에서 하나를 선택하여 파드를 배치합니다.

taints and Tolerations vs Node Affinity

taints and Tolerations (node가 scheduilng 제어)

node가 scheduling 된 Pod를 받을지 말지를 결정합니다.

단점 :  taint가 없는 node는 Pod의 toleration 보지 않기 때문에 toleration이 있는 Pod도 scheduilng 될 수도 있습니다.

Node Affinity (Pod가 scheduilng 제어)

Pod가 해당 Node에 scheduilng 될 수 있는 지를 결정 합니다.

단점 : Node Affinity 설정이 없는 pod는 label이 있는 node에  scheduilng 될 수도 있습니다. 왜냐하면 기본 scheduler를 node의 label을 보지 않고 scheduling 하기 때문입니다.

결론

pod를 원하는 node에 정확히 scheduilng 하려면 taint, toleration, node affinity를 모두 사용해야 합니다. 

 

정리 

node selector를 사용해서 간단하게 pod를 원하는 node를 배치할 수 있지만 복잡한 조건을 주어서 pod를 node에 배치하려면 

node affinity를 사용해야 합니다. 

그리고 node affinity는 2개의 type이 지원합니다.

 

type1 : requiredDuringSchedulingIgnoredDuringExecution

- 규칙과 일치하지 않으면 pod를 scheduling 하지 않습니다.

- 이미 실해 중인 pod에 대해서는 규칙을 적용하지 않습니다.

- nodeselect와 기능을 동일 하지만 좀 더 복잡하게 사용가능 합니다.

type2 : preferredDuringSchedulingIgnoredDuringExecution

- scheduler는 규칙을 충족하는 노드를 찾으려고 시도합니다. 

- 일치하는 노드를 사용할 수 없는 경우 schedule는 원래 방식대로 동작하여 node에 Pod를 배치합니다

- weight를 사용하여 pod 배치 우선순위를 결정합니다. 

Next Post

[CKA] 9. Pod resource 제어 방법

728x90
반응형