pod이 resource마다 request를 지정하면, kube-scheduler는 request만큼의 여유공간이 존재하는 node에 스케줄링한다. 만약 해당하는 node가 없다면 스케줄하지 않고 Event를 발생시킨다.
scheduler의 스케줄링 방식으로는 가볍게 2가지가 있다.
LeastRequestedPriority: 자원 여유 많은 node에 스케줄링
MostRequestedPriority: 자원 여유 적은 node에 스케줄링
request 필드는 pod들 간의 우선순위도 담당한다.
Pod A의 CPU request가 1이고 Pod B의 CPU request가 3일 경우, 한 노드 안에서 Pod A와 Pod B의 작업 수행시간은 1:3으로 주어진다.
node에 자원이 과도하게 사용될 경우 pod을 강제 종료시키는데, 이 때 종료시킬 pod의 우선순위를 세 그룹으로 나눈다. 그룹은 다음과 같다.
BestEffort (lowest)
pod에 따로 request나 limit을 걸어두기 않았을 경우 분류되는 그룹이다.
Burstable
request < limit으로 명시될 경우 분류되는 그룹이다.
Guaranteed (highest)
모든 resource에 대해 request == limit일 경우 분류되는 그룹이다.
간단히 말하면 request / limit이 작은 순서대로 pod를 preemption한다.
limit을 지정하면 kubelet이 해당 limit을 container runtime에 전달한다. container runtime은 해당 리소스만큼 격리한 후 프로세스가 제한을 초과하는지 감시한다. 프로세스가 더 많은 자원을 요청할 경우 OOM(Out of Memory) 상태롤 출력하고 종료시킨다.
limit은 또한 namespace 단위로 걸 수도 있는데, 이 때 ResourceQuota를 사용한다.
namespace별로 resource 뿐만 아니라 requests.storage 또는 persistentvolumeclaims 등을 정의해서 Volume 등 다양한 resource에 제한을 걸 수 있다.
apiVersion: v1
kind: ResourceQuota
metadata:
name: objects
spec:
hard:
pods: 10
replicationcontrollers: 5
secrets: 10
configmaps: 10
persistentvolumeclaims: 4
services: 5
services.loadbalancers: 1
services.nodeports: 2
ssd.storageclass.storage.k8s.io/persistentvolumeclaims: 2
spec.containers[].resources 필드에서 limits와 requests를 설정할 수 있다.
정의하는 자원은 보통 cpu / memory / hugepages-<size> / ephemeral-storage 가 있다.
hugepage) CPU가 사용하는 메모리가 있는 RAM의 부분 (운영체제)
ephemeral-storage) 캐싱, 로그등에 사용되는 RAM으로 지원되는 임시공간
아래는 yaml 적용 예제이다.
...
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
node level로 extended resource가 만들어지면 cluster 운영자는 API server에 HTTP request를 보내서 node별로 사용량을 정할 수 있다.
예를 들어 GPU resource를 추가로 정의해 실행하는 GPU 개수 등을 지정할 수 있다.
scheduler extender에 의해 관리된다.
scheduler가 resource accounting 방식을 사용하여 기존 자원처럼 스케줄링 시 resource 여유공간을 넘기지 않도록 감시한다.
pod 차원에서는 일반적인 resource처럼 정의하면 된다.
(예제에서 example.com/foo)
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myimage
resources:
requests:
cpu: 2
example.com/foo: 1
limits:
example.com/foo: 1
Kubernetes의 1.27에 추가된 기능으로 기존에 immutable했던 request를 변경할 수 있는 기능이다. spec.containers[].resizePolicy에서 resizing 시 어떻게 할지 정의 가능하다. (기본은 NotRequired)
spec:
containers:
- name: qos-demo-ctr-5
image: nginx
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainer
...
NotRequired : container running 중에 자원 추가
RestartContainer : 재시작 후 더 많은 자원으로 교체
아래와 같은 명령어를 입력하여 resize가 가능하다.
kubectl -n {namespaceName} patch pod {podName} --patch '{"spec":{"containers":[{"name":"qos-demo-ctr-5", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}
출처
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/
Kubernetes_in_Action