이야기박스
(작성중) Kubernetes. Pod AutoScaling 본문
# 개요
쿠버네티스는 CPU 사용량 또는 다른 항목들을 모니터링하고 이를 토대로 오토스케일링이 가능합니다.
오토 스케일링 기능은 v1.6에서 v1.7로 넘어가면서 큰 개편이 있엇다고 하니 참고하시기 바랍니다.
# HPA ; HorizontalPodAutoScaler
쿠버네티스는 HPA라는 리소스를 만들어 포드의 수펑젹 오토 스케일링을 진행합니다.
프로세스는 다음과 같습니다.
- 스케일된 리소스 객체가 관리하는 모든 리소스의 메트릭을 수집
- 지정된 Target에 맞출 수 있는 Pod 수를 계산
- 계산된 결과 값을 Replicas 필드에 업데이트
1. 포드 메트릭 가져오기
쿠버네티스의 MetricServer(과거에는 Heapster)에게 RestAPI를 요청하여 메트릭을 획득합니다.
2. 필요한 포드 수 계산
사용중인 메트릭 값을 합산한 후 설정된 리소스 목표 값으로 나눈 후, 결과 값을 반올림합니다.
이 결과 값이 필요 Replica의 숫자이고 여기에 맞추어 오토 스케일링을 진행합니다.
만약, 여러 메트릭을 사용하더라도 복잡해지지는 않습니다. 개별적으로 필요 Replicas를 계산한 후, Max값을 스케일링에 사용합니다.
3. Replicas 업데이트
HPA는 스케일링 하는 Resource의 상세 내용을 몰라도 됩니다. 오토 스케일링의 대상이 되는 리소스들은 sub-resource라는 항목을 노출하고 HPA는 이를 조작할 뿐입니다.
Scale sub-resource를 노출하는 리소스
- Deployment
- ReplicaSet
- ReplicationController
- StatefulSet
## 전체 오토스케일링 프로세스
# CPU 사용률에 따른 스케일링
오토스케일링 기반으로 측정하는 메트릭 중 가장 중요한 정보는 CPU의 사용량입니다.
Tip. 갑작스러운 Peak 부하가 들어온다면?
Pod의 CPU 사용량을 100%가 되도록 설정하면 안된다. 최대 90% 공간을 넘지 않도록 주의!!
쿠버네티스에는 두 가지 Resource 정책이 있습니다. Request와 Limit입니다. 자세한 내용은 이전 포스트를 참조하시면 좋을 것 같습니다.
쿠버네티스는 어떤 기준으로 CPU 사용량을 판단할까요?
쿠버네티스는 Resource의 Request를 기준으로 사용량을 판단하고 오토스케일링을 진행합니다.
## YAML 정의
Deployment에는 반드시 Resource Request 필드가 있어야 합니다.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
resources:
requests:
cpu: 100m
다음은 HPA yaml입니다.
$ kubectl get hpa.v2beta1.autoscaling kubia -o yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: kubia
...
spec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 30
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: kubia
status:
currentMetrics: []
currentReplicas: 3
desiredReplicas: 0
HPA 또한 get, describe 명령을 통하여 확인할 수 있습니다.
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
kubia Deployment/kubia <unknown> / 30% 1 5 0
HPA를 배포하고 부하를 넣지 않았기 때문에 스케일링되어 파드가 1개로 줄었습니다.
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kubia 1 1 1 1 23m
그리고 Describe를 통하여 위 이벤트를 확인할 수 있습니다.
$ kubectl describe hpa
Name: kubia
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Sat, 03 Jun 2017 12:59:57 +0200
Reference: Deployment/kubia
Metrics: ( current / target )
resource cpu on pods
(as a percentage of request): 0% (0) / 30%
Min replicas: 1
Max replicas: 5
Events:
From Reason Message
---- ------ ---
horizontal-pod-autoscaler SuccessfulRescale New size: 1; reason: All
metrics below target
이제 부하를 넣어보도록 하겠습니다.
우선 서비스를 생성합니다.
$ kubectl expose deployment kubia --port=80 --target-port=8080
service "kubia" exposed
그리고 Deployment, HPA를 모니터링합니다.
$ watch -n 1 kubectl get hpa,deployment
Every 1.0s: kubectl get hpa,deployment
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa/kubia Deployment/kubia 0% / 30% 1 5 1 45m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deploy/kubia 1 1 1 1 56m
동시에 부하를 넣으면 Scale-UP을 확인할 수 있습니다.
From Reason Message
---- ------ -------
h-p-a SuccessfulRescale New size: 1; reason: All metrics below target
h-p-a SuccessfulRescale New size: 4; reason: cpu resource utilization
(percentage of request) above target
# 기타 오토스케일링
## Memory
Memory 기반 스케일링은 훨씬 복잡합니다. 쿠버네티스가 우리에게 해주는 일은 Pod를 죽이고 새로 생성하는 것 뿐입니다. 아무리 많은 Pod를 만들어줘도 애플리케이션 자체가 동일한 메모리를 사용한다면 결국 또 다시 스케일링이 발생할 수밖에 없습니다.
사용자는 이를 위해 애플리케이션이 메모리 기반으로도 Scale Out이 이루어 질 수 있도록 설계해야 합니다.
## Custom Metric
아래 블로그를 참조하시면 좋을 것 같습니다.
K8S autoscaling based on custom metrics without using a host port
QPS(Queries Per Second) 기준으로 한 오토스케일링 설정입니다.
...
spec:
metrics:
- type: Pods
resource:
metricName: qps
targetAverageValue: 100
...
커스텀 메트릭은 포드와 직접적으로 관련이 없는 메트릭을 사용할 수도 있습니다.
예를 들어, 다른 클러스터의 Ingress 객체의 메트릭을 사용할 수 있습니다.
...
spec:
metrics:
- type: Object
resource:
metricName: latencyMillis
target:
apiVersion: extensions/v1beta1
kind: Ingress
name: frontend
targetValue: 20
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: kubia
...
## Scale-Down to Zero
아직 쿠버네티스에서는 이 기능을 지원하지 않고, idling / un-idling을 통한 파드의 Replica를 0로 만드는 것을 논의중이라고 합니다.
# VPA ; Vertical Pod Autoscaling
VPA의 특징은 Autoscaler가 기존 사용량을 보고 CPU/Memory 사용량을 추천하고 업데이트 합니다. 그렇기 때문에 적절한 Resource Request/Limit을 찾기 위한 성능 테스트가 필요 없습니다.
하지만 현재로서 한계점도 많이 있습니다.
-
수직형 Pod 자동 확장은 클러스터당 최대 200개의 VPA 객체를 지원합니다.
-
수직형 Pod 자동 확장은 버전 1.12.6부터 리전 클러스터에서 지원됩니다.
-
CPU 또는 메모리에서는 수평형 Pod 자동 확장(HPA)과 함께 수직형 Pod 자동 확장을 사용하지 마세요. 하지만 커스텀 측정항목과 외부 측정항목에는 VPA와 HPA를 함께 사용할 수 있습니다.
-
워크로드의 실제 메모리 사용량에 대한 제한된 공개 상태로 인해 수직형 Pod 자동 확장 처리를 아직 자바 워크로드와 함께 사용할 수 없습니다.
# Cluster AutoScaler
위에서 포드의 스케일링에 대하여 알아보았다면, 이번 챕터는 노드의 스케일링에 대한 내용입니다.
'Computer & Data > Orchestration' 카테고리의 다른 글
Kubernetes. Ingress and TLS Setting (0) | 2020.01.28 |
---|---|
Kubernetes. Helm3 (1) | 2020.01.10 |
Docker - SpringBoot JVM Option 이슈 (0) | 2019.12.03 |
(작성중) Cheating Kubernetes & Docker (0) | 2019.11.19 |
(작성중) Docker <none>:<none> images (0) | 2019.11.14 |