장치 테인트와 톨러레이션

장치 테인트와 톨러레이션 (Device Taints and Tolerations)

이 페이지는 DRA의 장치 테인트와 톨러레이션에 대해 설명해요. 이를 통해 드라이버와 관리자가 특정 장치에서 파드를 멀리 두거나, 이미 그 장치를 사용 중인 파드를 축출할 수 있어요.

출처: 문서

본문

장치 테인트와 톨러레이션

이 기능은 쿠버네티스에서 안정(stable) 기능이에요. v1.37부터 그랬으며, 처음에는 v1.33 릴리스에서 제공됐어요. 이 기능이나 동작을 더 이상 비활성화하거나 선택 해제할 수 없어요(잠겨 있음). 관련 기능 게이트인 DRADeviceTaints에 값을 명시적으로 설정하면 쿠버네티스는 이를 무시하지만 오류를 보고하지는 않아요.

장치 테인트는 노드 테인트와 비슷해요. 테인트는 문자열 키, 문자열 값, 그리고 효과(effect)가 있어요. 그 효과는 테인트된 장치를 사용하는 ResourceClaim과 그 ResourceClaim을 참조하는 모든 파드에 적용돼요. "NoSchedule" 효과는 그 파드의 스케줄링을 방지해요. 테인트된 장치는 ResourceClaim을 할당하려 할 때 무시되는데, 그 장치를 사용하면 파드의 스케줄링이 방지되기 때문이에요.

"NoExecute" 효과는 "NoSchedule"을 내포하고, 추가로 이미 스케줄링된 모든 파드의 축출을 유발해요. 이 축출은 kube-controller-manager의 장치 테인트 축출 컨트롤러가 관련 파드를 삭제하면서 구현돼요.

"None" 효과는 스케줄러와 축출 컨트롤러가 무시해요. DRA 드라이버는 관리자나 다른 컨트롤러에게 예외(예: 장치의 상태 저하)를 알리는 데 사용할 수 있어요. 관리자도 DeviceTaintRules에서 파드 축출의 건식 실행(dry-run)에 사용할 수 있어요(아래에서 더 설명).

ResourceClaim은 테인트를 톨러레이션할 수 있어요. 테인트가 톨러레이션되면 그 효과는 적용되지 않아요. 빈 톨러레이션은 모든 테인트에 일치해요. 톨러레이션은 특정 효과로 제한되거나 특정 키/값 쌍과 일치할 수 있어요. 톨러레이션은 특정 키가 값이 무엇이든 존재하는지 확인할 수 있고, 특정 키의 특정 값을 확인할 수도 있어요. 이 일치에 대한 자세한 내용은 노드 테인트 개념을 참고하세요.

특정 기간 동안 테인트를 톨러레이션하면 축출을 지연할 수 있어요. 그 지연은 테인트가 장치에 추가된 시점부터 시작되며, 테인트의 한 필드에 기록돼요.

테인트는 위에 설명한 대로 노드의 "모든" 장치를 할당하는 ResourceClaim에도 적용돼요. 모든 장치가 테인트되지 않았거나 그 테인트가 모두 톨러레이션되어야 해요. 관리자 접근으로 장치를 할당하는 것도 예외가 아니에요. 그 모드를 사용하는 관리자는 테인트된 장치에 접근하려면 모든 테인트를 명시적으로 톨러레이션해야 해요.

DeviceTaintRule API 종류를 사용해 다음 방식으로 장치에 테인트를 추가할 수 있어요.

드라이버가 설정한 테인트

DRA 드라이버는 ResourceSlices에 게시하는 장치 정보에 테인트를 추가할 수 있어요. DRA 드라이버의 문서를 확인해 드라이버가 테인트를 사용하는지, 키와 값이 무엇인지 알아보세요.

관리자가 설정한 테인트

이 기능은 쿠버네티스에서 안정(stable) 기능이에요. v1.37부터 그랬으며, 처음에는 v1.35 릴리스에서 제공됐어요. 이 기능이나 동작을 더 이상 비활성화하거나 선택 해제할 수 없어요(잠겨 있음). 관련 기능 게이트인 DRADeviceTaintRules에 값을 명시적으로 설정하면 쿠버네티스는 이를 무시하지만 오류를 보고하지는 않아요.

관리자나 제어 플레인 구성 요소는 DRA 드라이버에게 ResourceSlices의 장치 정보에 테인트를 포함하라고 알리지 않고도 장치를 테인트할 수 있어요. DeviceTaintRules를 만들어서요. 각 DeviceTaintRule은 장치 셀렉터와 일치하는 장치에 테인트 하나를 추가해요. 그런 셀렉터가 없으면 테인트되는 장치가 없어요. 이렇게 하면 셀렉터를 실수로 빠뜨렸을 때 ResourceClaim을 사용하는 모든 파드를 우발적으로 축출하기가 더 어려워져요.

장치는 DeviceClass, 드라이버, 풀(pool), 및/또는 장치의 이름을 주어 선택할 수 있어요. DeviceClass는 그 DeviceClass의 셀렉터가 선택하는 모든 장치를 선택해요. 드라이버 이름만으로 관리자는 그 드라이버가 관리하는 모든 장치를 테인트할 수 있어요. 예를 들어 그 드라이버를 클러스터 전체에서 어떤 유지보수를 할 때요. 풀 이름을 추가하면 드라이버가 노드 로컬 장치를 관리하는 경우 테인트를 단일 노드로 제한할 수 있어요.

