본문 바로가기
k8s

k8s autoscaling 2. CA (Cluster Autoscaler)

by 혜리루 2021. 2. 7.

1. 서론

오늘은 CA(Cluster Autoscaler)에 대해서 얘기해보려고합니다.

CA는 이름에 cluster가 들어가서 뭔가 cluster를 조작할 것 같지만 사실 node를 scaling하는 기능입니다.

 

2. CA

 

Cluster Autoscaler는 resource부족으로 scheduling이 안된 pod(pending상태의 pod)가 존재할때 node를 scale out 합니다. 

그리고 Cluster에 장시간동안 utilization이 낮은 node가 있고, 이 node에 있는 pod를 다른 node에 재배치할 수 있을때 node를 scale in 합니다.

CA는 10초에 한번씩 pod를 검사하며 빠르게 scale out, scale in을 합니다. 하지만 한번 node가 scale out 되면 scale in 검사를 하기까지 10분동안 대기를 하기때문에 scale out은 비교적 빠르게, scale in은 비교적 느리게 진행된다고 할 수 있습니다.

3. aws에서의 작동

저희는 aws의 eks로 쿠버네티스 클러스터를 운영하기때문에 aws를 기준으로 말씀드리겠습니다.

CA는 node group을 관리하기 위해서 aws의 EC2 asg(Auto Scaling Group)를 이용합니다.

 

CA에 ASG를 적용하는 방법은 두가지가 있습니다.

 

1) CA 실행 argument로 ASG의 이름을 직접 넣어준다.

2) CA에 ASG의 node selector tag, taint tag를 달아준다.

- k8s.io/cluster-autoscaler/node-template/label/<label 이름> : ASG의 노드가 이 라벨을 가지고 있다고 간주한다.

- k8s.io/cluster-autoscaler/node-template/taint/<taint 이름> : ASG의 노드가 이 taint를 가지고 있다고 간주한다.

CA 버전 1.14부터는 ephemeral-storage, cpu, memory등을 tag로 달아줄 수 있습니다.

k8s.io/cluster-autoscaler/node-template/resources/ephemeral-storage: 100G

 

일반적으로 1번보다는 2번이 더 자주 사용되고, 권고된다고 합니다.

 

 

만일 node group이 한개가 아니라 여러개 이고, 조건에 맞는 asg가 여러개일경우에는 어떻게 할까요?

 

--expander flag를 주면 됩니다. k8s는 expander 옵션을 보고 여러개의 node 다수의 node group중에 어떤 녀석을 추가할지 결정합니다.

현재 CA에는 5개의 expander가 있다고 합니다.

 

1.random -> 무작위로 선택

2.most-pods -> 현재 pending된 pod들을 가장 많이 할당할 수 있는 node group을 선택

3.least-waste -> cpu, memor가 가장 적게 남는 node group을 선택

4.price -> cost가 가장 적은 node group을 선택

5.priority -> 우선순위가 높은 node group을 선택

 

기본 값은 random입니다. 상황에 따라서 적절한 expander값을 사용하면 됩니다.

 

4. node가 scale in 되지않는 조건

특정 조건의 pod가 있는 node가 scale in되는 것을 막을 수도 있습니다.

아래 조건들은 node가 CA에 의해 scale in 되지않는 조건입니다.

 

1. PodDisruptionBudget이 설정되어있을때.

  PodDisruptionBudget옵션을 설정하면 일정 개수 이상의 pod가 떠있을 수 있도록 CA의 node scale in을 막습니다.

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: practice
  namespace: default
  labels:
    app: practice
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: practice

2. kubesystem namespace를 가진 pod가 있을때

3. pod를 다른 node로 이동할 수 없을 때

4. "cluster-autoscaler.kubernetes.io/safe-to-evict" : "false" 어노테이션이 설정 되어있는경우.

  pod에 safe-to-evict 어노테이션을 설정하면 ca가 pod를 다른 노드로 옮기거나, 해당 pod가 실행되고 있는 노드를 scale in할 수 없습니다.

 

