Kubernetes

Kubernetes 기초 - Scheduling(5)

사실 나도 모름 2024. 1. 9. 00:34
  1. NodeSelector
  2. Affinity and Anti-affinity
  3. Pod Overhead
  4. 파드 스케줄링 준비성(Readiness)
  5. 파드 토폴로지 분배 제약 조건
  6. Taints and Tolerations             ←  오늘 볼 내용
  7. cordon and drain

6. Taints and Tolerations

https://kubernetes.io/ko/docs/concepts/scheduling-eviction/taint-and-toleration/

 

테인트(Taints)와 톨러레이션(Tolerations)

노드 어피니티는 노드 셋을 (기본 설정 또는 어려운 요구 사항으로) 끌어들이는 파드의 속성이다. 테인트 는 그 반대로, 노드가 파드 셋을 제외시킬 수 있다. 톨러레이션 은 파드에 적용된다. 톨

kubernetes.io

 

1. 테인트(Taints)

 

이전에 본 어피니티에 대한 내용은 파드가 생성될 때 어디에 스케줄할 것인지 결정하는 방법이었다.

어피니티는 파드 템플릿에 설정함으로 파드가 어느 노드를 선택할지 결정하는 방법이라면 테인트는 노드에 설정하여 노드가 파드를 스케줄되지 못하게 밀어내는 역할을 한다.

 

테인트의 이펙트는 다음과 같다.

테인트 이펙트 설명
NoSchedule 레이블 조건에 만족하는 톨러레이션이 없으면 파드를 스케줄하지 않는다.
PreferNoSchedule NoSchedule의 소프트 버전.
파드를 스케줄하지 않지만 보장되지는 않는다.
NoExecute 해당 노드에 실행중인 파드 중에서 조건에 만족하는 파드가 있으면 축출하고 이후에 생성된 파드도 스케줄링하지 않는다.

 

 

노드에 테인트 규칙을 적용하는 방법은 다음과 같다.

kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node2 key2=value2:PreferNoSchedule
kubectl taint nodes node3 key3=value3:NoExecute

 

 

테인트 규칙을 해제하는 방법은 다음과 같다.

kubectl taint nodes node1 key1=value1:NoSchedule-
kubectl taint nodes node2 key2=value2:PreferNoSchedule-
kubectl taint nodes node3 key3=value3:NoExecute-

 

 

이전에 레이블을 추가하고 해제하는 방법과 동일하게 '-' 만 붙이면 해제된다.

 

중요한 것은 테인트 설정 시 사용되는 키-값 쌍은 스케줄될 수 있는 파드의 레이블을 의미하는 것이 아니라 테인트를 구별하는 식별자같은 역할을 한다는 점이다.

파드가 해당 노드에 스케줄되도록 하려면 동일한 키-값 쌍 정보를 입력하여 파드에 톨러레이션 설정을 명시해야 한다.

마치 테인트는 자물쇠, 톨러레이션은 열쇠같은 역할이다.

열쇠가 없으면 자물쇠를 열 수 없듯이 열쇠없는 파드는 아무리 해당 노드에 스케줄하려 해도 할 수 없다.

 

 

 

 

2. 톨러레이션(Tolerations)

톨러레이션은 테인트가 적용된 노드라도 파드를 스케줄할 수 있는 설정이다.

톨러레이션은 파드 템플릿에 적용하여 테인트의 조건과 맞으면 무시하고 스케줄 될 수 있다.

 

톨러레이션 필드에서 오퍼레이터와 이펙트를 설정할 수 있다.

다음 표를 보자.

operator 설명 effect 설명
Equal 테인트의 키-값 쌍과 일치하면 용인 NoSchedule NoSchedule 설정을 무시한다.
Exists 테인트의 키만 일치하면 용인 NoExecute NoExecute 설정을 무시한다.

 

 

파드 템플릿에 톨러레이션을 적용하는 방법은 다음과 같다.

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"

 

 

만약 NoExecute의 경우는 톨러레이션 규칙이 적용된 파드가 실행 중이더라도 규칙과 일치하지 않는 테인트가 노드에 추가되면 실행중인 파드는 바로 축출된다.

하지만 톨러레이션과 일치하는 테인트라면 당연히 축출되지 않는다.

 

선택적으로 톨러레이션의 규칙과 일치한 테인트가 노드에 추가되는 경우 일정시간 바인드 후 축출되도록 설정할 수 있다.

tolerationSeconds는 지정한 시간만큼 바인딩되었다가 축출되기 때문에 이펙트가 NoExecute인 경우만 사용할 수 있다.

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600

 

 

이것은 이 파드가 실행 중이고 일치하는 테인트가 노드에 추가되면, 파드는 3600초 동안 노드에 바인딩된 후, 축출된다는 것을 의미한다.

그 전에 테인트를 제거하면, 파드가 축출되지 않는다.

 

 

 

 

 

실습

node1에 app=web이라는 키-값 쌍으로 테인트를 적용한다.

그 전에 파드를 하나 생성하여 테인트의 이펙트에 따라 결과가 어떻게 달라지는지 확인해보자.

# taints-tolerations-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers: 
  - name: nginx-container
    image: nginx:1.25
  nodeName: node1    # 명시적 노드 선택(자신의 노드 이름을 명시)

명시적으로  node1에 스케줄

 

kubectl taint nodes node1 app=web:NoSchedule

테인트를 적용해도 기존 파드는 여전히 실행 중

 

 

 

 

NoSchedule 이펙트는 기존의 파드에 영향을 주지는 않는다.