마지막으로 장치 이름을 추가하면 특정 장치 하나를 선택할 수 있어요. 원하면 장치 이름과 풀 이름만 단독으로 사용할 수도 있어요. 예를 들어 노드 로컬 장치용 드라이버는 노드 이름을 자신의 풀 이름으로 사용하도록 권장돼요. 그러면 그 풀 이름으로 테인트하면 자동으로 노드의 모든 장치가 테인트돼요.

드라이버는 "gpu-0" 같은 안정적인 이름을 사용할 수 있는데, 이는 현재 그 이름에 어떤 특정 장치가 할당되어 있는지 숨겨요. 특정 하드웨어 인스턴스를 테인트하는 것을 지원하기 위해, 드라이버가 자기 하드웨어에 대한 공급업체 고유 ID 속성을 지원한다면 DeviceTaintRule에서 CEL 셀렉터를 사용해 그 속성과 일치시킬 수 있어요.

테인트는 DeviceTaintRule이 존재하는 한 적용돼요. 언제든 수정하고 제거할 수 있어요. 가상의 DRA 드라이버에 대한 DeviceTaintRule 예시는 다음과 같아요.

apiVersion: resource.k8s.io/v1
kind: DeviceTaintRule
metadata:
  name: example
spec:
  # 이 특정 드라이버의 전체 하드웨어 설치가
  # 고장났습니다.
  # 모든 파드를 축출하고 새 것은 스케줄링하지 마세요.
  deviceSelector:
    driver: dra.example.com
  taint:
    key: dra.example.com/unhealthy
    value: Broken
    effect: NoExecute

kube-apiserver는 spectimeAdded 필드를 설정해 이 테인트가 생성된 때를 자동으로 추적해요. 톨러레이션 기간은 그 타임스탬프에서 시작돼요. 효과를 변경하는 업데이트 중(아래의 시뮬레이션된 축출 흐름 참고) kube-apiserver는 타임스탬프를 자동으로 업데이트해요. 사용자는 DeviceTaintRule 생성 시 필드를 설정하고 업데이트 시 다른 값으로 변경해 타임스탬프를 명시적으로 제어할 수 있어요.

status에는 축출 컨트롤러가 추가한 조건이 포함돼요.

kubectl describe devicetaintrules
Name:         example
...
Spec:
  Device Selector:
    Driver:  dra.example.com
  Taint:
    Effect:      NoExecute
    Key:         dra.example.com/unhealthy
    Time Added:  2025-11-05T18:15:37Z
    Value:       Broken
Status:
  Conditions:
    Last Transition Time:  2025-11-05T18:15:37Z
    Message:               1 pod evicted since starting the controller.
    Observed Generation:   1
    Reason:                Completed
    Status:                False
    Type:                  EvictionInProgress
Events:                    <none>

파드는 삭제되어 축출돼요. 보통 이것은 아주 빠르게 일어나지만, 테인트에 대한 톨러레이션이 특정 기간 동안 지연시키거나 축출해야 할 파드가 아주 많을 때는 그렇지 않아요. 더 오래 걸릴 때는 메시지가 현재 상태에 대한 정보를 제공해요.

2 pods need to be evicted in 2 different namespaces. 1 pod evicted since starting the controller.

그 조건을 사용해 축출이 현재 진행 중인지 확인할 수 있어요.

kubectl wait --for=condition=EvictionInProgress=false DeviceTaintRule/example

스케줄러와 컨트롤러가 새 테인트를 서로 다른 시점에 관찰하는 잠재적 경쟁(race)에 주의하세요. 이는 컨트롤러가 축출할 파드가 없다고 생각할 때 파드가 여전히 스케줄링될 수 있어 조건을 False로 설정하게 만들 수 있어요. 실제로는 이 경쟁은 의도적인 몇 초 지연 후에만 status를 업데이트함으로써 발생 가능성을 매우 낮춰요.

effect: None의 경우 메시지는 영향을 받는 장치 수, 그중 얼마나 할당되어 있는지, 그리고 효과가 NoExecute였다면 얼마나 많은 파드가 축출될 것인지에 대한 정보를 제공해요. 이는 실제로 축출을 촉발하기 전에 건식 실행을 하는 데 사용할 수 있어요.

  • 원하는 셀렉터와 effect: None으로 DeviceTaintRule을 만들어요.
  • 메시지를 검토하세요:
3 published devices selected. 1 allocated device selected.
1 pod would be evicted in 1 namespace if the effect was NoExecute.
This information will not be updated again. Recreate the DeviceTaintRule to trigger an update.

Published 장치는 ResourceSlices에 나열된 장치예요. 이들을 테인트하면 새 파드를 위한 할당을 방지해요. 할당된 장치만 그 장치를 사용하는 파드의 축출을 일으켜요.

  • DeviceTaintRule을 편집하고 효과를 NoExecute로 변경하세요.

더 알아보기 (Learn more)