DRA(동적 리소스 할당) — 클러스터 관리자를 위한 모범 사례

DRA(동적 리소스 할당) — 클러스터 관리자를 위한 모범 사례 (Good practices for Dynamic Resource Allocation as a Cluster Admin)

이 페이지는 동적 리소스 할당(DRA, Dynamic Resource Allocation) 을 활용하는 쿠버네티스 클러스터를 구성할 때 알아두면 좋은 모범 사례를 다룹니다. 내용이 클러스터 관리자 관점에서 쓰여 있다는 점을 먼저 기억해 두세요. DRA는 하드웨어 같은 특수 리소스를 팟에 유연하게 할당할 수 있게 해 주는 기능이에요.

출처: Kubernetes 공식 문서 — DRA Good practices (Cluster Admin)

DRA는 여러 개의 서로 다른 API를 통해 조율됩니다. RBAC(역할 기반 접근 제어) 같은 인가 도구를 사용해서 사용자의 성격(persona)에 맞게 적절한 API에만 접근할 수 있도록 통제하세요.

  • 일반적으로 DeviceClassResourceSlice는 관리자와 DRA 드라이버만 접근할 수 있게 제한하는 게 좋아요.
  • 클레임을 가진 팟을 배포할 클러스터 운영자는 ResourceClaimResourceClaimTemplate API에 접근할 수 있어야 해요. 이 두 API는 모두 네임스페이스 범위(namespace scoped) 입니다.

DRA 드라이버 배포와 유지 관리 (DRA driver deployment and maintenance)

가능하면 무중단 업그레이드가 되는 드라이버를 쓰세요

무중단(seamless) 업그레이드를 지원하는 드라이버를 선택하면 시간과 리스크를 줄일 수 있어요. 다만 이 기능은 kubelet 1.33 이상에서만 사용 가능하고, 이기종(heterogeneous) 클러스터라면 드라이버가 지원하는지 문서를 꼭 확인해야 합니다.

DRA 드라이버가 liveness probe를 노출하는지 확인하고 활용하세요

DRA 드라이버는 보통 상태 확인용 gRPC 소켓을 제공합니다. 이 소켓을 드라이버를 배포하는 DaemonSetliveness probe로 설정하면 가장 쉽게 활용할 수 있어요. 만약 드라이버 설정을 직접 만들거나 쿠버네티스 팟으로 실행하지 않는다면, 오케스트레이션 도구가 DRA 드라이버를 재시작하도록 반드시 설정해 두세요.

노드를 드레인할 때 DRA 드라이버는 가능한 한 마지막에 드레인하세요

노드에 대한 커스텀 드레인 로직을 직접 구현한다면, DRA 드라이버 자체를 종료하기 전에 할당되거나 예약된 ResourceClaim/ResourceClaimTemplate이 남아 있지 않은지 확인하는 걸 고려해 보세요.

높은 부하(특히 대규모 환경)에서 컴포넌트를 모니터링하고 튜닝하세요

DRA API에 저장된 메타데이터를 바탕으로 팟을 스케줄링하는 동안, 컨트롤 플레인 컴포넌트인 kube-schedulerkube-controller-manager에 의해 조율되는 내부 ResourceClaim 컨트롤러가 가장 많은 일을 처리해요.

  • DRA 클레임을 사용하는 팟은 그렇지 않은 팟에 비해 API 서버 호출 수, 메모리, CPU 사용량이 더 필요합니다.
  • 노드 로컬 컴포넌트인 DRA 드라이버와 kubelet도 팟 샌드박스 생성 시 DRA API를 통해 하드웨어 요청을 할당해요.
  • 특별히 노드가 많은 대규모 환경이나 DRA 리소스 클레임을 많이 쓰는 워크로드가 많은 환경에서는, 관련 컴포넌트를 늘어난 부하에 대비하도록 설정해야 합니다.

잘못 튜닝된 컴포넌트는 팟 라이프사이클 동안 직간접적으로 다양한 증상을 일으킬 수 있어요. 예를 들어 kube-scheduler의 QPS와 burst 설정이 너무 낮으면, 스케줄러가 팟에 적합한 노드는 빠르게 찾지만 팟을 그 노드에 바인딩하는 데는 오래 걸릴 수 있습니다. DRA 스케줄링 중에는 kube-controller-managerclient-go 설정의 QPS와 Burst 파라미터가 특히 중요해요.

