티스토리 뷰

카테고리 없음

테인트

미니대왕님 2024. 8. 22. 15:10

파드 스펙의 노드 셀렉터를 통해 특정 노드로 스케줄되는 것을 수행할 수 있지만 k8s는 이를 확장하는 메커니즘을

제공한다.

테인트  톨러레이션 은 특정 노드에서 파드의 실행 여부를 통제하는 데 사용된다.
파드는 노드의 테인트가 허용(tolerate)된 경우에만 노드에 스케줄될 수 있다.

테인트

테인트를 설정한 노드에는 파드들을 스케줄링하지 않는다.

테인트에는 key, value, effect 가 있고, <key>=<value>:<effect> 으로 표시한다.

테인트 effect
어떤 식으로 스케줄링이 동작할지를 정의하는 설정이다.

  • NoSchedule : 노드가 테인트를 허용(tolerate)하지 않는 경우, 파드가 노드에 스케줄되지 않는다.
  • PreferNoSchedule : 노드 스케줄을 피하려고 하지만 다른 곳에서 스케줄할 수 없는 경우, 해당 노드에 스케줄한다.
  • NoExecute : 스케줄링에만 영향을 미치는 NoSchedule과 PreferNoSchedule과 달리, 노드에서 실행 중인 파드에도 영향을 미친다. 해당 노드에서 이미 실행 중인 파드도 NoExecute 테인트를 톨러레이션하지 않는 파드면 노드에서 제거한다.

테인트는 새로운 파드(NoSchedule effect)의 스케줄링을 방지하고,
선호하지 않는 노드(PreferNoSchedule effect)를 정의하며 노드에서 기존 파드를 제거(NoExecute effect) 할 수 있다.

테인트 확인


kubeadm 명령으로 생성한 마스터 노드의 세부 정보 출력 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/16)

마스터 노드에는 하나의 테인트가 있고, node-role.kubernetes.io/master 키, null 값, NoSchedule의 effect를 가진다.

이 파드가 테인트를 허용(tolerate)하지 않으면 파드는 마스터 노드에 스케줄링되지 못한다. 이 테인트를 허용(tolerate)하는 파드는 보통 시스템 파드이다.


노드의 테인트가 허용된 경우에만 파드가 노드에 스케줄된다 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/16)

시스템 파드의 톨러레이션 노드의 테인트가 일치하기 때문에 마스터 노드에 스케줄된다. 톨러레이션이 없는 파드는 테인트가 없는 일반 노드에 스케줄된다.

테인트 추가

# 노드에 테인트 추가
kubectl taint node node1.k8s node-type=production:NoSchedule 

node "node1.k8s" tainted

키는 node-type, 값은 production, effect는 NoSchedule가 있는 테인트가 추가된다.

# 디플로이먼트 배포
kubectl run test --image busybox --replicas 5 -- sleep 9999

deployment "test" created


톨러레이션 없이 파드 배포 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/16)

테인트된 노드에 스케줄된 파드가 없음을 확인할 수 있다.

톨러레이션

톨러레이션은 파드에 적용되며, 테인트된 노드에 파드들을 스케줄링되게 한다.

노드는 하나 이상의 테인트를 가질 수 있고 파드는 하나 이상의 톨러레이션을 가질 수 있다.

톨러레이션 추가

톨러레이션에서 key, value, effect는 원하는 taint의 값을 지정해 주면 된다.

# 톨러레이션 추가 (1)
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: prod
spec:
  replicas: 5
  template:
    spec:
      ...
      tolerations:  # 프로덕션 노드에 파드가 스케줄링 될 수 있도록 톨러레이션 추가
      - key: node-type
        operator: Equal
        value: production
        effect: NoSchedule


톨러레이션 있는 파드가 프로덕션 노드에 배포된다 (출처: github.com/sungsu9022/study-kubernetes-in-action/issues/16)

디플로이먼트를 배포하면 해당 파드가 프로덕션 노드에 배포되는 것을 확인할 수 있다.

# 톨러레이션 추가 (2)
...
tolerations:
- key: node-type
  operator: Exists
  effect: NoSchedule

Equal 연산자를 지정해 특정 값을 허용하거나 Exists 연산자를 사용하는 경우에는 특정 테인트 키의 값을 허용할 수 있다.

  • Equal : key, value가 일치하는 경우에만 파드 스케줄링을 진행한다.
  • Exist : value는 필요없고, key만 일치할 경우 파드 스케줄링을 진행한다.

또한 key, effect 값을 주지 않고 Exists 옵션만 줄 수도 있는데, 이러면 모든 key와 effect에 적용되서 어떤 taint가 걸려있던 상관없이 스케줄링되서 파드가 실행된다. 

tolerations:
- operator: "Exists"

톨러레이션의 지속 시간 설정

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

  • node.kubernetes.io/not-ready : 노드가 준비되지 않았다. 이는 NodeCondition에서 Ready 가 "False"로 됨에 해당한다.
  • node.kubernetes.io/unreachable : 노드가 노드 컨트롤러에서 도달할 수 없다. 이는 NodeCondition에서 Ready 가 "Unknown"로 됨에 해당한다.
  • node.kubernetes.io/network-unavailable : 노드의 네트워크를 사용할 수 없다.
  • node.kubernetes.io/unschedulable : 노드를 스케줄할 수 없다.

이외의 빌트인 테인트 보기

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

이 기능을 tolerationSeconds 와 함께 사용하면, 위와 같은 문제가 있는 노드에서 파드를 얼마나 오래 실행할 수 있는지에 대한 기간을 지정할 수 있다. 예를 들어, 네트워크 장애에서 네트워크가 복구된 후에 파드가 제거되는 것을 피하기 위해 오랫동안 노드에 바인딩된 상태를 유지하려고 할 수 있다.

# 톨러레이션에 tolerationSeconds 지정
tolerations:
- key: "node.kubernetes.io/notReady"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 300
- key: "node.kubernetes.io/unreachable"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 300
# 파드 확인
$ kubectl describe pod kube-proxy-tf7w5 -n kube-system

Name:                 kube-proxy-tf7w5
...
Tolerations:          node.kubernetes.io/notReady:NoExecute op=Exists
                      node.kubernetes.io/unreachable:NoExecute op=Exists
                      ...

위 두가지 톨러레이션은 파드가 300초 동안 준비되지 않았거나 접근할 수 없는 노드도 허용하고 대기할 수 있음을 의미한다.

k8s 컨트롤 플레인은 노드가 준비되지 않았거나 더 이상 접근할 수 없다고 감지하면 300초 동안 기다렸다가 파드를 삭제하고 다른 노드로 다시 스케줄한다.

톨러레이션을 별도로 정의하지 않은 파드는 이 두 톨러레이션이 자동으로 추가된다. 만약 조정하고 싶다면 파드 스펙에 이 두 톨러레이션을 추가해 지연 시간을 짧게 설정할 수 있다.

테인트와 톨러레이션은 주로 노드를 특정 역할만 하도록 만들 때 사용한다. 예를 들어 데이터베이스용 파드를 실행한 후 노드 전체의 CPU나 RAM 자원을 독점해서 사용할 수 있도록 설정할 수 있다. GPU가 있는 노드에는 실제로 GPU를 사용하는 파드들만 실행되도록 설정할 수도 있다.

댓글