5. overprovisioning

node를 scale out할때는 instace를 새로 띄우는거다보니 pod를 scale out하는 것보다 시간이 오래 걸리는데요

이 scale out 시간 절약을 위해서 미리 프로비저닝할 수 있습니다.

방법은 직관적이고 간단한데요,

 

1. 아무 역할을 하지않는 pod를 미리 생성합니다. 이때 pod의 priority를 다른 일반 pod들보다 낮게 설정해줍니다.

---
apiVersion: scheduling.k8s.io/v1beta1
kind: PriorityClass
metadata:
  name: overprovisioning
value: -1
globalDefault: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: overprovisioning
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      run: overprovisioning
  template:
    metadata:
      labels:
        run: overprovisioning
    spec:
      priorityClassName: overprovisioning
      containers:
      - name: reserve-resources
        image: k8s.gcr.io/pause
        resources:
          requests:
            cpu: 1600m
            memory: 550Mi

2. 일반 pod가 새롭게 생성될때 node에 자리가 부족하면 1의 pod를 내쫓고 그 자리를 차지합니다.

3. 내쫓김을 당한 pod는 scale out을 trigger합니다.

 

이렇게 너무 간단하게 node를 over provisioning할 수 있는데요. 한가지 주의할점은 overprovisioning pod의 resource입니다.  overprovisioning pod를 내쫓아도 node의 잔여 resource가 모자라는 경우에 당연하게도 overprovisioning이 정상적으로 작동하지 않습니다. 이를 대비해서 overprovisioning pod의 memory, cpu의 resource request를 적정한 크기로 설정해야합니다.

5. 기타 옵션

--skip-nodes-with-system-pods=false 

CA는  kube-system pod를 실행중인 node는 terminate하지 않는데요, 이 옵션을 주면 해당 node까지도 terminate합니다.

 

--scale-down-delay-after-add
--scale-down-delay-after-delete
--scale-down-delay-after-failure

 

CA는 기본 설정상으로 scale down 전에 10분정도 대기를 합니다. 위의 옵션들로 대기시간을 수정할 수 있습니다.

 

  # write-status-configmap: true
  # leader-elect: true
  # skip-nodes-with-local-storage: false
  # expander: least-waste
  # scale-down-enabled: true
  # balance-similar-node-groups: true
  # min-replica-count: 2
  # scale-down-utilization-threshold: 0.5
  # scale-down-non-empty-candidates-count: 5
  # max-node-provision-time: 15m0s
  # scan-interval: 10s
  # scale-down-unneeded-time: 3m
  # skip-nodes-with-local-storage: false
  # skip-nodes-with-system-pods: true

기타 사용 가능한 옵션들입니다.

6. 마무리

이번에는 CA의 기본적인 내용에 대해서 알아보았는데요, 다음 포스팅에서 실제로 AWS기준으로 CA를 구성해보도록 하겠습니다.

 

출처 : github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.mdgithub.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node

github.com/kubernetes/autoscaler

medium.com/scout24-engineering/cluster-overprovisiong-in-kubernetes-79433cb3ed0e

 

Cluster overprovisioning in Kubernetes

At Scout24 we have started to use Kubernetes, more specifically Amazon’s managed service EKS, to run our microservices. Kubernetes, at its…

medium.com

 

kubernetes/autoscaler

Autoscaling components for Kubernetes. Contribute to kubernetes/autoscaler development by creating an account on GitHub.

github.com

 

kubernetes/autoscaler

Autoscaling components for Kubernetes. Contribute to kubernetes/autoscaler development by creating an account on GitHub.

github.com

 

kubernetes/autoscaler

Autoscaling components for Kubernetes. Contribute to kubernetes/autoscaler development by creating an account on GitHub.

github.com

 

'k8s' 카테고리의 다른 글

k8s autoscaling 3. vpa (Vertical Pod Autoscaler)  (0) 2021.02.21
k8s autoscaling 1. hpa (Horizontal Autoscaler)  (0) 2021.02.05

댓글