CKA를 준비해보자 8일차 - Taints and Tolerations

0

CKA

목록 보기
8/43

Taints And Tolerations

taintstolerations는 pod를 어떤 node에 스케줄링한 것인지에 대한 개념이다. taints는 node에 적용하고 tolerations은 pod에 적용하는 field라고 생각하면된다.

------ ------ ------
|pod1| |pod2| |pod3|
------ ------ ------

--Node1-- --Node2-- --Node3--
|       | |       | |       |
--------- --------- ---------

다음과 같이 pod 3개가 있고, node 3개가 있다고 하자. pod들은 각 node에 스케줄링될텐데 스케줄링 알고리즘에 따라 다음과 같이 할당이 가능하다.

--Node1-- --Node2-- --Node3--
|pod1   | | pod2  | | pod3  |
--------- --------- ---------

그런데 만약 Node1은 특정 pod들만 스케줄링되도록 막고싶을 수가 있다. 이럴 때 taints를 사용하는 것이다. Node1taint=blue를 적용시켜보도록 하자. 그렇게되면 pod들은 다음과 같이 스케줄링된다.

(taint=blue)
--Node1--   --Node2-- --Node3--
|       |   | pod1  | | pod3  |
|       |   | pod2  | |       |
---------   --------- ---------

Node1에는 pod들이 스케줄링되지 못하고 다른 곳으로 나가떨어져 스케줄링되는 것이다.

그럼 어떤 pod들이 taint된 Node1에 할당될 수 있을까?? 그것이 바로 tolerations이다. pod3taint=blue에 대해서 tolerations하도록 설정하는 것이다.

              (toleration)
------ ------   ------
|pod1| |pod2|   |pod3|
------ ------   ------

(taint=blue)
--Node1--   --Node2-- --Node3--
|       |   |       | |       |
---------   --------- ---------

이제 다음과 같이 pod3Node1에 스케줄링될 수 있다.

(taint=blue)
----Node1----   --Node2--  --Node3--
|(toleration)|  | pod1  |  | pod2  |
|    pod3    |  |       |  |       |
-------------   ---------  ---------

이처럼 taints를 node에 부여하여 특정 pod만이 해당 node에 스케줄링될 수 있도록 할 수 있으며, toleration을 부여하고 pod를 taint가 적용된 node에 할당할 수 있도록 할 수 있다.

한 가지 오해하지말 것은 taintstolerations는 절대 security에 관한 목적이 아니다. 오직 특정 node에 특정 pod가 스케줄링되게 하기위함인 것이다.

Taints - node

그럼 어떻게 taints를 적용하는가? taintskey-value쌍으로 이루어져 있다. 다음과 같이 taint를 적용시킬 수 있다.

kubectl taint nodes node-name key=value:taint-effect

만약 app=blue라는 taint를 적용시키고 싶다면 key=valueapp=blue로 쓰면 된다. 그럼 taint-effect는 무엇인가??

taint-effect는 pod들이 만약 taint된 node에 대한 toleration이 없을 때 어떻게 동작시킬 것인지 동작을 나타낸다.

여기에는 3가지 taint-effect가 있다.
1. NoSchedule: 해당 pod가 taint node에 스케줄링되지 않는다.
2. PreferNoSchedule: 최대한 taint node에 해당 pod를 배정하지 않으려고 한다. 즉, 우선순위가 낮아지는 것이다.
3. NoExecute: 첫번째인 NoSchedule과 같이 해당 pod가 taint node에 스케줄링되지 않으며, 만약 해당 node에 실행되고 있었지만 taint에 대한 toleration이 없는 pod들은 실행도 멈추어 evicted가 된다.

즉, 이전에 해당 node에서 동작 중이던 pod가 있었는데, nodetaint를 걸어버리고 NoExecute로 설정해주면 해당 pod는 evicted가 된다.

  • NoExecute example
------Node1-------
|pod1(toleration)|
|pod2            |
------------------

다음의 예는 taint가 적용되지 않은 Node1에서 pod1, pod2가 스케줄링된 상황이다. 그런데 pod1은 미래에서 Node1에 부여될 taint에 대한 toleration을 가지고 있는 상태이다.

이제 Node1taint를 부여하되 taint-effectNoExecute로 적용했다고 하자.

  • NoExecute example
     (taint)
------Node1-------
|pod1(toleration)|
|pod2(evicted)   |
------------------

