DRA API

DRA API (DRA API Kinds)

이 페이지는 동적 리소스 할당(DRA)이 장치를 분류하고, 요청하고, 할당하는 데 사용하는 쿠버네티스 API 종류를 설명해요.

출처: 문서

본문

DRA 용어 {#terminology}

DRA는 핵심 할당 기능을 제공하기 위해 다음 쿠버네티스 API 종류를 사용합니다. 이 API 종류들은 모두 resource.k8s.io/v1 API 그룹에 포함됩니다.

DeviceClass : 요청할 수 있는 장치 범주와 요청에서 특정 장치 속성을 선택하는 방법을 정의한다. DeviceClass 파라미터는 ResourceSlice의 장치 0개 이상과 일치할 수 있다. DeviceClass에서 장치를 요청하려면 ResourceClaim이 특정 장치 속성을 선택한다.

ResourceClaim : 클러스터의 장치 같은 연결된 리소스에 대한 접근 요청을 설명한다. ResourceClaim은 파드에 특정 리소스에 대한 접근을 제공한다. ResourceClaim은 워크로드 운영자가 만들거나 ResourceClaimTemplate을 기반으로 쿠버네티스가 생성할 수 있다.

ResourceClaimTemplate : 쿠버네티스가 워크로드에 대해 파드별 ResourceClaim을 만드는 데 사용하는 템플릿을 정의한다. ResourceClaimTemplate은 파드에 별도의 유사한 리소스에 대한 접근을 제공한다. 템플릿에서 쿠버네티스가 생성하는 각 ResourceClaim은 특정 파드에 바인딩된다. 파드가 종료되면 쿠버네티스가 해당 ResourceClaim을 삭제한다.

ResourceSlice : 장치 같은 노드에 연결된 하나 이상의 리소스를 나타낸다. 드라이버는 클러스터에서 ResourceSlice를 만들고 관리한다. ResourceClaim이 만들어져 파드에서 사용되면, 쿠버네티스는 ResourceSlice를 사용해 요청된 리소스에 접근할 수 있는 노드를 찾는다. 쿠버네티스는 리소스를 ResourceClaim에 할당하고 리소스에 접근할 수 있는 노드에 파드를 스케줄링한다.

DeviceClass {#deviceclass}

DeviceClass는 클러스터 관리자나 장치 드라이버가 클러스터의 장치 범주를 정의하게 해줍니다. DeviceClass는 운영자에게 어떤 장치를 요청할 수 있고 어떻게 요청할 수 있는지 알려줍니다. 공통 표현 언어(CEL)를 사용해 특정 속성에 기반해 장치를 선택할 수 있습니다. DeviceClass를 참조하는 ResourceClaim은 그런 다음 DeviceClass 안의 특정 구성을 요청할 수 있습니다.

DeviceClass를 만들려면 클러스터에서 DRA 설정을 참조하세요.

ResourceClaim과 ResourceClaimTemplate {#resourceclaims-templates}

ResourceClaim은 워크로드가 필요로 하는 리소스를 정의합니다. 모든 ResourceClaim은 DeviceClass를 참조하고 그 DeviceClass에서 장치를 선택하는 요청(requests) 을 가집니다. ResourceClaim은 특정 요구 사항을 충족하는 장치를 필터링하기 위한 선택자(selectors) 를 사용할 수 있고, 요청을 충족할 수 있는 장치를 제한하기 위한 제약(constraints) 을 사용할 수 있습니다. ResourceClaim은 워크로드 운영자가 만들거나 ResourceClaimTemplate을 기반으로 쿠버네티스가 생성할 수 있습니다. ResourceClaimTemplate은 쿠버네티스가 파드용 ResourceClaim을 자동 생성하는 데 사용할 수 있는 템플릿을 정의합니다.

ResourceClaim과 ResourceClaimTemplate의 사용 사례 {#when-to-use-rc-rct}

사용하는 방법은 다음과 같이 요구 사항에 따라 다릅니다:

  • ResourceClaim: 여러 파드가 특정 장치에 대한 접근을 공유하길 원한다. 만든 ResourceClaim의 수명을 수동으로 관리한다.
  • ResourceClaimTemplate: 파드가 별도의 유사하게 구성된 장치에 독립적으로 접근하길 원한다. 쿠버네티스는 ResourceClaimTemplate의 명세에서 ResourceClaim을 생성한다. 각 생성된 ResourceClaim의 수명은 해당 파드의 수명에 묶인다.
  • PodGroup ResourceClaimTemplate: 파드가 공유할 수 있는 별도의 유사하게 구성된 장치에 독립적으로 접근하길 원한다. 쿠버네티스는 ResourceClaimTemplate의 명세에서 PodGroup용 ResourceClaim 하나를 생성한다. 각 생성된 ResourceClaim의 수명은 해당 PodGroup의 수명에 묶인다. 이를 위해서는 DRAWorkloadResourceClaims 기능을 활성화해야 한다.

워크로드를 정의할 때 [CEL 표현식]을 사용해 특정 장치 속성이나 용량으로 필터링할 수 있습니다. 필터링에 사용 가능한 파라미터는 장치와 드라이버에 따라 다릅니다.

파드에서 특정 ResourceClaim을 직접 참조하면 그 ResourceClaim이 파드와 같은 네임스페이스에 이미 존재해야 합니다. ResourceClaim이 네임스페이스에 없으면 파드는 스케줄링되지 않습니다. 이 동작은 PersistentVolumeClaim이 그것을 참조하는 파드와 같은 네임스페이스에 존재해야 하는 방식과 유사합니다.

자동 생성된 ResourceClaim을 파드에서 참조할 수 있지만, 자동 생성된 ResourceClaim은 생성을 트리거한 파드나 PodGroup의 수명에 묶이므로 권장되지 않습니다.

이 방법 중 하나로 리소스를 요청하는 방법을 배우려면 DRA로 워크로드에 장치 할당하기를 참조하세요.

우선순위 목록 {#prioritized-list}

ResourceClaim 또는 ResourceClaimTemplate의 요청에 대해 하위 요청(subrequests)의 우선순위 목록을 제공할 수 있어요. 그러면 스케줄러가 할당될 수 있는 첫 번째 하위 요청을 선택합니다. 이를 통해 사용자는 주 선택이 불가능할 때 워크로드가 사용할 수 있는 대체 장치를 지정할 수 있습니다.

아래 예시에서 ResourceClaimTemplate은 색이 검은색이고 크기가 큰 장치를 요청했습니다. 그 속성의 장치를 사용할 수 없으면 파드는 스케줄링될 수 없습니다. 우선순위 목록 기능으로 두 번째 대안을 지정할 수 있는데, 이는 색이 흰색이고 크기가 작은 장치 두 개를 요청합니다. 큰 검은색 장치를 사용할 수 있으면 그것이 할당됩니다. 없다면 작은 흰색 장치 두 개가 사용 가능할 때 파드가 여전히 실행될 수 있습니다.

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: prioritized-list-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        firstAvailable:
        - name: large-black
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "black" &&
                device.attributes["resource-driver.example.com"].size == "large"
        - name: small-white
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "white" &&
                device.attributes["resource-driver.example.com"].size == "small"
          count: 2

파드가 클러스터의 여러 노드에 자격이 있다면, 스케줄러는 각 노드를 점수 매길 때 어떤 우선순위 목록에서든 선택된 하위 요청의 인덱스를 입력 중 하나로 사용합니다. 그래서 더 높은 순위의 하위 요청에서 요청된 장치를 할당할 수 있는 노드가, 더 낮은 순위의 하위 요청에만 장치를 할당할 수 있는 노드보다 선택될 가능성이 더 높습니다.

결정은 파드별로 이루어지므로, 파드가 ReplicaSet이나 유사한 그룹의 구성원이라면 그룹의 모든 구성원이 같은 하위 요청을 선택할 것이라고 기대할 수 없습니다. 워크로드는 이를 수용할 수 있어야 합니다.

워크로드 ResourceClaim {#workload-resource-claims}

Workload API로 파드를 구성할 때, 개별 파드 대신 전체 PodGroup에 대해 ResourceClaim을 예약하고 단일 파드 대신 PodGroup에 대한 ResourceClaimTemplate을 생성할 수 있어, PodGroup 안의 파드들이 생성된 ResourceClaim에 할당된 장치에 대한 접근을 공유할 수 있게 합니다.

이 기능은 두 가지 문제를 대상으로 합니다:

  • ResourceClaim API의 status.reservedFor 목록은 256개 항목만 담을 수 있습니다. kube-scheduler는 그 목록에 개별 파드만 기록하므로, 256개의 파드만 ResourceClaim을 공유할 수 있습니다. PodGroup이 status.reservedFor에 기록되도록 허용하면 256개보다 훨씬 많은 파드가 ResourceClaim을 공유할 수 있습니다.
  • 파드는 정확한 이름을 알 때만 ResourceClaim을 공유할 수 있습니다. 파드 그룹 을 복제하는 복잡한 워크로드의 경우, 각 그룹의 파드가 공유하는 ResourceClaim은 그룹 집합이 스케일 업/다운될 때 명시적으로 만들어지고 삭제되어야 합니다. 각 PodGroup에 대해 ResourceClaim을 생성함으로써, 단일 ResourceClaimTemplate이 자동으로 복제되고 PodGroup 안의 파드들 사이에서 공유될 수 있는 ResourceClaim들의 기초가 될 수 있습니다.

PodGroup API는 Pod API의 spec.resourceClaims 필드와 같은 구조와 비슷한 의미를 가진 spec.resourceClaims 필드를 정의합니다:

apiVersion: scheduling.k8s.io/v1beta1
kind: PodGroup
metadata:
  name: training-group
  namespace: some-ns
spec:
  ...
  resourceClaims:
  - name: pg-claim
    resourceClaimName: my-pg-claim
  - name: pg-claim-template
    resourceClaimTemplateName: my-pg-template

파드가 하는 요청처럼, resourceClaimName을 정의하는 PodGroup용 요청은 이름으로 ResourceClaim을 참조합니다. resourceClaimTemplateName을 정의하는 요청은 전체 PodGroup에 대해 하나의 ResourceClaim으로 복제되고 그 파드들 사이에 공유될 수 있는 ResourceClaimTemplate을 참조합니다.

파드가 name, resourceClaimName, resourceClaimTemplateName이 모두 그것이 속한 PodGroup의 spec.resourceClaims 중 하나와 일치하는 요청을 정의하면, kube-scheduler는 파드 대신 PodGroup에 대해 ResourceClaim을 예약합니다. 파드의 요청이 그것이 속한 PodGroup이 하는 요청과 일치하지 않으면, kube-scheduler는 파드에 대해 ResourceClaim을 예약합니다. 어느 경우든 예약은 ResourceClaim의 status.reservedFor에 기록됩니다. PodGroup 예약과 해당 리소스 할당은 PodGroup이 삭제될 때까지 ResourceClaim에 유지됩니다. 그룹에 더 이상 파드가 없어도 마찬가지입니다.

PodGroup이 하는 요청과 일치하는 resourceClaimTemplateName을 정의하는 파드 요청이 있으면, PodGroup에 대해 ResourceClaim 하나가 생성됩니다. 같은 요청을 정의하는 그룹의 다른 파드들은 각 파드에 대해 새 ResourceClaim이 생성되도록 촉구하는 대신 그 생성된 ResourceClaim을 공유합니다. resourceClaimTemplateName 요청이 PodGroup 요청과 일치하는지 여부와 관계없이, 생성된 ResourceClaim의 이름은 파드의 status.resourceClaimStatuses에 기록됩니다.

ResourceClaimTemplate에 대한 일치하는 PodGroup 요청은 DRAWorkloadResourceClaims 기능이 활성화되었을 때만 ResourceClaim 생성을 촉구합니다. 기능이 비활성화되면 파드별 ResourceClaim을 만드는 대신, kube-apiserverkube-controller-manager 사이의 클러스터 업그레이드나 기능 롤아웃/롤백 중에 잘못된 파드별 ResourceClaim이 생성되는 것을 방지하기 위해 어떤 ResourceClaim도 만들지 않습니다.

PodGroup용 ResourceClaimTemplate에서 생성된 ResourceClaim은 PodGroup의 수명을 따릅니다. ResourceClaim은 PodGroup과 그 ResourceClaimTemplate이 모두 존재할 때 처음 생성됩니다. ResourceClaim은 PodGroup이 삭제되고 더 이상 예약되지 않은 후 삭제됩니다.

다음 예시를 고려해 보세요:

apiVersion: scheduling.k8s.io/v1beta1
kind: PodGroup
metadata:
  name: training-group
  namespace: some-ns
spec:
  ...
  resourceClaims:
  - name: pg-claim
    resourceClaimName: my-pg-claim
  - name: pg-claim-template
    resourceClaimTemplateName: my-pg-template
---
apiVersion: v1
kind: Pod
metadata:
  name: training-group-pod-1
  namespace: some-ns
spec:
  ...
  schedulingGroup:
    podGroupName: training-group
  resourceClaims:
  - name: pod-claim
    resourceClaimName: my-pod-claim
  - name: pod-claim-template
    resourceClaimTemplateName: my-pod-template
  - name: pg-claim
    resourceClaimName: my-pg-claim
  - name: pg-claim-template
    resourceClaimTemplateName: my-pg-template

이 예시에서 training-group PodGroup에는 training-group-pod-1이라는 파드 하나가 있습니다. 파드의 pod-claimpod-claim-template 요청은 PodGroup이 하는 어떤 요청과도 일치하지 않으므로, 그 요청들은 PodGroup의 영향을 받지 않습니다: ResourceClaim my-pod-claim은 파드에 대해 예약되고, ResourceClaimTemplate my-pod-template에서 ResourceClaim이 생성되어 역시 파드에 대해 예약됩니다. pg-claimpg-claim-template은 PodGroup이 하는 요청과 일치합니다. ResourceClaim my-pg-claim은 PodGroup에 대해 예약되고, ResourceClaimTemplate my-pg-template에서 ResourceClaim이 생성되어 역시 PodGroup에 대해 예약됩니다.

ResourceClaim을 Workload API 리소스와 연결하는 것은 kube-apiserver, kube-controller-manager, kube-scheduler, kubeletDRAWorkloadResourceClaims 기능 게이트에 의해 제어됩니다.

ResourceSlice {#resourceslice}

각 ResourceSlice는 풀(pool)에 있는 하나 이상의 리소스를 나타냅니다. 풀은 ResourceSlice를 만들고 관리하는 장치 드라이버가 관리합니다. 풀의 리소스는 단일 ResourceSlice로 표현되거나 여러 ResourceSlice에 걸쳐 있을 수 있습니다.

ResourceSlice는 장치 사용자와 스케줄러에게 유용한 정보를 제공하며 동적 리소스 할당에 중요합니다. 모든 ResourceSlice는 다음 정보를 포함해야 합니다:

  • 리소스 풀(Resource pool): 드라이버가 관리하는 하나 이상의 리소스 그룹. 풀은 둘 이상의 ResourceSlice에 걸칠 수 있다. 풀의 리소스 변경은 그 풀의 모든 ResourceSlice에 걸쳐 전파되어야 한다. 풀을 관리하는 장치 드라이버가 이 전파가 일어나도록 보장할 책임이 있다.
  • 장치(Devices): 관리되는 풀의 장치. ResourceSlice는 풀의 모든 장치 또는 일부 장치를 나열할 수 있다. ResourceSlice는 속성, 버전, 용량 같은 장치 정보를 정의한다. 장치 사용자는 ResourceClaim이나 DeviceClass에서 장치 정보를 필터링해 장치를 할당용으로 선택할 수 있다.
  • 노드(Nodes): 리소스에 접근할 수 있는 노드. 드라이버는 어떤 노드가 리소스에 접근할 수 있는지 선택할 수 있다 — 클러스터의 모든 노드, 단일 명명된 노드, 또는 특정 노드 라벨이 있는 노드.

드라이버는 컨트롤러를 사용해 클러스터의 ResourceSlice를 드라이버가 게시해야 하는 정보와 조정합니다. 이 컨트롤러는 클러스터 사용자가 ResourceSlice를 만들거나 수정하는 것 같은 수동 변경을 덮어씁니다.

다음 예시 ResourceSlice를 고려해 보세요:

apiVersion: resource.k8s.io/v1
kind: ResourceSlice
metadata:
  name: cat-slice
spec:
  driver: "resource-driver.example.com"
  pool:
    generation: 1
    name: "black-cat-pool"
    resourceSliceCount: 1
  # The allNodes field defines whether any node in the cluster can access the device.
  allNodes: true
  devices:
  - name: "large-black-cat"
    attributes:
      color:
        string: "black"
      size:
        string: "large"
      cat:
        bool: true

이 ResourceSlice는 black-cat-pool 풀의 resource-driver.example.com 드라이버가 관리합니다. allNodes: true 필드는 클러스터의 어떤 노드든 장치에 접근할 수 있음을 나타냅니다. ResourceSlice에는 large-black-cat이라는 장치가 하나 있으며 다음 속성을 가집니다:

  • color: black
  • size: large
  • cat: true

DeviceClass는 이 속성들을 사용해 이 ResourceSlice를 선택할 수 있고, ResourceClaim은 그 DeviceClass에서 특정 장치를 필터링할 수 있습니다.

명명과 우선순위 {#resourceslice-naming-and-prioritization}

쿠버네티스 스케줄러가 할당을 위해 장치를 평가하는 순서는 ResourceSlice와 리소스 풀 이름의 사전순 정렬에 의해 결정됩니다. 스케줄러는 요청의 요구 사항을 충족하는 첫 번째 사용 가능한 장치를 선택하는 first-fit 전략을 사용합니다.

이를 통해 리소스 할당의 우선순위를 풀과 ResourceSlice에 할당된 이름으로 영향을 줄 수 있습니다. 바인딩 조건이 없는 풀은 이름과 무관하게 항상 바인딩 조건이 있는 풀보다 먼저 평가된다는 점에 주의하세요.

k8s.io/dynamic-resources/kubeletplugin Go 패키지 또는 해당 모듈의 ResourceSlice 컨트롤러로 구축된 드라이버의 경우, 이 구성 요소들이 드라이버가 지정한 순서로 평가되도록 ResourceSlice 명명을 자동으로 처리합니다.

관리자 접근 {#admin-access}

ResourceClaim 또는 ResourceClaimTemplate의 요청을 유지보수·문제 해결 작업을 위한 특권 기능으로 표시할 수 있어요. 관리자 접근이 있는 요청은 사용 중인 장치에 대한 접근을 부여하고, 장치를 컨테이너에서 사용 가능하게 만들 때 추가 권한을 활성화할 수 있습니다:

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: large-black-cat-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        exactly:
          deviceClassName: resource.example.com
          allocationMode: All
          adminAccess: true

관리자 접근은 특권 모드이며 멀티테넌트 클러스터의 일반 사용자에게 부여되어서는 안 됩니다. resource.kubernetes.io/admin-access: "true"(대소문자 구분)로 라벨이 지정된 네임스페이스에서 ResourceClaim 또는 ResourceClaimTemplate 객체를 만들 권한이 있는 사용자만 adminAccess 필드를 사용할 수 있습니다. 이는 비관리자 사용자가 기능을 남용할 수 없도록 보장합니다.

관리자 접근은 kube-apiserver, kube-scheduler, kubeletDRAAdminAccess 기능 게이트에 의해 제어됩니다.

목록 유형 속성 {#list-type-attributes}

이 기능은 ResourceSlice API를 개선해 DRA 드라이버가 스칼라만이 아니라 장치 속성에 대해 목록 값을 지정할 수 있게 해줍니다. 이는 더 복잡한 내부 노드 토폴로지를 모델링할 때 유용합니다. 예를 들어 CPU가 여러 PCIe 루트에 인접해 있을 때 그렇습니다.

ResourceClaim 작성자(최종 사용자)에게 이는 matchAttributedistinctAttribute가 이런 경우에 더 잘 동작함을 의미합니다.

  • matchAttribute — 두 속성은 동일할 필요 없이 비어 있지 않은 목록 교집합을 가져야 합니다(스칼라 값은 단일 항목 목록으로 취급됨). 이는 한 드라이버가 예를 들어 PCIe 루트에 대해 단일 값을 게시하고 다른 드라이버가 목록을 게시하면, 단일 값이 목록 어딘가에 나타나기만 하면 제약이 충족됨을 의미합니다.
  • distinctAttribute — 속성 값은 쌍별로 분리(어떤 두 장치 간에도 값이 공유되지 않음)되어야 합니다.

ResourceClaim 작성자가 CEL 표현식 내부에서 목록일 수 있는 속성을 사용하도록 돕기 위해 이 기능은 includes() CEL 함수도 도입합니다.

# Scalar attribute (backward compatible)
# assume: device.attributes["dra.example.com"].model = "model-a"
device.attributes["dra.example.com"].model.includes("model-a")  # true
device.attributes["dra.example.com"].model.includes("model-b")  # false

# List-type attribute (requires DRAListTypeAttributes)
# assume: device.attributes["dra.example.com"].supported-models= ["model-a", "model-b"]
device.attributes["dra.example.com"].supported-models.includes("model-a")  # true
device.attributes["dra.example.com"].supported-models.includes("model-c")  # false

DRA 드라이버 작성자를 위한 세부 사항

기본적으로 각 DeviceAttribute는 정확히 하나의 스칼라 값(boolean, 정수, 문자열 또는 시맨틱 버전 문자열)을 보유합니다. DRAListTypeAttributes 기능 게이트는 DeviceAttribute를 네 개의 목록 유형 필드로 확장해, 장치가 단일 속성에 대해 여러 값을 광고할 수 있게 합니다:

  • bools — boolean 값 목록
  • ints — 64비트 정수 값 목록
  • strings — 문자열 목록(각각 최대 64자)
  • versions — semver.org 스펙 2.0.0에 따른 시맨틱 버전 문자열 목록(각각 최대 64자)

장치당 개별 속성 값의 총 개수(스칼라 필드 + 모든 목록 요소 합산)는 48으로 제한됩니다. ResourceSlice의 어떤 장치가 이 기능이나 테인트 같은 다른 고급 기능을 사용하면, 그 ResourceSlice는 최대 64개의 장치로 제한됩니다.

목록 유형 문자열 속성을 사용해 여러 지원 모델을 광고하는 장치의 예시입니다:

kind: ResourceSlice
apiVersion: resource.k8s.io/v1
metadata:
  name: example-resourceslice
spec:
  nodeName: worker-1
  pool:
    name: pool
    generation: 1
    resourceSliceCount: 1
  driver: dra.example.com
  devices:
  - name: gpu-0
    attributes:
      dra.example.com/supported-models:
        strings:
        - model-a
        - model-b

목록 유형 속성은 kube-apiserverkube-schedulerDRAListTypeAttributes 기능 게이트에 의해 제어됩니다.

파생 속성 {#derived-attributes}

matchAttributedistinctAttribute 제약은 일반적으로 장치가 정확히 같은 이름으로 속성을 게시하도록 요구합니다. GPU 드라이버가 pcie_locality를 게시하고 NIC 드라이버가 pcie_root를 게시한다면(또는 numa0-pcie1 같은 문자열에 같은 정보를 포함한다면), 스케줄러는 이들이 같은 것을 나타낸다는 것을 인식할 방법이 없으므로, 두 드라이버의 장치는 공유 속성 이름에 동의하지 않는 한 공동 배치될 수 없습니다.

derivedAttributes는 드라이버가 공유 속성 이름을 표준화하기를 기다리지 않고 이 격차를 인라인으로 메울 수 있게 해줍니다. 요청의 .spec.devices.requests[].exactly 또는 .spec.devices.requests[].firstAvailable[] 아래에 하나 이상의 derivedAttributes 항목을 추가하세요. 각 항목은 스케줄러가 그 요청의 모든 후보 장치에 대해 평가하는 CEL 표현식을 정의합니다. 결과는 드라이버가 제공한 장치 속성과 정확히 같은 방식으로 matchAttribute 또는 distinctAttribute 제약에서 참조할 수 있는 가상 속성이 됩니다.

apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
  name: gpu-nic-numa-alignment
spec:
  devices:
    requests:
    - name: gpu
      exactly:
        deviceClassName: gpu.example.com
        count: 1
        derivedAttributes:
        - name: derived/numa
          expression: device.attributes["gpu.example.com"].numa
    - name: nic
      exactly:
        deviceClassName: nic.example.com
        count: 1
        derivedAttributes:
        - name: derived/numa
          expression: device.attributes["nic.example.com"].numaNode
    constraints:
    - requests: ["gpu", "nic"]
      matchAttribute: derived/numa

이 예시에서 gpunic 드라이버는 서로 다른 속성 이름(numanumaNode)으로 토폴로지 정보를 게시합니다. 각 요청은 자신의 장치 속성에서 공통의 derived/numa 값을 계산하고, matchAttribute 제약은 기반 드라이버가 공유 속성 이름에 절대 동의하지 않았어도 그 가상 속성에서 두 요청을 정렬합니다.

derivedAttributes에 대해 알아야 할 몇 가지 사항:

  • 명명: name은 DNS 서브도메인 뒤에 /와 C 식별자가 와야 하며, 드라이버가 제공한 속성 이름에 사용되는 같은 형식입니다(예: example.com/numaNode 또는 derived/numaNode). 이름이 드라이버가 이미 게시한 속성과 일치하면, 파생 속성의 값이 제약 일치를 위해 드라이버 제공 값을 가립니다. 의도하지 않은 가림을 피하려면 derived/ 같이 어떤 드라이버도 사용하지 않을 도메인 접두사를 사용하세요. 요청당 최대 32개의 파생 속성을 정의할 수 있습니다.
  • 제약에서 사용되어야 함: 모든 파생 속성은 그것을 정의하는 요청(또는 하위 요청)에 적용되는 최소 하나의 matchAttribute 또는 distinctAttribute 제약에서 참조되어야 합니다. 그렇지 않으면 ResourceClaim이 검증에 실패합니다.
  • 평가 범위와 순서: expression은 후보 장치마다 한 번, 요청 자신의 CEL 선택자(.selectors[].cel)가 그 장치를 이미 필터링한 후에 평가됩니다. 결과적으로 파생 속성은 선택자 표현식에서 참조될 수 없고, CEL 환경의 device.attributes를 통해 노출되지 않습니다.
  • 반환 유형: expression은 스칼라(string, int, bool, 또는 시맨틱 버전)로 평가되어야 하며, DRAListTypeAttributes 기능 게이트도 활성화된 경우 그 스칼라 유형 중 하나의 목록으로 평가될 수 있습니다.
  • 비용 제한: 각 표현식은 최대 길이와 추정 CEL 평가 비용 제한이 있습니다. 게다가 ResourceClaim의 모든 derivedAttributes 표현식의 결합된 추정 비용도 상한이 있어, 단일 스케줄링 시도에 추가되는 총 오버헤드를 제한합니다. 이러한 제한 중 하나라도 초과하면 ResourceClaim이 거부됩니다.
  • 런타임 오류는 스케줄링을 중단: 후보 장치에 대해 표현식 평가가 실패하면, 예를 들어 장치가 없는 속성을 참조하는 경우, 스케줄러는 그 장치를 조용히 건너뛰는 대신 할당을 중단하고 파드 스케줄링을 실패시킵니다. 표현식을 방어적으로 작성하세요, 예를 들어 읽기 전에 속성이 존재하는지 확인하는 방식으로.

파생 속성은 kube-apiserverkube-schedulerDRADerivedAttributes 기능 게이트에 의해 제어됩니다.

DRA 드라이버가 게시할 수 있는 표준 장치 속성 목록은 표준 장치 속성 참조를 참조하세요.

DRA에 의한 확장 리소스 할당 {#extended-resource}

DeviceClass에 확장 리소스 이름을 제공할 수 있어요. 그러면 스케줄러가 확장 리소스 요청에 대해 해당 클래스와 일치하는 장치를 선택합니다. 이를 통해 사용자는 파드에서 확장 리소스 요청을 계속 사용해 장치 플러그인이 제공하는 확장 리소스나 DRA 장치를 요청할 수 있습니다. 같은 확장 리소스는 단일 클러스터 노드에서 장치 플러그인 또는 DRA에 의해 제공될 수 있습니다. 같은 확장 리소스는 일부 노드에서는 장치 플러그인에, 같은 클러스터의 다른 노드에서는 DRA에 의해 제공될 수 있습니다.

아래 예시에서 DeviceClass에는 example.com/gpu라는 extendedResourceName이 주어집니다. 파드가 확장 리소스 example.com/gpu: 2를 요청하면 DeviceClass와 일치하는 장치가 둘 이상인 노드에 스케줄링될 수 있습니다.

apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
  name: gpu.example.com
spec:
  selectors:
  - cel:
      expression: device.driver == 'gpu.example.com' && device.attributes['gpu.example.com'].type
        == 'gpu'
  extendedResourceName: example.com/gpu

또한 사용자는 특수 확장 리소스를 사용해 ResourceClaim을 명시적으로 만들지 않고도 장치를 할당할 수 있습니다. 확장 리소스 이름 접두사 deviceclass.resource.kubernetes.io/와 DeviceClass 이름을 사용합니다. 이는 확장 리소스 이름을 지정하지 않더라도 모든 DeviceClass에서 동작합니다. 결과 ResourceClaim은 그 DeviceClass의 지정된 수의 장치에 대한 ExactCount 요청을 포함합니다.

DRA에 의한 확장 리소스 할당은 kube-apiserver, kube-scheduler, kube-controller-manager, kubeletDRAExtendedResource 기능 게이트에 의해 제어됩니다.

확장 리소스 요청에 대한 실습 워크스루는 컨테이너에 확장 리소스 할당을 참조하세요.

더 알아보기 (Learn more)