카테고리 없음

[Lambda] 업무시간 외 EKS WorkerNode Stop/Start

김붕어87 2025. 4. 28. 16:32
반응형

개요
DEV환경은 업무시간에만 사용하는 테스트 환경입니다.
업무시간(09:00 ~ 18:00) 외 모든 리소스를 Stop하고 업무시간에는 모든 리소스를 Start 해서 요금을 줄입니다.

업무시간 : 09:00 ~ 18:00 (총 9시간)
업무시간 외 : 24시간 - 업무시간 (총 15시간) 

1DAY : 업무시간 외 Stop을 하면 하루에 15시간 요금을 줄일 수 있습니다.
365DAY : 15 * 365 = 5475시간 ( 5475시간 / 24시간 = 228.125일)
1년 기준으로 하면 228일 요금을 줄일 수 있습니다.

 

 

1. 요금을 줄일 수 있는 리소스

  • EC2
  • RDS DB
  • WorkerNode
  • Fargate 

 

2. 요금을 줄이는 스케쥴링 방식

Stop & Start 스케쥴링은 여러 방식이 있습니다.

이 글에서는 Lambda + EventBrige 방식으로 진행합니다.

 

ex)

EventBridge Rule : 09:00시 -> Start Fargate Lambda 실행

EventBridge Rule : 18:00시 -> Stop Fargate Lambda 실행

 

 

 

 

3. WorkerNode 스케쥴링

3-1. IAM Role 생성 

[ Lambda에서 사용할 Role Policy 생성 ]

Lambda 함수에서 WorkerNode Stop & Start 권한 넣기

 

AWS Consoel -> IAM -> Policy -> policy 생성

Policy Name : dev-lambda-ec2-Policy

{
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Action": [
                "ec2:Start*",
                "ec2:Stop*",
                "autoscaling:UpdateAutoScalingGroup",
                "autoscaling:DescribeAutoScalingGroups"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}

 

 

 

AWS Consoel -> IAM -> Role -> Role 생성

Role Name : dev-lambda-schedule-role

Policy Attach : dev-lambda-ec2-Policy

 

 

[ EventBridge에서 사용할 Role & Policy 생성 ]

EventBridge에서 Lambda 함수를 실행할 권한 넣기

AWS Consoel -> IAM -> Policy -> policy 생성

Policy Name : dev-Amazon-EventBridge-Scheduler-Execution-Policy

{
    "Statement": [
        {
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:lambda:ap-northeast-2:xxx:function:StartEKSWorkerNode:*",
                "arn:aws:lambda:ap-northeast-2:xxx:function:StartEKSWorkerNode",
                "arn:aws:lambda:ap-northeast-2:xxx:function:StopEKSWorkerNode:*",
                "arn:aws:lambda:ap-northeast-2:xxx:function:StopEKSWorkerNode"
            ]
        }
    ],
    "Version": "2012-10-17"
}

 

AWS Consoel -> IAM -> Role -> Role 생성

Role Name : dev-Amazon_EventBridge_Scheduler_LAMBDA_role

Policy Attach : dev-Amazon-EventBridge-Scheduler-Execution-Policy

 

 

3-2. Lambda 함수 생성 

 

  • StopEKSWokrNode Lambda 함수 만들기

AWS Console -> Lambda -> 함수 -> 함수 생성 

함수 이름 : StopEKSWokrNode

런타임 : Python 3.9

기본 실행 역할 변경 -> 실행 역할 : 기존 역할 사용 클릭

기존 역할 : dev-lambda-schedule-role 클릭

함수 생성 

 

코드 소스

import boto3

asg_client = boto3.client('autoscaling')

def lambda_handler(event, context):
    try:
        # 모든 ASG 가져오기
        paginator = asg_client.get_paginator('describe_auto_scaling_groups')
        asgs = []
        for page in paginator.paginate():
            asgs.extend(page['AutoScalingGroups'])

        # eks:nodegroup-name 태그가 있는 ASG만 필터링
        target_asgs = []
        for asg in asgs:
            for tag in asg.get('Tags', []):
                if tag['Key'] == 'eks:nodegroup-name':
                    target_asgs.append(asg['AutoScalingGroupName'])
                    break  # 하나라도 있으면 이 ASG는 타겟이니까 추가하고 다음으로

        print(f"Target ASGs to update: {target_asgs}")

        # 타겟 ASG들의 DesiredCapacity, MinSize, MaxSize를 0으로 변경
        for asg_name in target_asgs:
            response = asg_client.update_auto_scaling_group(
                AutoScalingGroupName=asg_name,
                DesiredCapacity=0,
                MinSize=0,
                MaxSize=0
            )
            print(f"Updated ASG {asg_name}: {response}")

    except Exception as e:
        print(f"Error occurred: {e}")
        raise e

    return {
        'statusCode': 200,
        'body': f"Successfully updated ASGs: {target_asgs}"
    }

 

Deploy 코스 업로드

TEST 실행 

 

AWS -> AWS CloudTrail -> 이벤트 기록  클릭

속성 조회 : 이벤트 이름

값 : StopEKSWorkerNode

Lambda가 ASG stop되었는지 감사로그 확인 가능

 

  • StartEKSWokrNode Lambda 함수 만들기

AWS Console -> Lambda -> 함수 -> 함수 생성 

함수 이름 : StartEKSWorkerNode

런타임 : Python 3.9

기본 실행 역할 변경 -> 실행 역할 : 기존 역할 사용 클릭

기존 역할 : dev-lambda-schedule-role 클릭

함수 생성 

 

코드 소스

import boto3

asg_client = boto3.client('autoscaling')

def lambda_handler(event, context):
    try:
        # 모든 ASG 가져오기
        paginator = asg_client.get_paginator('describe_auto_scaling_groups')
        asgs = []
        for page in paginator.paginate():
            asgs.extend(page['AutoScalingGroups'])

        # eks:nodegroup-name 태그가 있는 ASG만 필터링
        target_asgs = []
        for asg in asgs:
            for tag in asg.get('Tags', []):
                if tag['Key'] == 'eks:nodegroup-name':
                    target_asgs.append(asg['AutoScalingGroupName'])
                    break

        print(f"Target ASGs to update: {target_asgs}")

        # 타겟 ASG들의 DesiredCapacity, MinSize, MaxSize를 2로 고정
        for asg_name in target_asgs:
            response = asg_client.update_auto_scaling_group(
                AutoScalingGroupName=asg_name,
                DesiredCapacity=2,
                MinSize=2,
                MaxSize=2
            )
            print(f"Updated ASG {asg_name}: {response}")

    except Exception as e:
        print(f"Error occurred: {e}")
        raise e

    return {
        'statusCode': 200,
        'body': f"Successfully updated ASGs: {target_asgs}"
    }

 

Deploy 코스 업로드

TEST 실행 

 

 

 

 

3-1. EventBridge 생성 

AWS Console -> Amazon EventBridge -> 일정 -> 일정 생성 

일정 이름 : StopEKSWorkerNode

설명 : Scheduling server off outside of business hours

일정 그룹 : 선택

일정 패턴 : 반복 일정 선택

시간대 : (UTC+09:00) Asia/Seoul)

일정 유형 : Cron 기반 일정

Cron 표현식 : 0 18 ? * MON-FRI *

유연한 기간 : 꺼짐

 

대상 세부 정보 : AWS Lambda 선택

Lambda 함수 : StopEKSWorkerNode 선택 

 

일정 완료 후 작업 : NONE

재시도 정책 : No

DLQ : 없음

 

기존 역할 사용 : dev-Amazon_EventBridge_Scheduler_LAMBDA_role 선택

 

반응형