구체적인 튜닝 값은 노드/팟 수, 팟 생성 속도, 변경 주기(churn) 등 여러 요소에 따라 달라집니다. 스케일러빌리티 관련 기준은 SIG Scalability의 쿠버네티스 스케일링 임계값 문서를 참고하세요. DRA가 활성화된 100개 노드 클러스터에서 720개의 장수명 팟(90% 포화도)과 80개의 churn 팟(10% churn, 10회), 잡 생성 QPS 10으로 스케일 테스트를 수행했을 때, kube-controller-manager의 QPS를 75, Burst를 150까지 낮춰도 동등한 지표를 충족할 수 있었습니다.

kube-controller-manager 메트릭

kube-controller-manager가 관리하는 내부 ResourceClaim 컨트롤러를 관찰할 수 있는 메트릭이에요.

  • Workqueue Add Rate: sum(rate(workqueue_adds_total{name="resource_claim"}[5m]))ResourceClaim 컨트롤러에 항목이 얼마나 빨리 추가되는지 가늠할 수 있어요.
  • Workqueue Depth: sum(workqueue_depth{endpoint="kube-controller-manager", name="resource_claim"})ResourceClaim 컨트롤러의 백로그(밀린 작업)를 파악해요.
  • Workqueue Work Duration: histogram_quantile(0.99, sum(rate(workqueue_work_duration_seconds_bucket{name="resource_claim"}[5m])) by (le)) — 컨트롤러가 작업을 처리하는 속도를 이해하는 데 도움이 돼요.

만약 낮은 Workqueue Add Rate + 높은 Workqueue Depth + 높은 Workqueue Work Duration이 보인다면 컨트롤러가 최적으로 동작하지 않는다는 뜻이에요. QPS, burst, CPU/메모리 설정 같은 파라미터 튜닝을 고려해 보세요.

반대로 높은 Add Rate + 높은 Depth인데 Work Duration은 적정하다면, 컨트롤러가 작업을 처리하고는 있지만 동시성(concurrency)이 부족하다는 신호예요. 동시성은 컨트롤러에 하드코딩되어 있으므로, 클러스터 관리자는 팟 생성 QPS를 낮춰서 리소스 클레임 workqueue의 추가 속도를 감당 가능한 수준으로 조정할 수 있습니다.

kube-scheduler 메트릭

다음 스케줄러 메트릭은 DRA만이 아니라 스케줄된 모든 팟의 성능을 집계한 상위 수준 메트릭이에요. ResourceClaimTemplate을 많이 쓰는 배포에서는 종단 간(end-to-end) 메트릭이 결국 kube-controller-managerResourceClaimTemplate으로부터 ResourceClaim을 만드는 성능에 영향을 받는다는 점을 알아 두세요.

  • Scheduler End-to-End Duration: histogram_quantile(0.99, sum(increase(scheduler_pod_scheduling_sli_duration_seconds_bucket[5m])) by (le))
  • Scheduler Algorithm Latency: histogram_quantile(0.99, sum(increase(scheduler_scheduling_algorithm_duration_seconds_bucket[5m])) by (le))

kubelet 메트릭

노드에 바인딩된 팟이 ResourceClaim을 충족해야 할 때, kubelet은 DRA 드라이버의 NodePrepareResourcesNodeUnprepareResources 메서드를 호출해요. 이 동작은 kubelet 관점에서 다음 메트릭으로 관찰할 수 있습니다.

DRA kubeletplugin 동작

DRA 드라이버는 kubeletplugin 패키지 인터페이스를 구현하며, 이는 하부 gRPC 연산인 NodePrepareResourcesNodeUnprepareResources에 대한 자체 메트릭을 노출합니다. 예를 들어 다음과 같이 관찰할 수 있어요.

  • DRA kubeletplugin gRPC NodeUnprepareResources 연산: histogram_quantile(0.99, sum(rate(dra_grpc_operations_duration_seconds_bucket{method_name=~".*NodeUnprepareResources"}[5m])) by (le))

더 알아보기 (Learn more)