Infra/Kubernetes & EKS

쿠버네티스 Node/Pod Affinity와 Taint-Tolerations 개념 정리

jimmy_AI 2024. 6. 13. 01:05
반응형

kubernetes(k8s) 에서 많이 사용되지만 혼동되는 개념인

Affinity와 Taint-Tolerations에 대해서 정리해보도록 하겠습니다.

 

 

0. 언제 사용되는 개념인가요?

해당 개념들은 Pod를 Node에 배정하는 스케줄링을 진행할 때,

조건을 제어하는 용도로 사용됩니다.

 

 

1. Node Affinity

사용 목적

Pod를 특정한 조건을 만족하는 Node에 배정하고 싶을 때 사용합니다.

 

 

종류

- 필수 조건 (requiredDuringSchedulingIgnoredDuringExecution):

반드시 만족해야 하는 조건입니다.

해당 조건을 만족하지 않으면 Pod는 해당 노드에 스케줄링되지 않습니다.


- 선호 조건 (preferredDuringSchedulingIgnoredDuringExecution):

만족하면 좋지만, 필수는 아닌 조건입니다.

우선 순위에 따라 선호도가 높은 노드에 스케줄링됩니다.

 

 

사용 예제

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: region
            operator: In
            values:
            - kr
  containers:
  - name: nginx
    image: nginx

위의 yaml 파일 예시에서는 disktype=ssd인 node에만 pod가 할당될 수 있습니다.

 

선호 조건의 경우에는 조건 만족 가중치인 weight를 지정하게 되며, region=kr인 경우

해당 가중치만큼의 가산점을 기존 자원 가용성 등의 조건 점수와 합쳐서 계산됩니다.

 

 

node selector와의 차이점

node selector는 명시적인 라벨 이름에 대한 비교만 가능한 반면,

node affinity는 In, Not In, Existed, DoesNotExisted 등의 고급 연산자를 제공하고,

AND나 OR의 복합 조건에 대한 필터링도 가능하게 만들어 유연한 노드 선택을 지원합니다.

 

각 고급 연산자의 필터링 조건은 다음과 같습니다.

  • In: 키=값까지 완전히 일치
  • NotIn: 키=값까지 완전히 일치하면 안됨
  • Exists: 특정 키가 존재(값은 상관 없음)
  • DoesNotExist: 특정 키가 존재하면 안됨

 

AND 조건 사용 예시

(하나의 matchExpressions 내에 여러 조건 나열)

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
          - key: region
            operator: Exists
  containers:
  - name: nginx
    image: nginx

disktype=ssd이고, region key가 존재하는 경우에 대한 필터링 yaml 파일 예시입니다.

 

OR 조건 사용 예시

(matchExpressions를 여러 개 나열)

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
        - matchExpressions:
          - key: region
            operator: Exists
  containers:
  - name: nginx
    image: nginx

여기서는 disktype=ssd 이거나 region key가 존재하는 경우에 대한

필터링을 진행하는 yaml 파일의 예시가 됩니다.

 

 

2. Pod Affinity / Pod Anti-Affinity

사용 목적

Pod Affinity: pod가 다른 특정 조건의 pod와 같은 node에 떠야할 때 사용합니다.

ex) 두 pod가 같은 PV를 공유하는 경우

 

Pod Anti-Affinity: pod가 다른 특정 조건의 pod와 다른 node에 떠야할 때 사용합니다.

ex) 두 pod가 master-slave 구조로 하나가 백업 용도로 사용되어야 할 때

 

 

종류

여기서도 필수 / 선호 조건으로 나눌 수 있으며,

이에 대한 설명은 Node Affinity 부분과 동일합니다.

 

 

사용 예제

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: region
            operator: In
            values:
            - kr
        topologyKey: "kubernetes.io/hostname"
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app-name
            operator: In
            values:
            - backup
        topologyKey: "kubernetes.io/hostname"
  containers:
  - name: nginx
    image: nginx

 

위의 예시에서는 배정받으려는 node 내에 region=kr인 pod는 있어야 하며,

app-name=backup인 pod는 있어서는 안됩니다.

 

다른 심화 문법(고급 연산자 및 복합 조건)의 적용 예제는

Node Affinity와 마찬가지로 적용이 가능합니다.

 

 

3. Taint-Tolerations

사용 목적

특정 node 내에 배정될 수 있는 pod들의 조건을 제한하는 용도로 사용합니다.

비유를 하자면, VIP 회원권을 가진 회원들만 출입이 가능한 라운지라고 생각하면 됩니다.

 

Node에 Taint 조건을 걸어두고, pod에 Tolerations을 해당하는 Taint 조건을 일치시켜

적어주면, 해당 pod는 그 Node에 배정받을 수 있는 자격이 생기는 것입니다.

 

다만, VIP 회원권을 가진 회원들이 일반 라운지에도 출입이 가능한 것처럼,

Tolerations만 적어주면 다른 Node에도 여전히 배정이 가능하므로,

일반적으로 node selector나 affinity 등의 조건을 같이 사용하게 됩니다.

 

실제 사용의 케이스로는 node가 GPU를 보유한 경우,

GPU 점유가 필요한 pod들만 그 node에 배정이 가능하게 만드는 경우 등에 사용됩니다.

 

 

종류

Taint는 key, value, effect로 구성되는데, key=value는 만족해야할 조건을 의미하며,
effect는 스케줄링 조건이며 아래의 3가지 값 중 하나를 가질 수 있습니다.

  • NoSchedule: 조건을 만족하지 않는 Pod는 해당 노드에 스케줄링되지 않습니다.
  • PreferNoSchedule: 가능하면 조건을 만족하지 않는 Pod를 다른 노드에 스케줄링합니다.
  • NoExecute: 조건을 만족하지 않는 Pod는 즉시 퇴출되며, 새로 스케줄링되지 않습니다.

 

참고로, Tolerations에서 key, value 뿐만 아니라 effect까지 모두 일치시켜야

배정이 가능해집니다.

 

그리고, NoExecute는 Taint를 pod 배정 이후 나중에 적용하더라도

이미 배정된 pod들에게도 영향을 끼칠 수 있는 옵션인 것으로 이해해주시면 됩니다.

 

 

사용 예제

참고: 노드에 테인트 조건을 추가하는 명령어

kubectl taint nodes nodename key=value:NoSchedule

 

pod에 Tolerations을 지정한 yaml 파일 예제

apiVersion: v1
kind: Pod
metadata:
  name: with-tolerations
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
  containers:
  - name: nginx
    image: nginx

 

이제 해당 pod는 key=value:NoSchedule의 Taint를 가진 node에도 배정이 가능해졌습니다.