Skip to main content

특정 노드에만 파드 배포하기

개요#

이번 시간에는 쿠버네티스의 특정 노드에만 파드를 배포하는 방법에 대해서 알아보겠습니다.

이를 위해서는 Node-AffinityTaintsToleration에 대해서 알아야합니다.

TaintsNode-Affinity와 반대되는 옵션입니다.

Node-AffinityPod가 특정 Node에 배포될 수 있게 하는 옵션이라면,

TaintsNode가 특정 Pod를 쫓아내는 옵션입니다.

Node-Affinity#

스크린샷 2021-02-17 오전 12 16 20스크린샷 2021-02-17 오전 12 16 28

Node-Affinity에서 주목할 옵션은 아래입니다.

requiredDuringSchedulingIgnoredDuringExecution 인데요.

막상 보면 길어보이지만 잘라서 보면 이해하기 쉽습니다.

Node-Affinity의 옵션은 크게 가장 앞 부분인 requiredpreferred 조건으로 나누어집니다.

required반드시 이 파드가 해당 노드에 배포가 되어야한다는 점이고 preferred는 가급적이면~ 이라는 옵션입니다.

그리고 꼬리에 해당하는 IgnoredDuringExecution의 경우 런타임에 노드의 Label이 바뀌더라도 무시할 것인지, 즉시 eviction할 것인지에 대한 옵션입니다.

반대 옵션으로는 RequiredDuringExecution가 있습니다.

이를 종합해보면,

  • requiredDuringSchedulingIgnoredDuringExecution

  • preferredDuringSchedulingIgnoredDuringExecution

  • requiredDuringSchedulingRequiredDuringExecution

  • preferredDuringSchedulingRequiredDuringExecution

총 네 개의 조합이 가능해집니다.

Node의 입장에서#

Node-Affinity특정 파드특정 노드로 배포할 것을 설정하는 옵션입니다.

그러나 A Pod가 Node01로의 배포를 반드시 보장해주지만,

Node01에서 B,C 파드가 배포될 것을 보장해주지는 않습니다.

스크린샷 2021-02-17 오전 12 16 33

Node-Affinity VS Node-Selector#

우리는 이전에, Node-Selector를 이용해서도 Node-Affinity와 비슷한 기능을 구현할 수 있는 것을 알고 있습니다.

---
apiVersion: v1
kind: Pod
metadata:
name: A
spec:
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
nodeSelector:
nodeName: node01

얼핏 봐서는 이 옵션이 Node-Affinity 보다 더 명확하고 직관적이라는 생각도 듭니다.

하지만 k8s에서는 이 Node-Selector보다 Node-Affinity를 권장하고 있으며, 추후에 Node-Selector를 Deprecate하고 Node-Affinity만을 사용할 것이라고 밝혔습니다.

그 이유는 Node-Affinity에서는 조금 더 다양한 표현식으로 선택이 가능하며, 제약조건의 주체가 노드에 있는 것이 아닌 파드에 부여함으로써 서로 같이 배치될 수 있는 파드와 아닌 파드를 정의하는게 가능해지기 때문인데요.

Node-Selector에서는 반드시 해당 노드에 배포가 된다는 식의 설정이지만, Node-Affinity의 경우 가급적이면 그렇게 해줘라는 옵션도 설정이 가능하므로 조금 더 유연하게 사용할 수 있다는 장점도 있습니다.

Taints와 Toleration#

그러면 Node-Affinity에 반대되는 옵션인 Taints는 무엇일까요?

Taints의 사전적 의미는 오염, 감염이라는 뜻을 갖고 있는데요.

노드에 Taints를 하면, Toleration을 가진 Pod만 해당 노드에 배포될 수 있게 하는 옵션입니다.

스크린샷 2021-02-17 오전 12 17 43스크린샷 2021-02-17 오전 12 17 48스크린샷 2021-02-17 오전 12 17 53스크린샷 2021-02-17 오전 12 17 57스크린샷 2021-02-17 오전 12 18 04

노드에 Taints를 추가하는 명령어는 다음과 같습니다.

kubectl taints node 노드_이름 key=value:effect

여기서 key와 value는 임의로 줄 수 있으나 effect는 정해진 것을 사용해야합니다.

노드에 추가된 Taints를 제거하는 명령은 다음과 같습니다.

kubectl taints node 노드_이름 key=value:effect-

Taints effect에는 NoSchedule, NoExecute, PreferNoSchedule 세 가지 effect가 존재합니다.

NoSchedule은 일치하는 Toleration이 없으면 해당 노드에 파드를 배치할 수 없음을 의미합니다.

PreferNoSchedule은 toleration이 없으면 포드를 스케쥴링 하지 않으려고 하지만, 이는 필수는 아닙니다. 클러스터 내의 자원이 부족하다면 taint가 있는 노드에도 파드가 스케쥴 될 수 있습니다.

NoExecute의 경우 새롭게 생성된 파드가 toleration이 없으면 배치되지 않게 하고, 기존에 존재하던 파드도 taint에 맞는 toleration이 없다면 즉시 종료시킵니다.

Node01에 다음과 같이 taints를 주고, A Pod에 Toleration을 부여해보겠습니다.

kubectl taints node node01 color=white:NoSchedule

---
apiVersion: v1
kind: Pod
metadata:
name: A
spec:
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
tolerations:
- key: 'color'
operator: 'Equal'
value: 'white'
effect: 'NoSchedule'

참고로 operator의 경우 Equal 외에도 Exists도 사용가능합니다만, 이 경우 value를 따로 명시하지않아야 합니다.

만약 다음과 같이 effectNoExecute인 경우 특정 시간 이후에 노드 내에 있는 Toleration의 파드들을 제거하고 싶다면 다음과 같은 옵션을 줄 수도 있습니다.

---
apiVersion: v1
kind: Pod
metadata:
name: A
spec:
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
tolerations:
- key: 'color'
operator: 'Equal'
value: 'white'
effect: 'NoExecute'
tolerationSeconds: 3600

이렇게 하면 5분 뒤에 노드 내에 Toleration이 없는 파드들은 모두 제거될 것입니다.

Pod의 입장에서#

스크린샷 2021-02-17 오전 12 18 10

그러나 특정 노드의 TaintsToleration을 가진 파드가 반드시 해당 노드에 배포되는 것은 아닙니다.

해당 파드는 얼마든지 다른 노드로도 배포될 수 있습니다.

Node-Affinity + Taints And Toleration#

그렇다면 앞서 배운 Node-AffinityTaints And Toleration를 모두 사용해보겠습니다.

kubectl taints node node01 color=white:NoSchedule

스크린샷 2021-02-17 오전 12 20 15

두 기능을 조합하면 특정 파드가 반드시 특정 노드에 배포되는 것을,

특정 노드는 반드시 특정 파드만 배포되게 허락하는 것을 설정할 수 있습니다.

한 줄 요약#

Node-Affinity + Taints And Toleration를 사용하면 특정 노드와 특정 파드가 서로 반드시 배치하고 배치되어지는 것을 보장할 수 있다!

Last updated on