본문 바로가기

⭐ Kubernetes & EKS/오토스케일링 (HPA, CA)

ClusterAutoscaler 생성 및 테스트 (Part.1)

# EKS에 ClusterAutoscaler를 생성하자.

- 일단 ClusterAutoscaler가 무엇인지 알아보면 아래와 같다.

Cluster Autoscaler는 resource부족으로 실행이 안된 pod가 존재할때 node를 scale out 한다.

그리고 Cluster에 장시간동안 사용률이 낮은 node가 있고, 이 node에 있는 pod를 다른 node에 재배치할 수 있을때 node를 scale in 한다. CA는 10초에 한번씩 pod를 검사하며 빠르게 scale out, scale in을 한다. 하지만 한번 node가 scale out 되면 scale in 검사를 하기까지 10분동안 대기를 하기때문에 scale out은 비교적 빠르게, scale in은 비교적 느리게 진행된다고 할 수 있다.

- 자 그럼 CA를 생성하도록 하자.

1. IAM Policy 및 role 생성

ClusterAutoscaler는 IAM Role 권한을 기반으로 동작을 하므로 아래의 권한을 추가해 줘야한다.

- IAM Policy 생성

cluster-autoscaler-policy.json 파일 명으로 아래의 내용을 추가하고 저장한다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeAutoScalingInstances",
                "autoscaling:DescribeLaunchConfigurations",
                "autoscaling:DescribeTags",
                "autoscaling:SetDesiredCapacity",
                "autoscaling:TerminateInstanceInAutoScalingGroup",
                "ec2:DescribeLaunchTemplateVersions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

- 위의 저장된 파일명을 실행하여 policy를 생성한다. 여기서 생성된 Amazon Resource Name (ARN) 정보를 따로 저장해 둔다.

aws iam create-policy \
    --policy-name AmazonEKSClusterAutoscalerPolicy \
    --policy-document file://cluster-autoscaler-policy.json

- IAM role 생성

아래의 명령어를 활용하여 IAM Role을 생성할 수 있다.

eksctl create iamserviceaccount \
  --cluster=<Cluster_name> \
  --namespace=kube-system \
  --name=cluster-autoscaler \
  --attach-policy-arn=<위에서 생성한 policy의 arn> \
  --override-existing-serviceaccounts \
  --approve

2. Custer Autoscaler 생성

- 일단 CA를 생성할 YAML 파일이 필요하다. 아래의 URL을 실행하여 다운로드를 수행한다.

curl -o cluster-autoscaler-autodiscover.yaml https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml

- 위에서 다운받은 YAML을 VI나 VIM등의 프로그램으로 열고, <YOUR CLUSTER NAME>을 현재의 EKS 클러스터의 이름으로 변경 후 저장한다.

- 그리고 수정된 파일을 적용한다.

kubectl apply -f cluster-autoscaler-autodiscover.yaml

- 다음은 아래의 내용을 패치해준다.

kubectl patch deployment cluster-autoscaler \
  -n kube-system \
  -p '{"spec":{"template":{"metadata":{"annotations":{"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"}}}}}'

- 그리고 CA의 Deployment를 수정한다.

kubectl -n kube-system edit deployment.apps/cluster-autoscaler

- <YOUR CLUSTER NAME> 을 현재의 EKS 클러스터 이름으로 수정하고 container command 에 --balance-similar-node-groups 와 --skip-nodes-with-system-pods=false 를 추가하여 아래와 같이 수정한다.

    spec:
      containers:
      - command
        - ./cluster-autoscaler
        - --v=4
        - --stderrthreshold=info
        - --cloud-provider=aws
        - --skip-nodes-with-local-storage=false
        - --expander=least-waste
        - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<YOUR CLUSTER NAME>
        - --balance-similar-node-groups
        - --skip-nodes-with-system-pods=false

- https://github.com/kubernetes/autoscaler/releases

 

Releases · kubernetes/autoscaler

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

github.com

위의 페이지를 확인하여 현재 EKS 클러스터의 버전이 몇 버전인지 확인 후 아래의 명령어를 통해 적용한다.

(필자의 경우는 EKS 클러스터의 버전이 1.21이라서 아래와 같이 1.21.2 버전을 적용 하였다.)

kubectl set image deployment cluster-autoscaler \
  -n kube-system \
  cluster-autoscaler=k8s.gcr.io/autoscaling/cluster-autoscaler:v1.21.2

* 추가로, 위의 cluster-autoscaler의 버전과 eks 클러스터의 버전이 꼭 일치하지 않아도 된다.

테스트 한 바로는 eks 클러스터 버전 1.24에서 위의 1.21.2 버전이 정상적으로 작동하는것을 확인 했다.

3. Cluster Autoscaler 로그 확인

- 설정이 정상적으로 되었다면 로그를 확인하여 동작을 확인한다.

kubectl -n kube-system logs -f deployment.apps/cluster-autoscaler

