쿠버네티스의 스케일링 방안
- 포드에서 실행되는 애플리케이션은 리플리케이션컨트롤러, 레플리카셋, 디플로이먼트 또는 확장 가능한 리소스의 복제본 필드를 늘려서 수동으로 스케일링 가능
- 컨테이너의 리소스 요청 및 제한을 늘려 수직적으로 스케일 조정 가능 (현재 포드가 실행되는 동안이 아니라 포드 생성 시에만 수행할 수 있음)
1. 포드의 수평적 오토스케일링
[HorizontalPodAutoscaler(HPA)]
포드의 수평적 오토스케일링은 컨트롤러가 관리하는 포드 복제본의 수를 자동으로 조정한다. 이것은 HorizontalPodAutoscalet 리소스를 만들어 활성화 및 구성되는 Horizontal 컨트롤러가 수행한다.
컨트롤러는 포드 매트릭을 주기적으로 확인하고 HorizontalPodAutoscaler 리소스에 구성된 대상 메트릭 값을 충족시키는 데 필요한 복제본 수를 계산하고 대상 리소스(대플로이먼트, 레플리카셋, 레플리케이션컨트롤러 또는 스테이트풀셋)의 복제본 필드를 조정한다.
ㅁ 오토스케일링 프로세스
오토스케일링 프로세스는 세단계로 나눌 수 있다.
ㅇ 스케일된 리소스 객체가 관리하는 모든 포드의 메트릭을 가져온다.
ㅇ 지정된 목표값에 메트릭을 가져오는데 필요한 포드수를 계산한다.
ㅇ 스케일된 리소스의 복제본 필드를 업데이트 한다.
[첫번째. 포드 메트릭 가져오기]
오토스케일링은 포드 메트릭 자체 수집을 수행하지 않는다. 다른 소스에서 메트릭을 가져온다.
포드 및 노드 메트릭은 cAdvisor라는 에이전트에 의해 수집된다.
cAdvisor는 각 노드의 Kubelet에서 실행된 다음 힙스터라고 불리는 클러스터 전체 구성 요소로 집계된다. 포드의 수평적 오토스케일러 컨트롤러는 REST 호출을 통해 힙스터를 쿼리하여 모든 포드의 메트릭을 가져온다.
이것은 오토스케일링이 동작하려면 클러스터에서 힙스터가 실행 중이어야 함을 의미한다.
[필요한 포드의 개수 계산]
오토스케일러가 스케일링(디플로이먼트, 레플리카셋, 레플리케이션컨트롤러 또는 스테이트풀셋 리소스)에 속하는 모든 포드의 메트릭을 가지면, 필요한 메트릭을 사용해 필요한 복제본 수를 계산할 수 있다.
가능한 모든 대상 복제본의 메트릭 평균 값을 구성된 대상 값에 가까운 수를 찾아야 한다. 이 계산에 대한 입력은 포드 메트릭 집합(가능한 한 포드당 여러 메트릭)이고 출력은 단일 정수(포드 복제본 수)이다.
오토스케일러가 단일 측정 항목만 고려하도록 구성된 경우 필요한 복제본 수를 계산하는 것이 간단하다.
모든 포드의 메트릭 값을 합산해 HorizontalPodAutoscaler 리소스에 설정된 목표값으로 나누고 나서 다음으로 큰 정수로 반올림 한다.
실제 계산은 메트릭 값이 불안정하고 빠르게 변경될 때 오토스케일러가 같이 요동하지 않도록 하기 때문에 이보다 조금 더 복잡하다.
오토스케일러가 여러 포드 메트릭(예: CPU 사용량 및 초당 쿼리 수 QPS)을 기반으로 할 경우 계산이 훨씬 복잡해진다. 오토스케일러는 메트릭의 복제본 수를 개별적으로 계산한 다음 가장 높은 값을 가진다.
(예: 대상 CPU 사용을 달성하기 위해 네 개의 포드가 필요하고 대상 QPS를 달성하는 데 세 개의 포드가 필요한 경우 오토스케일러가 네 개의 포드로 스케일 할 것이다.)
[스케일된 리소스에서 이상적인 복제본 수 만큼 업데이트 하기]
오토스케일링 작업의 마지막 단계는 크기가 조정된 리소스 객체(예: 레플리카셋)에서 원하는 복제본 개수 필드를 업데이트한 다음 레플리카셋 컨트롤러가 추가 포드를 순환하거나 초과된 객체를 삭제하도록 관리하는 것이다.
오토스케일러는 API 서버가 스케일 하위 리소스를 노출하는 한 확장 가능한 모든 리소스에서 동작할 수 있다. 현재 노출되는 것은 다음과 같다.
ㅇ Deployment (디플로이먼트)
ㅇ ReplicaSet (레플리카셋)
ㅇ ReplicationController (레플리케이션컨트롤러)
ㅇ StatefulSet (스테이트풀셋)
[전체 오토스케일링 프로세스]
ㅁ. CPU 사용률에 따른 스케일링
[CPU 사용을 기반으로 한 HorizontalPodAutoscaler 생성]
수평적 오토스케일러를 생성하고 CPU 사용률에 따라 포드 크기를 조정하는 방법은 Deployment의 포드 템플릿에 CPU 리소스 요청을 추가해야 한다.
ㅇ 일반적인 CPU 요청 세트의 Deployment: deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kuiba
spec:
replicas: 3 # 초기 복제본 수를 이상적인 3으로 수동 설정
template:
metatdata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1 # kubia 실행: v1 이미지
name: nodejs
resources:
requests:
cpu: 100m # 포드당 100밀리코어의 CPU 요구
위의 예에서는 오토스케일링을 사용하지 않았다. Deployment 작성 후 포드의 수평 오토스케일링 기능을 사용하려면 HPA (HorizontalPodAutoscaler) 객체를 생성하고 디플로이먼트를 가리켜야 한다.
아래와 같이 kubectl autoscale 명령을 사용한다.
$ kubectl autoscale deployemt kubia --cpu-percent=30 --min=1 --max=5
deployment "kubia" autoscaled
이렇게 하면 HPA 객체가 생성되고 kubia라는 디플로이먼트가 스케일링 대상으로 설정된다. 포드의 목표 CPU 사용률을 30%로 설정하고 최소 및 최대 복제본 수를 지정한다.
오토 스케일러는 계속해서 CPU 사용률을 30% 정도로 유지하기 위해 복제본 수를 지속적으로 조정하지만 1미만으로 축소되지 않거나 최대 5 복제본까지 확장되지 않는다.
ㅇ HorizontalPodAutoscaler YAML 정의
$ kubectl get hpa.v2beta1.autoscaling kubia -o yaml
apiVersion: autoscaling/v2beta1 # HPA 리소스는 오토스케일러 API 그룹에 있다.
kind: HorizontalPodAutoscaler
metadata:
name: kubia # 각 HPA 에는 이름이 있다 (이 경우 디프롤이먼트 이름과 일치할 필요는 없다.)
. . .
spec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilziation: 30
type: Resource
minReplicas: 1
scaleTargeRef: # 오토스케일러가 처리할 대상 리소스
apiVersion: extensions/v1beta1
kind: Deployment
name: kubia
status: # Autoscale의 현재 상태
currentMetrics: []
currentReplicas: 3
desiredReplicas: 0
ㅁ 첫번째 오토 리스케일 이벤트 보기
오토스케일러가 조치를 취하기 전에 cAdvisror가 CPU 메트릭을 얻고 힙스터가 수집하기까지는 시간이 걸린다. 이 시간 동안 kubectl get을 사용해 HPA 리소스를 표시하면 TARGET 열에 <unknown>이 표시된다.
$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
kubia Deployment/kubia <unkown> / 30% 1 5 0
현재 요청이 없는 3개의 포드를 실행 중이므로 CPU 사용률이 0에 가까워야 한다. 오토스케일러가 단일 포드로 크기를 조정할 것을 예상해야 한다. 단일 포드로도 CPU 사용률이 여전히 30% 미만일 수도 있다.
실제 사용률이 없으면 MINPODS 수로 디플로이먼트를 단일 복제본으로 축소한다.
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kubia 1 1 1 1 23m
[kubectl describe를 사용해 HorizontalPodAutoscaler 검사하기]
$ kubectl describe hpa
NAME: kubia
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Sat, 03 Jun 2020 12:59:58 +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 Mesage
---- ------ ---
horizontal-pod-autoscaler SuccessfulRescale New size : 1; reason: ALL
ㅁ 스케일업 트리거
위에서 첫 번째 오토 리스케일 이벤트(스케일 다운)을 확인 했다. 이제 포드에 요 청을 보내기 시작해 해당 포드의 CPU 사용량을 늘리려고 한다.
이 때 포드를 서비스를 통해 노출시켜야 하므로 단일 URL을 통해 포드를 모두 맞출 수 있도록 kubectl expose를 사용한다.
$ kubectl expose deployment kubia --port=80 --target-port=8080
service "kubia" exposed
[병렬로 다수의 리소스 감시]
$ 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
ㅁ HPA 객체에서 사용할 수 있는 세가지 유형의 메트릭
ㅇ 리소스 메트릭 유형
리소스 유형은 오토스케일러 베이스를 컨테이너의 리소스 요청에 지정된 것과 같은 리소스 메트릭에 대한 오토스케일링 결정으로 만든다.
ㅇ 포드 메트릭 유형
포드 유형은 포드와 관련된 다른 메트릭을 직접 참조하는데 사용, 이런 메트릭의 이미 언급한 QPS(Queries Per Second) 또는 메시지 브로커 대기열의 메시지 수(메시지 브로커가 포드로 실행 중일 때)
포드의 QPS 메트릭을 사용하도록 오토스케일러를 구성하려면 HPA 객체의 메트릭 필드 아래에 나열된 항목을 포함시킨다.
[HPA의 사용자 정의 포드 메트릭 참조하기]
...
spec:
metrics:
- type: Pods # 포드 메트릭 정의
resource:
metricName: qps # 메트릭 이름
targetAverageValue: 100 # 모든 대상 포드의 평균 목표 값
...
위 예제에서는 오토스케일러를 구성해 HPA 리소스가 대상으로 하는 레플리카셋 컨트롤러가 관리하는 모든 포드의 평균 QPS를 100으로 유지한다.
ㅇ 객체 메트릭 유형
객체 메트릭 유형은 오토스케일의 스케일 포드를 해당 포드와 직접 관련이 없는 메트릭을 기반으로 만들려는 경우에 사용된다.
인그레스 객체와 같은 다른 클러스터 객체의 메트릭에 따라 포드의 크기를 조정할 수 있다.
[HPA에서 다른 객체의 메트릭 참조하기
...
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
...
이 예제에서 HPA는 프론트엔드 인그레스 객체의 latencyMills 메트릭을 사용하도록 ㅜ성됨
메트릭의 대상 값은 20