리소스 빈 패킹

리소스 빈 패킹 (Resource Bin Packing)

참고: 이 글은 단일 Pod 스케줄링 맥락에서의 리소스 빈 패킹에 적용됩니다. Pod 그룹을 스케줄링할 때의 빈 패킹은 토폴로지 인지 스케줄링 (Topology-aware Scheduling) 문서를 읽어보세요.

kube-scheduler의 스케줄링 플러그인 NodeResourcesFit에는 리소스 빈 패킹(bin packing)을 지원하는 두 가지 점수 계산 전략이 있어요: MostAllocatedRequestedToCapacityRatio.

출처: 문서

MostAllocated 전략으로 빈 패킹 활성화하기 (Enabling bin packing using MostAllocated strategy)

MostAllocated 전략은 리소스 사용률을 기반으로 노드에 점수를 매기며, 할당량이 높은 노드를 선호합니다. 각 리소스 유형에 대해 가중치(weight)를 설정해 노드 점수에 미치는 영향을 조정할 수 있어요.

NodeResourcesFit 플러그인에 MostAllocated 전략을 설정하려면 다음과 같은 스케줄러 구성을 사용하세요.

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- pluginConfig:
  - args:
      scoringStrategy:
        resources:
        - name: cpu
          weight: 1
        - name: memory
          weight: 1
        - name: intel.com/foo
          weight: 3
        - name: intel.com/bar
          weight: 3
        type: MostAllocated
    name: NodeResourcesFit

이 구성에서 노드는 네 가지 리소스 모두에 걸친 사용률의 가중 평균으로 점수가 매겨집니다. intel.com/foointel.com/bar가 각각 CPU와 메모리의 1과 달리 3의 가중치를 가지므로, 이 확장 리소스의 사용률은 최종 노드 점수에 세 배 더 큰 영향을 미칩니다. 스케줄러는 가장 높은 점수를 받은 노드를 선택해 사용률이 높은 노드에 Pod를 스케줄링하는 것을 목표로 합니다. 이는 사용률이 가장 낮은 노드의 스케일다운을 준비하는 데 도움이 됩니다.

다른 매개변수와 기본 구성에 대해 더 알아보려면 NodeResourcesFitArgs API 문서를 참고하세요.

RequestedToCapacityRatio로 빈 패킹 활성화하기 (Enabling bin packing using RequestedToCapacityRatio)

RequestedToCapacityRatio 전략은 사용자가 리소스와 각 리소스의 가중치를 지정해 요청 대 용량 비율(request to capacity ratio)을 기준으로 노드에 점수를 매길 수 있게 해줘요. 이를 통해 대규모 클러스터에서 희소 리소스의 사용률을 높이기 위해 적절한 매개변수로 확장 리소스를 빈 패킹할 수 있어요. 할당된 리소스의 구성된 함수에 따라 노드를 선호합니다. NodeResourcesFit 점수 함수에서 RequestedToCapacityRatio의 동작은 scoringStrategy 필드로 제어됩니다. scoringStrategy 필드 안에서 requestedToCapacityRatioresources라는 두 매개변수를 구성할 수 있어요. requestedToCapacityRatio 매개변수의 shape는 사용률과 점수 값에 따라 최소 요청(least requested) 또는 최대 요청(most requested)으로 함수를 조정할 수 있게 해줍니다. resources 매개변수는 점수 계산 중 고려할 리소스의 name과 각 리소스의 가중치를 지정하는 weight로 구성됩니다.

아래는 requestedToCapacityRatio 필드를 사용해 확장 리소스 intel.com/foointel.com/bar에 대한 빈 패킹 동작을 설정하는 예시 구성이에요.

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- pluginConfig:
  - args:
      scoringStrategy:
        resources:
        - name: intel.com/foo
          weight: 3
        - name: intel.com/bar
          weight: 3
        requestedToCapacityRatio:
          shape:
          - utilization: 0
            score: 0
          - utilization: 100
            score: 10
        type: RequestedToCapacityRatio
    name: NodeResourcesFit

이 예시에서 resources에는 확장 리소스 intel.com/foointel.com/bar만 나열됩니다. 따라서 NodeResourcesFit 플러그인은 이 두 리소스의 사용률만을 기반으로 노드에 점수를 매겨요. CPU와 메모리는 이 플러그인의 점수에 기여하지 않습니다. 구성된 shape가 사용률이 증가함에 따라 더 높은 점수를 부여하므로(utilization: 0에서 score: 0, utilization: 100에서 score: 10으로 상승), 스케줄러는 이 확장 리소스가 이미 더 많이 사용 중인 노드를 선호해 이들에 대한 요청을 가능한 한 적은 노드에 빈 패킹합니다.