- 로그를 확인하여 현재 정상적으로 실행 되고 있는지 확인이 가능하고, 진행 내역 또한 확인이 가능하다.

4. CA가 정상적으로 동작하고 있는지 확인을 해보자.

- 첫번째로, 현재 노드그룹의 노드의 수는 t3.medium 2개이다. 이 노드의 수를 강제로 1개로 줄여보자.

1개로 줄이게 되면 pending 되는 pod들이 생길것이고, 이런 상황이 됐을때 CA는 어떤 반응을 보이는지 확인해보자.

- 결과는 아래와 같다. 강제로 Node를 줄이게 되면 pod도 강제로 Pending 상태로 변하게 된다.

- 그런데, 바로 약 1분뒤 다시 노드그룹을 확인해보니... 아래와 같이 자동적으로 노드를 증가시킨것을 볼 수 있다.

그리고 원하는 크기도 원래는 1로 설정 되어 있었는데, EKS 자동으로 3으로 변경한 것으로 확인이 된다.

- 서비스에 지장이 없도록 자동적으로 노드를 늘리고 pod를 재배치 한것으로 확인이 된다. 그리고 이역할을 CA(ClusterAutoscaler)가 수행을 하였다.

- 두번째 테스트로 pod의 갯수를 늘려서 정상적으로 노드를 추가하는지 테스트를 해보자.

위에서 노드 2번의 추가할수 있는 pod의 갯수는 15개 이다. 20개의 pod를 추가로 생성할때 어떤 반응을 보이는지 테스트를 해보자.

- pod를 오버하여 생성한 모습, pending 상태에 있는 pod들이 빠르게 다시 생성되는 모습을 볼 수 있다.

- 그렇다면 노드는 어떻게 됐는지 확인해 보자.

아래의 캡쳐 화면을 보면 알겠지만 원하는 크기는 2개 이지만 pod가 정상적으로 실행이 되도록 노드를 신규로 생성하여 3개의 노드가 유지되는 모습을 볼 수 있다.

- 그렇다면 각각의 노드가 몇개의 pod들을 가지고 있는지 확인해보자.

1번과 2번 노드는 모든 pod를 사용하고 있고, 3번 노드만 pod 실행 여유를 가지고 있다.

CA가 늘어난 요청의 pod를 실행시키기 위해 노드를 강제로 생성하고, pod자원을 재배치 까지 완료한 모습이다.

놀라운것은 이런 과정에서 서비스의 끊김이 전혀 없었다는 점이다. (아니... 잠시 약 5분정도 504 배드 게이트웨이가 발생 하였다... 쩝 서비스에 대한 단절 부분은 조금더 봐야할거 같다.)

- 그렇다면 다시 pod를 3개로 줄여보면 어떻게 되는지 확인을 해보자.

위에서 써 놓았지만 CA는 스케일 아웃은 정보를 10초간격으로 확인하여 수행하지만 스케일 인 작업은 10분의 간격으로 확인하여 수행한다. 그래서 스케일 인 작업을 확인하기까지 조금 시간이 필요하다.

그리고 스케일 인 작업은 스케일 아웃 작업과 다르게 굉장히 천천히 10분이라는 넉넉한 시간동안 아주 천천히 스케일 인 작업을 수행 하는것 같았다.

서비스가 정상화 되고 Terminating 된 pod들이 남게 되는데 이게 상당히 오랜시간 Terminating된 상태로 있다가 삭제가 된다. 아래의 캡쳐 화면을 보면 무려 42m 분 동안 Terminating 상태로 머물러 있는 모습을 볼 수 있다.

그리고 노드 그룹을 확인해보면 노드 3개가 정상적으로 실행되고 있는 모습을 볼 수 있다.

정상화가 되는데 약 40분정도 소요가 된거 같다... ㅎㄷㄷ 왜그런지는 확인이 필요하다.

그런데 또 다른 테스트에서는 약 5분만에 Terminating pod가 삭제 된것을 확인할 수 있는데 케바케 인거 같기도 하다.

하지만 Node는 늘어나는것은 굉장히 빠르지만 줄어드는것은 pod의 재배치 때문인지 모르겠지만 굉장히 느리다.

일단 여기까지... 추가 테스트는 다음 파트에서 기록 하겠음.


추가 정보를 얻으려면 아래의 블로그를 방문하면 된다. 정리가 잘 되어 있으며 추가 정보를 확인 할 수 있다.

https://haereeroo.tistory.com/24

 

k8s autoscaling 2. CA (Cluster Autoscaler)

1. 서론 오늘은 CA(Cluster Autoscaler)에 대해서 얘기해보려고합니다. CA는 이름에 cluster가 들어가서 뭔가 cluster를 조작할 것 같지만 사실 node를 scaling하는 기능입니다. 2. CA Cluster Autoscaler는 resource부족

haereeroo.tistory.com