쿠버네티스는 컨테이너 단위로 리소스 제한 설정이 가능하다. 제한 가능한 리소스는 CPU, 메모리, Ephemeral 스토리지, 플러그인을 이용한 GPU 등이 있다.
CPU/메모리 제한
CPU는 클럭 수로 지정하지 않고 1vCPU를 1000m(millicores) 단위로 지정한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-resource
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
editor: vscode
spec:
containers:
- name: nginx-container
image: nginx:1.16
resources:
requests:
memory: "1024Mi"
cpu: "500m"
limits:
memory: "2048Mi"
cpu: "1000m"
Requests에는 사용하는 리소스 최솟값을 지정한다. 리소스 최솟값에 충족하지 못하는 노드에는 스케줄링되지 않는다. Limits는 사용할 리소스의 최댓값을 지정한다.
Ephemeral 스토리지 용량도 Request와 Limit을 지정할 수 있다. Ephemeral 스토리지 용량으로 계산되는 것으로 컨테이너가 출력하는 로그, emptyDir에 기록된 non-memory 데이터, 컨테이너의 쓰기 가능한 레이어에 기록된 데이터가 있다.
apiVersion: v1
kind: Pod
metadata:
name: sample-ephemeral-storage
spec:
containers:
- name: nginx-container
image: nginx:1.16
resources:
requests:
ephemeral-storage: "1024Mi"
limits:
ephemeral-storage: "2048Mi"
Cluster Autoscaler
쿠버네티스에는 Cluster Autoscaler가 구현된 환경이 많다. Cluster Autoscaler는 쿠버네티스 클러스터 자체의 오토 스케일링을 의미하며 수요에 따라 쿠버네티스 노드를 자동을 추가하는 기능이다. 노드를 자동으로 추가하는 기능은 클라우드 환경에서 수행되는 경우가 많다.
기본적으로 리소스에 의한 스케줄링은 Requests(최소)를 기준으로 이루어진다. Requests를 초과하여 할당한 경우에는 최소 리소스 요청만으로 리소스가 꽉 차 버려서 신규 노드를 추가해야 만한다. 이때 실제 컨테이너 프로세스가 사용하는 리소스 사용량은 고려되지 않는다. 다시 말해 Requests를 잘못 설정할 경우 실제 부하가 없는 상황에서 신규 노드가 추가되거나 실제 부하가 높은 상황에서 신규 노드가 추가되지 않을 수가 있다.
기본 정책으로 Requests와 Limits에 너무 큰 차이를 주지 않을 것과 Requests를 너무 크게 설정하지 않을 것 이 두가지를 명심해야 한다. 실제 값을 정할 때 Requests와 Limits를 낮게 설정하고 성능 테스트를 하면서 올려가는 것이 좋다.
LimitRange를 사용한 리소스 제한
LimitRange를 사용하면 파드 등에 대해 CPU나 메모리 리소스의 최솟값과 최댓값, 기본값 등을 설정할 수 있다. 네임스페이스마다 설정이 필요하며 신규로 파드를 생성할 때 사용되므로 기존 파드에는 영향을 주지 않는다.
설정 항목 | 개요 |
default | 기본 Limits |
defaultRequest | 기본 Requests |
max | 최대 리소스 |
min | 최소 리소스 |
maxLimitRequestRatio | Limits/Requests의 비율 |
LimitRange를 설정할 수 있는 리소스는 파드/컨테이너/영구 볼륨 클레임 세가지다.
타입 | 사용 가능한 설정 항목 |
컨테이너 | default/defaultRequest/max/min/maxLimitRequestRatio |
파드 | max/min/maxLimitRequestRatio |
영구 볼륨 클레임 | max/min |
컨테이너 LimitRange
apiVersion: v1
kind: LimitRange
metadata:
name: sample-limitrange-container
namespace: default
spec:
limits:
- type: Container
default:
memory: 512Mi
cpu: 500m
defaultRequest:
memory: 256Mi
cpu: 250m
max:
memory: 1024Mi
cpu: 1000m
min:
memory: 128Mi
cpu: 125m
maxLimitRequestRatio:
memory: 2
cpu: 2
파드 LimitRange
apiVersion: v1
kind: LimitRange
metadata:
name: sample-limitrange-pod
namespace: default
spec:
limits:
- type: Pod
max:
memory: 2048Mi
cpu: 2000m
min:
memory: 128Mi
cpu: 125m
maxLimitRequestRatio:
memory: 1.5
cpu: 1.5
영구 볼륨 클레임 LimitRange
apiVersion: v1
kind: LimitRange
metadata:
name: sample-limitrange-pvc
namespace: default
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 20Gi
min:
storage: 3Gi
QoS Class
파드에는 Requests/Limits 설정에 따라 자동으로 QoS Class 값이 설정되게 되어 있다.
QoS Class | 조건 | 우선순위 |
BestEffort | Requests/Limits 모두 미지정 | 3 |
Guaranteed | Requests/Limits가 같고 CPU와 메모리 모두 지정되어 있음 | 1 |
Burstable | Guaranteed를 충족하지 못하고 한개 이상의 Requests/Limits가 설정되어 있음 | 2 |
이 QoS Class는 쿠버네티스가 컨테이너에 oom score를 설정할 때 사용되며 oom score는 OOM Killer에 의해 프로세스를 정지시킬 때 우선순위 값으로 -1000(max) ~ 1000(min) 범위에서 설정한다. 위 테이블의 우선순위로 볼 때 OOM Killer에 의해 컨테이너를 정지시킬 때 BestEffort, Burstable, Guaranteed 순서로 정지한다.
QoS Class | 조건 |
BestEffort | 1000 |
Guaranteed | -998 |
Burstable | min(max(2, 1000 - (1000* 메모리의 Requests) / 머신 메모리 용량), 999) |
HorizontalPodAutoscaler
HorizontalPodAutoscaler(HPA)는 디플로이먼트/레플리카셋/레플리케이션 컨트롤러의 레플리카 수를 CPU 부하 등에 따라 자동으로 스케일 하는 리소스다. 부하가 높아지면 스케일 아웃하고 부하가 낮아지면 스케일 인된다. 파드에 Resource Requests가 설정되어 있지 않은 경우에는 동작하지 않는다.
레플리카 수 계산하는 수식은 아래와 같다
- 필요한 레플리카 수 = ceil(sum(파드의 현재 CPU 사용률) / targetAverageUtilization)
스케일링 조건식은 아래와 같다
- 스케일 아웃 조건식
- avg(파드의 현재 CPU 사용률) / targetAverageUtilization > 1.1
- 스케일 인 조건식
- avg(파드의 현재 CPU 사용률) / targetAverageUtilization < 0.9
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: sample-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sample-hpa-deployment
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 50
CPU 사용률 뿐만 아니라 다른 메트릭을 사용해 오토 스케일링도 할 수 있지만 프로메테우스나 그 외의 메트릭 서버와 연계하기 위한 설정이 필요하다.
'Kubernetes' 카테고리의 다른 글
쿠버네티스 노드 스케줄링 (0) | 2022.01.28 |
---|---|
쿠버네티스 헬스 체크 (0) | 2022.01.22 |
쿠버네티스 볼륨 (0) | 2022.01.02 |
쿠버네티스 컨피그 API (0) | 2022.01.01 |
쿠버네티스 인그레스 (0) | 2022.01.01 |