리소스 빈 패킹
리소스 빈 패킹 (Resource Bin Packing)
참고: 이 글은 단일 Pod 스케줄링 맥락에서의 리소스 빈 패킹에 적용됩니다. Pod 그룹을 스케줄링할 때의 빈 패킹은 토폴로지 인지 스케줄링 (Topology-aware Scheduling) 문서를 읽어보세요.
kube-scheduler의 스케줄링 플러그인 NodeResourcesFit에는 리소스 빈 패킹(bin packing)을 지원하는 두 가지 점수 계산 전략이 있어요: MostAllocated와 RequestedToCapacityRatio.
출처: 문서
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/foo와 intel.com/bar가 각각 CPU와 메모리의 1과 달리 3의 가중치를 가지므로, 이 확장 리소스의 사용률은 최종 노드 점수에 세 배 더 큰 영향을 미칩니다. 스케줄러는 가장 높은 점수를 받은 노드를 선택해 사용률이 높은 노드에 Pod를 스케줄링하는 것을 목표로 합니다. 이는 사용률이 가장 낮은 노드의 스케일다운을 준비하는 데 도움이 됩니다.
다른 매개변수와 기본 구성에 대해 더 알아보려면 NodeResourcesFitArgs API 문서를 참고하세요.
RequestedToCapacityRatio로 빈 패킹 활성화하기 (Enabling bin packing using RequestedToCapacityRatio)
RequestedToCapacityRatio 전략은 사용자가 리소스와 각 리소스의 가중치를 지정해 요청 대 용량 비율(request to capacity ratio)을 기준으로 노드에 점수를 매길 수 있게 해줘요. 이를 통해 대규모 클러스터에서 희소 리소스의 사용률을 높이기 위해 적절한 매개변수로 확장 리소스를 빈 패킹할 수 있어요. 할당된 리소스의 구성된 함수에 따라 노드를 선호합니다. NodeResourcesFit 점수 함수에서 RequestedToCapacityRatio의 동작은 scoringStrategy 필드로 제어됩니다. scoringStrategy 필드 안에서 requestedToCapacityRatio와 resources라는 두 매개변수를 구성할 수 있어요. requestedToCapacityRatio 매개변수의 shape는 사용률과 점수 값에 따라 최소 요청(least requested) 또는 최대 요청(most requested)으로 함수를 조정할 수 있게 해줍니다. resources 매개변수는 점수 계산 중 고려할 리소스의 name과 각 리소스의 가중치를 지정하는 weight로 구성됩니다.
아래는 requestedToCapacityRatio 필드를 사용해 확장 리소스 intel.com/foo와 intel.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/foo와 intel.com/bar만 나열됩니다. 따라서 NodeResourcesFit 플러그인은 이 두 리소스의 사용률만을 기반으로 노드에 점수를 매겨요. CPU와 메모리는 이 플러그인의 점수에 기여하지 않습니다. 구성된 shape가 사용률이 증가함에 따라 더 높은 점수를 부여하므로(utilization: 0에서 score: 0, utilization: 100에서 score: 10으로 상승), 스케줄러는 이 확장 리소스가 이미 더 많이 사용 중인 노드를 선호해 이들에 대한 요청을 가능한 한 적은 노드에 빈 패킹합니다.
이 점수 계산 전략에 CPU와 메모리를 포함하려면 resources 목록에 추가하세요. 목록의 모든 리소스가 동일한 shape 함수를 공유하므로, 그렇게 하면 해당 리소스에도 동일한 빈 패킹 곡선이 적용됩니다.
kube-scheduler 플래그 --config=/path/to/config/file로 KubeSchedulerConfiguration 파일을 참조하면 그 구성이 스케줄러에 전달됩니다.
다른 매개변수와 기본 구성에 대해 더 알아보려면 NodeResourcesFitArgs API 문서를 참고하세요.
점수 함수 튜닝 (Tuning the score function)
shape는 RequestedToCapacityRatio 함수의 동작을 지정하는 데 사용됩니다.
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)
- 스케줄링 프레임워크에 대해 더 읽어보기
- 스케줄러 구성에 대해 더 읽어보기