하지만 이펙트가 NoExecute인 테인트를 적용하면 기존의 파드조차 축출되어 버린다.

먼저 파드가 축출되는 장면을 눈으로 직접 확인하기 위해서 동일한 터미널을 하나 더 실행해서 다음 명령을 입력한다.

kubectl get pods -o wide --watch

 

 

이번에는 NoExecute 규칙을 적용한다.

kubectl taint node node1 app=web:NoExecute

실행되던 파드가 축출됨

 

 

파드가 축출되어 종료되었다.

이제는 node1에 파드를 스케줄하려고 해도 절대 스케줄되지 않는다.

Pending상태에서 바로 종료

 

 

이와 같이 테인트 설정으로 인해 파드는 더 이상 node1에는 스케줄되지 않는다(NoSchedule이나 NoExecute나 동일).

생성한 파드를 제거하고 yaml파일을 수정하여 톨러레이션 규칙을 추가한 후 다시 실행한다.

# taints-toleraions-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:1.25
  nodeName: node1
  tolerations:
  - key: app
    operator: Equal
    value: web
    effect: NoExecute
  - key: app
    operator: Equal
    value: web
    effect: NoSchedule

테인트 설정이 있더라도 무시하고 스케줄됨

 

 

이번에는 일정시간이 지나면 자동으로 축출되는 실습을 해보자.

생성한 파드를 제거하고 yaml파일을 한번 더 수정한 후 다시 실행한다.

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:1.25
  nodeName: node1
  tolerations:
  - key: app
    operator: Equal
    value: web
    effect: NoExecute
    tolerationSeconds: 10
  - key: app
    operator: Equal
    value: web
    effect: NoSchedule

10초 후 종료

 

 

위 yaml파일로 실행한 파드는 tolerationSeconds로 인해 10초 동안만 유지되다가 종료된다.

이와 같이 노드에 테인트를 설정하고 파드에 톨러레이션을 설정하여 스케줄되는 위치를 좀 더 엄격하게 지정할 수 있다.

 

 


테인트 기반 축출

노드 컨트롤러는 특정 컨디션이 참일 때 자동으로 노드를 테인트시킨다.

다음은 빌트인 테인트이다.

built-in taints 설명
node.kubernetes.io/not-ready 노드가 준비되지 않았다.
이는 NodeCondition Ready 가 "False"로 됨에 해당한다.
node.kubernetes.io/unreachable 노드가 노드 컨트롤러에서 도달할 수 없다.
이는 NodeCondition Ready 가 "Unknown"로 됨에 해당한다.
node.kubernetes.io/memory-pressure 노드의 가용 메모리가 부족하다.
memory-pressure 이 False인 상태다.
node.kubernetes.io/disk-pressure 노드의 가용 디스크 공간이 부족하다.
disk-pressure 이 False인 상태다.
node.kubernetes.io/pid-pressure 노드에서 사용 가능한 PID 리소스가 부족하다.
pid-pressure이 False인 상태다.
node.kubernetes.io/network-unavailable 노드의 네트워크를 사용할 수 없다.
network-unavailable 이 False인 상태다.
node.kubernetes.io/unschedulable 노드를 스케줄할 수 없다.
node.cloudprovider.kubernetes.io/uninitialized "외부" 클라우드 공급자로 kubelet을 시작하면, 이 테인트가 노드에서 사용 불가능으로 표시되도록 설정된다.
클라우드-컨트롤러-관리자의 컨트롤러가 이 노드를 초기화하면, kubelet이 이 테인트를 제거한다.


노드가 축출될 경우, 노드 컨트롤러 또는 kubelet은 NoExecute 이펙트로 관련 테인트를 추가한다.

장애 상태가 정상으로 돌아오면 kubelet 또는 노드 컨트롤러가 관련 테인트를 제거할 수 있다.

 

노드의 상세 내역을 보면 위 표와 같은 컨디션 정보가 나온다.

kubectl describe node <노드 이름>

 

큰 문제가 없다면 모두 이와 같은 상태일 것이다.

 

참고1 :
쿠버네티스는 사용자나 컨트롤러에서 명시적으로 설정하지 않았다면, 자동으로 node.kubernetes.io/not-ready 와 node.kubernetes.io/unreachable 에 대해 tolerationSeconds=300 으로 톨러레이션을 추가한다.
자동으로 추가된 이 톨러레이션은 이러한 문제 중 하나가 감지된 후 5분 동안 파드가 노드에 바인딩된 상태를 유지함을 의미한다.
기본 설정
참고2 :
데몬셋의 경우는 노드마다 반드시 하나의 파드가 스케줄되어야 하기 때문에 기본 톨러레이션 설정이 조금 특이하다.
노드의 Ready 상태에 대한 컨디션에 대해서는 NoExecute로 파드의 스케줄과 축출되지 않는 내성을 가지고 있지만 그 이외의 컨디션 문제에서는 NoSchedule로 스케줄에 대한 내성을 가지고 있다.
데몬셋 기본 설정

 

 

 

위 컨디션 정보를 바탕으로 테인트 혹은 톨러레이션을 설정할 때 노드의 상태를 기반으로 파드를 스케줄하거나 축출하는 다양한 케이스를 구성할 수 있다.

'Kubernetes' 카테고리의 다른 글

Kubernetes 기초 - Storage(1)  (0) 2024.01.12
Kubernetes 기초 - Scheduling(6)  (0) 2024.01.10
Kubenets 기초 - Scheduling(4)  (0) 2024.01.06
Kubernetes 기초 - Scheduling(3)  (0) 2024.01.05
Kubernetes 기초 - Scheduling(2)  (0) 2024.01.04