본문 바로가기

DevOps/Jenkins

[AWS CLI] ECS 서비스 우선순위 기반 Task 분배 자동화

스크립트 작성 배경

AWS ECS에는 Auto Scaling 기능이 있다. 

하지만 때로는 두개 또는 세개의 서비스가 n개의 task 수를 적절히 나눠가져야 할 때가 생긴다..,

그러나 기본 Auto Scaling으로는 안 된다. 그래서 Jenkins에서 AWS CLI로 오토스케일링을 구현했다.

 

스크립트

- total은 31개 유지하기

svc-high-priority가 svc-low-priority 보다 우선순위가 높다.

svc-high-priority의 max capacity는 30으로 유지, svc-low-priority은 최소 1개는 유지

- svc-high-priority가 30일 때, svc-low-priority는 1개만 가능

svc-high-priority가 15일 때, svc-low-priority는 16개까지 가능

svc-high-priority가 1일 때, svc-low-priority는 30개까지 가능

#!/bin/bash
export AWS_ACCOUNT=012356789000
export AWS_DEFAULT_REGION=ap-northeast-2
CLUSTER_NAME="cluster-name"
HIGH_SVC_NAME="svc-high-priority"
LOW_SVC_NAME="svc-low-priority"
TOTAL_DESIRED_COUNT=31

# desired count
HIGH_DESIRED_COUNT=$(aws ecs describe-services \
--cluster $CLUSTER_NAME \
--service $HIGH_SVC_NAME \
--query "services[0].desiredCount")
echo $HIGH_DESIRED_COUNT
LOW_MAX_CAPACITY=$((TOTAL_DESIRED_COUNT-HIGH_DESIRED_COUNT))
        
SETTED_LOW_MAX_CAPACITY=$(aws application-autoscaling describe-scalable-targets \
        --service-namespace ecs \
        --resource-id service/$CLUSTER_NAME/$LOW_SVC_NAME \
        --scalable-dimension ecs:service:DesiredCount \
        --query "ScalableTargets[0].MaxCapacity")

if [ $((SETTED_LOW_MAX_CAPACITY)) -eq $LOW_MAX_CAPACITY ] ; then
	echo low already $SETTED_LOW_MAX_CAPACITY
else
	aws application-autoscaling register-scalable-target \
        --service-namespace ecs \
        --resource-id service/$CLUSTER_NAME/$LOW_SVC_NAME \
        --scalable-dimension ecs:service:DesiredCount \
        --min-capacity 1 \
        --max-capacity $LOW_MAX_CAPACITY
fi

 

서비스 코드

없어도 되는데 low service의 max capacity만 바꿔놓고 오토스케일링 되도록 기다리기 싫을 때 바로 desired count를 업데이트 하기 위한 스크립트이다.

sleep 코드 없이 바로 desired count를 업데이트 하면 max capacity 보다 desired count가 더 크기 때문에 적용이 안 된다.

수정한 max capacity가 적용될 때까지 기다려주기....

    echo "Waiting for scalable target to be updated..."
    for i in {1..10}; do
      CURRENT_MAX=$(aws application-autoscaling describe-scalable-targets \
        --service-namespace ecs \
        --resource-id service/$CLUSTER_NAME/$LOW_SVC_NAME \
        --scalable-dimension ecs:service:DesiredCount \
        --query "ScalableTargets[0].MaxCapacity" \
        --output text)
    
      if [ "$CURRENT_MAX" -eq "$LOW_MAX_CAPACITY" ]; then
        echo "Scalable target updated."
        break
      fi
      sleep 2
    done
    
    aws ecs update-service \
      --cluster $CLUSTER_NAME \
      --service $LOW_SVC_NAME \
      --desired-count $LOW_MAX_CAPACITY

 

최최종

#!/bin/bash
export AWS_ACCOUNT=012356789000
export AWS_DEFAULT_REGION=ap-northeast-2
CLUSTER_NAME="cluster-name"
HIGH_SVC_NAME="svc-high-priority"
LOW_SVC_NAME="svc-low-priority"
TOTAL_DESIRED_COUNT=31

# desired count
HIGH_DESIRED_COUNT=$(aws ecs describe-services \
--cluster $CLUSTER_NAME \
--service $HIGH_SVC_NAME \
--query "services[0].desiredCount")
echo $HIGH_DESIRED_COUNT
LOW_MAX_CAPACITY=$((TOTAL_DESIRED_COUNT-HIGH_DESIRED_COUNT))
        
SETTED_LOW_MAX_CAPACITY=$(aws application-autoscaling describe-scalable-targets \
        --service-namespace ecs \
        --resource-id service/$CLUSTER_NAME/$LOW_SVC_NAME \
        --scalable-dimension ecs:service:DesiredCount \
        --query "ScalableTargets[0].MaxCapacity")

if [ $((SETTED_LOW_MAX_CAPACITY)) -eq $LOW_MAX_CAPACITY ] ; then
	echo low already $SETTED_LOW_MAX_CAPACITY
else
	aws application-autoscaling register-scalable-target \
        --service-namespace ecs \
        --resource-id service/$CLUSTER_NAME/$LOW_SVC_NAME \
        --scalable-dimension ecs:service:DesiredCount \
        --min-capacity 1 \
        --max-capacity $LOW_MAX_CAPACITY

    echo "Waiting for scalable target to be updated..."
    for i in {1..10}; do
      CURRENT_MAX=$(aws application-autoscaling describe-scalable-targets \
        --service-namespace ecs \
        --resource-id service/$CLUSTER_NAME/$LOW_SVC_NAME \
        --scalable-dimension ecs:service:DesiredCount \
        --query "ScalableTargets[0].MaxCapacity" \
        --output text)
    
      if [ "$CURRENT_MAX" -eq "$LOW_MAX_CAPACITY" ]; then
        echo "Scalable target updated."
        break
      fi
      sleep 2
    done
    
    aws ecs update-service \
      --cluster $CLUSTER_NAME \
      --service $LOW_SVC_NAME \
      --desired-count $LOW_MAX_CAPACITY
fi