pod1Node1taint에 대한 toleration이 있기 때문에 문제없이 계속 구동되지만, pod2의 경우는 다르다. 만약 taint-effectNoSchedule였다면 pod2도 계속 구동되었겠지만 NoExecute상태이기 때문에 pod2evicted상태로 들어가게 되어 Node1에서 빠져나온다.

그래서 최종 모습은 다음과 같이 된다.

  • NoExecute example
---pod2---
|Pending|
----------


     (taint)
------Node1-------
|pod1(toleration)|
------------------

위의 내용을 토대로 node1app=blue taint를 걸고 NoScheduletaint-effect를 설정하면 다음과 같다.

kubectl taint nodes node1 app=blue:NoSchedule

taints는 재밌게도 기본적으로 적용되어 있는 node가 하나 있는데, 바로 master node이다. master node는 kubernetes control plane를 담당하는 pod들이 스케줄링되지만, worker node들이 관리하는 사용자 pod들도 스케줄링되어 실행될 수 있다.

그러나, 관행상 master node에 일반 사용자 pod들이 배포되지 않도록 taints가 걸려있다. 이는 mastert node에 대한 시스템 부하를 관리하기 위함이다.

kubectl describe node kubemaster | grep Taint
Taints:         node-role.kubernetes.io/master:NoScheduler

만약, 단일 node로 clustet를 구성했다면 master node에서 user pod가 구동되어야 하기 때문에 user pod에 toleration을 추가하든 master node의 taint를 삭제해야한다.

taints가 무조건 key=value형식으로 될 필요는 없다. 위의 master nodetaint처럼 key만 있어도 된다. 위에서는 keynode-role.kubernetes.io/control-plane인 것이다.

삭제할 때는 taint의 마지막에 -만 붙이면 된다.

kubectl taint node kubemaster node-role.kubernetes.io/master:NoScheduler-

untainted되었다는 결과를 받을 수 있을 것이다.

Tolerations - pods

toleration은 pod에 적용시키는 것인데, 기본적으로 yaml파일을 통해 pod에 toleration을 추가할 수 있다.

만약, node1 taint를 뚫는 toleration을 만들어야 한다면 다음과 같다.

  • pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
  - name: nginx-container
    image: nginx
  tolerations:
  - key: "app"
    value: "blue"
    effect: "NoSchedule"
    operator: "Equal"

이는 잘보면 taintnode에 추가할 때의 요소들이 사용된 것을 알 수 있다.

kubectl taint nodes node1 app=blue:NoSchedule

keyapp=blue에서 app이고 valueblue, effectorNoSchedule에 딱 일치하는 것이다. 참고로 operator부분은 생략해도 된다.

여기서 재밌는 것은 toleration을 가지고 있다고 해서 무조건 taint를 가지고 있는 node에 스케줄링되는 것은 아니다. 즉, taintstolerations으로 스케줄링을 직접 설정하는 것이 아니라는 것이다.

가령 다음과 같은 경우가 있다.

              (toleration)
------ ------   ------
|pod1| |pod2|   |pod3|
------ ------   ------

(taint=blue)
--Node1--   --Node2-- --Node3--
|       |   |       | |       |
---------   --------- ---------

pod3Node1에 대한 toleration을 가지고 있지만, 다음과 같이 스케줄링될 수 있다.

(taint=blue)
--Node1---   --Node2--  --Node3--
|        |   | pod1  |  | pod2  |
|        |   | pod3  |  |       |
-----------  ---------  ---------

pod3이 toleration이 있다고 해서 반드시 taint가 있는 Node1에 스케줄링되는 것이 아니라는 것이다.

만약 특정 pod를 특정 node에 스케줄링되도록 제한하고 싶다면, 추후에 나올 node affinity를 사용하면 된다.

Taints and Toleration vs Node Affinity

taints와 toleration은 특정 node에 taint를 걸어 toleration을 가진 pod만이 해당 node에 스케줄링되는 것을 허용한다. 단, 이는 반드시 특정 taint에 대한 toleration을 가진 pod가 해당 node로 스케줄링된다는 것을 의미하는 건 아니다.

반면에 node affinitiy는 특정 pod를 특정 node에 스케줄링되도록 할 수 있다. 단, 이외의 pod들이 해당 node에 스케줄링되는 것을 막을 수는 없다.

따라서, taints와 tolerations, node affinity를 적절히 섞어 사용하는 것이 좋다. 특정 pod를 특정 node에 배정하는 것은 node affinity를 사용하고, 특정 node에 다른 pod들이 배정되지 못하게 하기위해서는 taint를 사용하도록 하는 것이다.

0개의 댓글