본문 바로가기

개발/DevOps&SRE

Github Action을 Cloud Function처럼 써서 서버 비용 절약하기

1. Intro
2. Trade-Off
3. 필요환경
    - NCP 서버 셋팅
    - nCloud API 키 발급
    - nCloud API 문서

4. Github Action 워크플로우 설정

 

Intro

 

최근 진행 중인 토이 프로젝트에서 성능&부하 테스트를 위해 nGrinder를 구축했습니다. 

Naver Cloud Platform(이하 NCP)에서 지원받은 크레딧으로 클라우드에 서버를 구축했습니다. 

 

nGrinder처럼 24/7 서비스가 아니라면 필요한 시간에만 사용해서 비용을 절감할 필요가 있습니다...

NCP 콘솔에서 수동으로 서버 정지, 시작을 하면 되지만 매일매일 해야 하는 불편함과

혹시라도 까먹었을 시 서버 비용이 부과될 것입니다.

 

서버 시작, 정지를 자동화할 방법을 생각했고 추가 비용 없이 해결 가능한 방법으로

Github Action 워크플로우 이벤트 트리거 +  nCloud API 중 클라우드 서버 시작, 중지를 조합해 

서버가 필요한 시간에만 자동으로 운영되도록 해줬습니다. 

 

그 결과 서버를 24시간 중 6시간만 사용해 서버 비용을 1/4로 줄였고, 아낀 크레딧은 다른 리소스에 사용했습니다. 

비용으로 따지면 월 13만원 짜리 서버를 하루 6시간씩만 사용하면 대략 월 32,500원에 사용할 수 있습니다! 

 

(NCP는 서버를 중지해도 기본 디스크 요금은 그대로 청구된다고 하니 참고하세요 / 최대 중지 일수도 존재합니다!)

Trade Off

 

운영해 보니 고려해야 할 Trade Off가 존재했습니다. 

1. 정확한 시간에 작동하지 않는 스케줄링

 

공식문서에도 관련된 설명이 있습니다. 저도 실제로 8분 정도 늦게 트리거 된 것을 확인했습니다.

Github Action으로 간편하게 스케줄러를 만들 수 있는 장점이 있는 대신 정확한 시간에 트리거는 포기해야합니다. 

 

필요 환경

 

1. Github Action

2. NCP 서버 / 어플리케이션 Docker 컨테이너로 띄우기 

3. nCloud API를 사용하기 위한 access key, secret key 발급

4. nCloud API 문서

 

NCP 서버 셋팅

 

- 서버 비용 청구 방법을 월이 아닌 시간당 계산으로 변경했습니다. 

- 어플리케이션을 Docker 컨테이너로 띄우고 --restart=always 옵션을 적용해야 서버가 중지됐다가 재실행되어도 어플리케이션이 자동으로 실행됩니다.

- 서버가 내렸다 올라갔다 반복하기 때문에 컨테이너에서 영구 저장되어야 하는 데이터는 반드시 호스트 디렉토리와 바인딩해두셔야 합니다. 

nCloud API 키 발급

 

마이페이지 - 인증키 관리 탭에서 발급받습니다. 

 

nCloud API 문서

 

문서 링크 : https://api.ncloud-docs.com/docs/common-ncpapi

 

NCP API 문서를 참고하실 때 반드시 주의해야 할 사항은 NCP는 국산이라 일반용, 공공기관용, 금융용 3가지로 나뉘어있고, 문서도 각각 존재합니다. 저는 공공기관용 문서를 참고해 API요청을 테스트하는 삽질을 했습니다;;

 

아무튼 사용할 nCloud API는 서버 중지, 시작 기능을 제공하는 Server API입니다. 

 

1. 기본 API

기본 API 탭에서 signature 생성 예제 코드와 API 요청 도메인을 확인합니다. 

 

 

 

 

2. Compute -> Server

Compute 탭 -> Server에 있는 API를 사용합니다. 

- startServerInstances : 중지 상태의 서버 인스턴스를 시작합니다. 

- stopServerInstances : 실행 상태의 서버 인스턴스를 중지합니다. 

 

 

 

 

 

 

Github Action 워크플로우 작성

 

 

1. github action 워크플로우 작성 - on.schedule

 

github action workflow를 트리거하는 이벤트를 설정할 수 있는데 그중 schedule 이 있습니다. 

cron 표현식으로 특정 시간에 워크플로우가 트리거되로독 지원하고 있습니다. 

 

이것을 활용해 특정 시간에 서버 시작, 중지하는 워크플로우를 만들어 줍니다. 

저는 매일 오후 13시에 워크플로우가 실행되게 설정했습니다. 똑같이 서버 중지용 워크플로우를 작성해 줍니다. 

 

2. jobs.<job>.environment

 

nCloud API를 요청하기 위해 필요한 시크릿이나 변수를 미리 셋팅합니다. 

github action은 환경별로 secrets과 변수를 설정할 수 있습니다. 저는 NCP 서버를 운영 서버로 사용하고 있어

운영용 환경에 필요한 시크릿값들을 셋팅해 두었습니다. 

 

3. API 요청 스크립트 실행

 

제 경우는 API 요청 코드를 워크플로우 job에서 쉡 스크립트 파일로 실행되게 변경했습니다. 

다른 언어로 작성하셔도 됩니다. 저는 API문서에 있는 예제코드를 활용해 작성했습니다. 아래 참고해 주세요

 

#!/bin/bash
function makeSignature() {

	nl=$'\\n'
	
    # signature 생성에 필요한 변수 설정
    TIMESTAMP=$(echo $(($(date +%s%N)/1000000))) # 주의 : 시그니처에 사용된 timestamp와 헤더에 포함한 timestamp는 동일한 값이어야 합니다. 
    ACCESSKEY=$NCP_ACCESS_KEY # access key
    SECRETKEY=$NCP_SECRET_KEY # secrete key
    NCP_SERVER_API_PATH=$API_PATH # server api path
    NGRINDER_AGENT=$NGRINDER_AGENT_INSTANCE_ID # 서버 시작요청할 인스턴스 id 1
    NGRINDER_CONTROLLER=$NGRINDER_CONTROLLER_INSTANCE_ID # 서버 시작요청할 인스턴스 id 2

    METHOD="GET"
    URI="/server/v2/$NCP_SERVER_API_PATH?serverInstanceNoList.1=$NGRINDER_AGENT&serverInstanceNoList.2=$NGRINDER_CONTROLLER"

    SIG="$METHOD"' '"$URI"${nl}
    SIG+="$TIMESTAMP"${nl}
    SIG+="$ACCESSKEY"

    # signature 설정
    SIGNATURE=$(echo -n -e "$SIG"|iconv -t utf8 |openssl dgst -sha256 -hmac $SECRETKEY -binary|openssl enc -base64)

    # api 요청 & !! 주의 : nCloud Server API 응답 메세지 스턴스 정보가 모두 포함되기 때문에 전문 출력이 아닌 특정 문자열만 출력되도록 변경합니다. 
    curl -s 'https://ncloud.apigw.ntruss.com'$URI \
        --header "Content-type:application/json" \
        --header "x-ncp-apigw-timestamp:$TIMESTAMP" \
        --header "x-ncp-iam-access-key:$ACCESSKEY" \
        --header "x-ncp-apigw-signature-v2:$SIGNATURE | sed -n 's/.*<returnCode>\(.*\)<\/returnCode>.*/\1/p'"

}

makeSignature