파드 및 컨테이너 리소스 관리 | Kubernetes : 요청(Request)과 제한(Limit)
Resource
pod.spec.containers.resources
requests
: 스케쥴러가 파드를 노드에 배치시킬 때 고려하는 리소스 요청. 이를 수용 가능한 노드에만 파드를 배치한다.cpu
memory
limits
: 애플리케이션이 최대로 증가할 수 있는 상한 값cpu
memory
$ kubectl explain pod.spec.containers.resources
...
FIELDS:
limits <map[string]string>
Limits describes the maximum amount of compute resources allowed. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
requests <map[string]string>
Requests describes the minimum amount of compute resources required. If
Requests is omitted for a container, it defaults to Limits if that is
explicitly specified, otherwise to an implementation-defined value. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
제한(Limit)과 달리, 요청(Request)은 보장을 해준다는 차이가 있다.
파드가 실행 중인 노드에 사용 가능한 리소스가 충분하면,
컨테이너가 해당 리소스에 지정한 request
보다 더 많은 리소스를 사용할 수 있도록 허용된다.
그러나, 컨테이너는 리소스 limit
보다 더 많은 리소스를 사용할 수는 없다.
limit만 세팅하는 경우, 자동으로 limit와 동일한 request가 세팅된다.
request만 세팅하는 경우 limit가 세팅되지는 않으며, 너무 큰 리소스는 생성 자체가 되지 않는다.
resource는 수정이 불가능하다.
replace 명령 시 --force
옵션을 사용하면, 기존의 것을 삭제하고 새로 생성한다.
Qos(서비스 품질) Class
- BestEffort : 품질 가장 낮음
- Burstable
- Guaranteed : 품질 가장 높음
요청 <= 제한 : 요청은 반드시 제한보다 작거나 같아야하며, 경우에 따라 우선 순위가 달라진다.
분류 | 설명 | 우선순위 |
Best-Effort 파드 | - request, limit 값이 설정되지 않은 경우 - 자원이 부족하면 가장 먼저 삭제된다. (kubelet에 의해) |
3 |
Bustable 파드 | - request < limit - 최소한의 자원 보장을 받지만 자원이 부족하면 최선적 파드 다음에 삭제된다 |
2 |
Guaranteed 파드 | - request = limit - 가장 우선순위가 높고 가장 나중에 삭제된다. |
1 |
요청과 제한의 단위
CPU 요청과 제한은 milicore
단위를 사용한다.
예시)
- 1500m == 1.5개
- 1000m == 1개
메모리의 요청과 제한은 M
, G
, T
Mi
, Gi
, Ti
단위를 사용할 수 있다.
☁️ 참고
노드가 사용하고 있는 CPU/Memory 확인하기
kubectl top nodes
- Addon
metrics-server
가 있어야한다. - cpu/memory의 실시간 모니터링만 가능하다.
- 설치 방법 : Ingress Addon 설정하기
- Addon
$ kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node1 254m 14% 1466Mi 45%
node2 105m 5% 747Mi 29%
node3 91m 4% 715Mi 27%
$ kubectl top pods
NAME CPU(cores) MEMORY(bytes)
myweb-reqlit 0m 1Mi
nfs-client-provisioner-758f8cd4d6-2sqcr 3m 6Mi
kubectl describe <NODE>
Non-terminated Pods:
- 요청/제한 양을 확인할 수 있음
$ kubectl describe node node1
...
Non-terminated Pods: (11 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
ingress-nginx ingress-nginx-controller-vp7w8 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3d8h
kube-system calico-node-qp7cm 150m (8%) 300m (16%) 64M (1%) 500M (14%) 8d
kube-system coredns-8474476ff8-lgmhr 100m (5%) 0 (0%) 70Mi (2%) 170Mi (5%) 8d
kube-system dns-autoscaler-5ffdc7f89d-jnxsm 20m (1%) 0 (0%) 10Mi (0%) 0 (0%) 8d
kube-system kube-apiserver-node1 250m (13%) 0 (0%) 0 (0%) 0 (0%) 8d
kube-system kube-controller-manager-node1 200m (11%) 0 (0%) 0 (0%) 0 (0%) 8d
kube-system kube-proxy-drg9s 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3d8h
kube-system kube-scheduler-node1 100m (5%) 0 (0%) 0 (0%) 0 (0%) 8d
kube-system metrics-server-c57c76cf4-4qpgb 100m (5%) 100m (5%) 200Mi (6%) 200Mi (6%) 3d8h
kube-system nodelocaldns-l2lz7 100m (5%) 0 (0%) 70Mi (2%) 170Mi (5%) 8d
metallb-system speaker-7jgsg 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3d10h
...
💻 실습
- Request = Limit
myweb-reqlim.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb-reqlim
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
resources:
requests:
cpu: 200m
memory: 200M
limits:
cpu: 200m
memory: 200M
$ kubectl create -f myweb-reqlim.yaml
Guranteed
확인
$ kubectl describe po myweb-reqlim
...
Volumes:
kube-api-access-jczpr:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: **Guaranteed**
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...
- Request < Limit
myweb-replim.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb-reqlim
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
resources:
requests:
cpu: 200m
memory: 200M
limits:
cpu: 300m
memory: 300M
리소스는 수정이 불가능하기 때문에, --force
옵션을 사용하여 삭제하고 다시 생성되도록 해야한다.
$ kubectl replace -f myweb-reqlim.yaml --force
pod "myweb-reqlit" deleted
pod/myweb-reqlit replaced
Burstable
확인
$ kubectl describe po myweb-reqlit
...
Volumes:
kube-api-access-f7k22:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: **Burstable**
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...
- Request 및 Limit 설정 X
myweb-reqlim.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb-reqlim
spec:
containers:
- name: myweb
image: ghcr.io/c1t1d0s7/go-myweb
$ kubectl replace -f myweb-reqlim.yaml --force
pod "myweb-reqlit" deleted
pod/myweb-reqlit replaced
BestEffort
확인
$ kubectl describe po myweb-reqlim
...
Volumes:
kube-api-access-qwhjg:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: **BestEffort**
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...
참고