본문 바로가기
Recent Study/Kubernetes 학습과정

18. Autoscaler

by Thinking 2024. 1. 22.

 k8s의 Autoscaler에는 3가지가 있습니다. Pod의 개수를 늘리는 HPA, Pod의 리소스를 증가시키는 VPA, 클러스터에 노드를 추가하는 CA가 있는데 각각의 개념과 동작 방식을 확인해보겠습니다.

1. HPA, VPA, CA

 

1. HPA (Horizontal Pod Autoscaler)

: 컨트롤러가 있고, Replicas 수치에 따라 Pod가 만들어져서 운영이 되고 있는 상태입니다. 서비스도 연결이 돼서 모든 트래픽이 해당 Pod로 흐르는 상황입니다. 트래픽이 많아져서 Pod 내에 있는 리소스를 모두 사용하게 됐고, 조금 더 트래픽이 증가되면 Pod는 죽을 수 있습니다. 만약 사전에 HPA 만들어서 Controller에 연결을 해놓았다면 HPA가 Pod의 리소스 상태를 감지하고 있다가 위험한 상황이 오게 되면 Controller의 Replicas를 높여줍니다.

 

 Controller는 Pod를 하나 더 만들게 되고, 수평적으로 증가하게 되는데 이것을 Scale Out이라고 합니다. 반대로 리소스 사용량이 줄면 Scale In이 되었다고 합니다. 권장되는 조건이 있는데 1) 기동이 빠르게 되는 앱에서 사용하길 권장 2) Stateless App 이어야 합니다.

 

 

2. VPA (Vertical Pod Autoscaler)

: 만약 Pod 내의 리소스가 모두 사용되는 상황이 왔습니다. VPA를 달아놨다면 VPA가 리소스 상태를 감지하고 있다가 이 상태를 인지하고 Pod를 Restart 시키면서 리소스를 증가시켜 주는데 이를 Scale Up이라고 하고, 감소를 Scale Down이라고 합니다. 그래서 VPA는 StatefulApp에 대한 오토 스케일링을 할 때 사용하면 되고, 주의할 점은 한 Controller에 VPA, HPA 둘 다 달면 기능이 작동하지 않습니다. 

 

 

3. CA (Cluster Autoscaler)

: 클러스터에 있는 모든 노드에 자원이 없을 경우 동적으로 워커 노드를 할당합니다. 예로 2개의 Node 내에 Pod가 운영되고 있습니다. 또 Pod를 만들면 스케줄러가 할당해주는 노드에 배치가 되겠죠? 그리고 어느덧 워커 노드의 자원이 모두 소모되었습니다. 이 상태에서 Pod를 하나 더 만들려고 했을 때 스케줄러는 어느 노드에도 배치할 수 없는것을 알고, CA에게 워커 노드를 생성해달라고 요청합니다. 

그리고 CA를 사전에 특정 클라우드 프로바이더와 연결을 해놨다면 위처럼 요청이 들어왔다면, 해당 프로바이더의 노드를 하나 만들어주고 스케줄러는 Pod를 여기에 배치를 시킵니다. 이렇게 운영이 되다가 기존에 사용하던 Pod들이 없어져서 로컬 노드에 자원이 남게 되면 이를 감하고 CA에게 노드를 삭제해달라고 요청합니다. 이후 해당 노드에 있던 Pod는 로컬 노드로 옮겨집니다.

 

 

 

2. HPA Architecture

 

 해당 구조는 Master, Worker 노드들이 있고 Master의 Control Plane Component라고 해서 k8s의 주요 기능을 하는 컴포넌트들이 Pod의 형태로 띄워져서 돌아가고 있습니다.

 

1. Controller Manager

 : 우리가 사용하고 있는 Controller, ReplicaSet, Deployment, Daemon Set, HPA, VPA의 기능들이 스레드의 형태로 돌아가고 있습니다. 

2. kube-apiserver

: 이것은 k8s 모든 통신의 길목 역할을 한다고 보시면 됩니다.

 

 Worker Node Component라고 해서 k8s 설치 시에 kubelet이라는 것이 설치됩니다. 이것은 각각의 Node를 대표하고 에이전트 역할을 하는데 자신의 노드에 있는 Pod를 관리하는 역할을 합니다. 직접 컨테이너까지 만드는 것은 아니고 Controller Runtime이라고 실제 컨테이너를 삭제하는 역할을 하는 구현체가 있습니다. 

 

 [ 예시 ] ReplicaSet을 만들었을 때 과정을 보겠습니다.

