[![logo](https://www.hongsnet.net/images/logo.gif)](https://www.hongsnet.net)

# K8s Auto Scaling에 대한 검토

> HPA(scale-up, scale-down)과 VPA(Resource-up, Resource-down)에 대한 검증을 진행한다.


# Auto Scaling

k8s에서는 **Horizontal Pod Autoscaler**(HPA), **Vertical Pod Autoscaler**(VPA)로 지정한 메트릭을 Controller가 체크하여, 부하에 따라 필요한 Pod의 Replica수가 되도록 자동으로 Pod수를 늘리거나 줄일 수 있는 기술을 지원한다.

- `Pre-Requirement`

k8s에서 Resouce에 대한 현황을 확인하려면, **metric-server가 설치**되어 있어야 한다. 최초의 경우 다음과 같이 설치를 진행한다.

```bash
# git clone https://github.com/kubernetes-sigs/metrics-server

# vi ./metrics-server/manifests/base/deployment.yaml
...중략
containers:
      - name: metrics-server
        image: gcr.io/k8s-staging-metrics-server/metrics-server:master
        imagePullPolicy: IfNotPresent
        #22 라인 아래추가 
        command:
        - /metrics-server
        - --kubelet-insecure-tls
        - --kubelet-preferred-address-types=InternalIP
```

다음과 같이 설치한다.

```bash
# kubectl apply -k ./metrics-server/manifests/base/
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
```

- **Horizontal Pod Autoscaler**(HPA, 수평)

**HPA**는 metric(System Resource metric)을 관찰한 후 임계치가 넘을 경우 `Pod 개수를 Scale Up 또는 Scale Down`한다. 만약 요구하는 metric에 비해 실행되고 있는 파드의 수가 작다면, 파드의 수를 늘리고(**Scale Up**), 반대의 경우 파드의 수를 줄인다(**Scale Down**). 단, `DaemonSet`과 같이 크기를 조정할 수 없는 경우에는 적용되지 않는다.


먼저 Deployment Object에 **Resource를 제한**한다.

```bash
# cat hello-world.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: k8s-verify
  name: hello-world
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: k8s-verify
  template:
    metadata:
      labels:
        app: k8s-verify
    spec:
      containers:
      - image: registry.hongsnet.net/joohan.hong/docker/nodejs:latest
        #imagePullPolicy: Always
        imagePullPolicy: IfNotPresent
        name: hello-world
        resources:
          requests:
            cpu: "500m"
          limits:
            cpu: "500m"
      nodeSelector:
        key: worker

```

이제 **HPA**의 Object를 다음과 같이 작성한다.

```bash
# cat hello-world_scale.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: k8s-verify-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hello-world
  minReplicas: 5
  maxReplicas: 10
  targetCPUUtilizationPercentage: 5
```

> cpu 사용률 평균이 5% 이상일 경우에 Scale Up이 발생된다.


다음은 기능에 대한 **동작검증 결과** 이며, **CPU 부하를 발생**하는 명령은 다음과 같다.


```bash
# while true;do curl localhost:32000;done
```

```bash
# kubectl get hpa --watch
NAME             REFERENCE                TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
k8s-verify-hpa   Deployment/hello-world   <unknown>/5%   5         10        0          8s
k8s-verify-hpa   Deployment/hello-world   <unknown>/5%   5         10        5          15s
k8s-verify-hpa   Deployment/hello-world   0%/5%          5         10        5          46s
k8s-verify-hpa   Deployment/hello-world   2%/5%          5         10        5          76s
k8s-verify-hpa   Deployment/hello-world   6%/5%          5         10        5          92s
k8s-verify-hpa   Deployment/hello-world   5%/5%          5         10        6          107s <- scale up
k8s-verify-hpa   Deployment/hello-world   5%/5%          5         10        6          2m2s
k8s-verify-hpa   Deployment/hello-world   4%/5%          5         10        6          2m17s
k8s-verify-hpa   Deployment/hello-world   4%/5%          5         10        6          2m33s
k8s-verify-hpa   Deployment/hello-world   4%/5%          5         10        6          3m18s
k8s-verify-hpa   Deployment/hello-world   4%/5%          5         10        6          3m34s
k8s-verify-hpa   Deployment/hello-world   4%/5%          5         10        6          3m49s
k8s-verify-hpa   Deployment/hello-world   4%/5%          5         10        6          4m4s
k8s-verify-hpa   Deployment/hello-world   1%/5%          5         10        6          4m19s
k8s-verify-hpa   Deployment/hello-world   0%/5%          5         10        6          4m35s
k8s-verify-hpa   Deployment/hello-world   0%/5%          5         10        6          7m7s
k8s-verify-hpa   Deployment/hello-world   0%/5%          5         10        5          7m22s <- scale down
k8s-verify-hpa   Deployment/hello-world   0%/5%          5         10        5          9m9s
k8s-verify-hpa   Deployment/hello-world   0%/5%          5         10        5          9m24s
```


- **Vertical Pod Autoscaler**(VPA, 수직)

HPA가 파드의 수를 늘리거나 줄여서 스케일링 했다면, **VPA**는 `Pod의 요청 리소스를 늘리거나 줄여서 스케일링 하는 방식`이다. 단, HPA와 다르게 Pod에 할당된 리소스는 실행 중에 다시 할당할 수 없기 때문에 스케일링 시 **Pod를 재시작하게** 된다. 