이 점수 계산 전략에 CPU와 메모리를 포함하려면 resources 목록에 추가하세요. 목록의 모든 리소스가 동일한 shape 함수를 공유하므로, 그렇게 하면 해당 리소스에도 동일한 빈 패킹 곡선이 적용됩니다.

kube-scheduler 플래그 --config=/path/to/config/fileKubeSchedulerConfiguration 파일을 참조하면 그 구성이 스케줄러에 전달됩니다.

다른 매개변수와 기본 구성에 대해 더 알아보려면 NodeResourcesFitArgs API 문서를 참고하세요.

점수 함수 튜닝 (Tuning the score function)

shapeRequestedToCapacityRatio 함수의 동작을 지정하는 데 사용됩니다.

shape:
  - utilization: 0
    score: 0
  - utilization: 100
    score: 10

위 인자는 사용률이 0%이면 노드에 0점, 사용률이 100%이면 10점을 부여해 빈 패킹 동작을 활성화합니다. 최소 요청(least requested)을 활성화하려면 점수 값을 다음과 같이 반대로 해야 해요.

shape:
  - utilization: 0
    score: 10
  - utilization: 100
    score: 0

resources는 선택적 매개변수로 기본값은 다음과 같아요.

resources:
  - name: cpu
    weight: 1
  - name: memory
    weight: 1

다음처럼 확장 리소스를 추가하는 데 사용할 수 있어요.

resources:
  - name: intel.com/foo
    weight: 5
  - name: cpu
    weight: 3
  - name: memory
    weight: 1

weight 매개변수는 선택적이며 지정하지 않으면 1로 설정됩니다. 또한 가중치는 음수 값으로 설정할 수 없습니다.

용량 할당을 위한 노드 점수 계산 (Node scoring for capacity allocation)

이 섹션은 이 기능의 내부 세부 사항을 이해하려는 사람을 위한 것이에요. 아래는 주어진 값 집합에 대해 노드 점수를 계산하는 방법의 예시입니다.

요청된 리소스 (Requested resources):

intel.com/foo : 2
memory: 256MB
cpu: 2

리소스 가중치 (Resource weights):

intel.com/foo : 5
memory: 1
cpu: 3

FunctionShapePoint {{0, 0}, {100, 10}}

노드 1 스펙 (Node 1 spec):

Available:
  intel.com/foo: 4
  memory: 1 GB
  cpu: 8

Used:
  intel.com/foo: 1
  memory: 256MB
  cpu: 1

노드 점수 (Node score):

intel.com/foo  = resourceScoringFunction((2+1),4)
               = (100 - ((4-3)*100/4))
               = (100 - 25)
               = 75                       # requested + used = 75% * available
               = rawScoringFunction(75)
               = 7                        # floor(75/10)

memory         = resourceScoringFunction((256+256),1024)
               = (100 -((1024-512)*100/1024))
               = 50                       # requested + used = 50% * available
               = rawScoringFunction(50)
               = 5                        # floor(50/10)

cpu            = resourceScoringFunction((2+1),8)
               = (100 -((8-3)*100/8))
               = 37.5                     # requested + used = 37.5% * available
               = rawScoringFunction(37.5)
               = 3                        # floor(37.5/10)

NodeScore   =  ((7 * 5) + (5 * 1) + (3 * 3)) / (5 + 1 + 3)
            =  5

노드 2 스펙 (Node 2 spec):

Available:
  intel.com/foo: 8
  memory: 1GB
  cpu: 8
Used:
  intel.com/foo: 2
  memory: 512MB
  cpu: 6

노드 점수 (Node score):

intel.com/foo  = resourceScoringFunction((2+2),8)
               =  (100 - ((8-4)*100/8)
               =  (100 - 50)
               =  50
               =  rawScoringFunction(50)
               = 5

memory         = resourceScoringFunction((256+512),1024)
               = (100 -((1024-768)*100/1024))
               = 75
               = rawScoringFunction(75)
               = 7

cpu            = resourceScoringFunction((2+6),8)
               = (100 -((8-8)*100/8))
               = 100
               = rawScoringFunction(100)
               = 10

NodeScore   =  ((5 * 5) + (7 * 1) + (10 * 3)) / (5 + 1 + 3)
            =  7

다음 단계 (What's next)

더 알아보기 (Learn more)