(1) ReplicaSet을 담당하는 스레드는 Replicas가 1이라고 했을 때 Pod를 하나 만들어 달라고 kube-apiserver를 통해 kubelet에게 요청합니다. kubelet은 Pod는 k8s의 개념이고, (2) 이 안에 컨테이너만 뺴서 이걸 만들어 달라고 Docker에게 요청합니다.

그럼 (3) Docker가 노드 위에 컨테이너를 만들어주는데, 여기까지가 ReplicaSet을 만들었을 때 Pod 하나가 만들어지는 절차입니다.

 

 이 상태에서 HPA가 Pod 성능 정보를 알 수 있는 과정에 대해 알아봅시다. 먼저 Resource Estimator인 cAdvisor가 Docker로 부터 메모리와 CPU에 대한 성능 정보를 측정하는데 이 정보를 kubelet을 통해 가져갈 수 있게 해놓습니다. 그리고 AddOn Component로 metrics-server를 설치해야 하는데 이것을 설치하면 metrics-server가 각각의 노드들에 있는 kubelet에게 메모리와 CPU 정보를 가져와서 저장을 해둡니다. 이 데이터들을 다른 컴포넌트들이 사용할 수 있도록 kube-apiserver에 등록해놓습니다.

 

 그럼 HPA가 CPU와 메모리 정보를 kube-apiserver를 통해 가져갈 수 있게 되고, HPA는 15초마다 체크를 하고 있다가 Pod의 리소스 사용률이 높아졌을 때 ReplicaSet의 Replicas를 증가시킵니다. 추가적으로 Prometheus를 설치하면 단순 메모리나 CPU 외에도 다양한 정보를 수집할 수 있는데 예로 Pod로 들어오는 패킷 수라든지 Ingress로 들어오는 Request양을 알 수 있습니다. 그럼 HPA는 이 정보를 trigger로도 컨트롤러의 Replicas를 조절할 수 있습니다. 

 

 

 

3. HPA 세부 내용

 

: Replicas를 2로 Deployment를 만들면 ReplicaSet이 만들어지면서 Pod를 2개 생성이 됩니다. Pod의 리소스 Limit, Requests가 위처럼 설정되어 있는 상태에서 이것을 Scale in/out 하는 HPA를 만들겠습니다. 먼저 target Controller를 지정하는 부분이 있고, 증감되는 Replicas에 대해 min과 max를 지정해야 합니다. metrics는 매트릭 정보에 어떤 조건을 통해서 Replicas를 증가시킬지에 대한 부분인데 type이라고 해서 Resource라고 선택하면 이 Pod의 Resource 부분을 가리킵니다. 세부적으로는 Memory, CPU를 볼건지 정할 수 있습니다. 마지막으로 어떤 조건으로 증가시킬지에 대한 부분인데 가장 기본으로 사용되는 옵션인 Utilization이 있고, 평균 50%라고 했다면, 이 Pod의 Request 값을 기준으로 현재 사용자원이 평균 50%가 넘으면 Replicas를 증가시킵니다. 이 수치를 넘으면 무조건 하나씩 무조건 1개씩 Pod가 만들어지는 것은 아니고, 정해진 공식을 가지고 한 번에 몇 개를 증가시킬지 결정이 되는데 계산해봅시다.

 

 Resource를 CPU라고 정하고, 이 2개 Pod의 평균 CPU는 200이고 이 Utilization 50%로 정했을 때 실제 CPU 사용률이 100이 넘게 되면 HPA는 Replicas를 증가시키게 됩니다.

 

Scale Out 예시

: 현재 평균 CPU가 300이 됐다고 가정을 했을 때 Limits cpu가 500이기에 Pod는 죽지 않을 것이고, 몇개의  Pod 증가시킬지 공식을 대입해보면 현재 Replicas는 2에 현재 평균 CPU를 곱하고 지정한 타겟 값을 나누면 이것이 HPA가 증가시킬 Replicas 값이 됩니다.

 

Scale In 예시

: 반대로 6개로 Pod가 Scale Out 된 상태에서 평균 CPU가 50으로 떨어졌다고 가정하면, Replicas 값은 3이 됩니다.