Browsing Tag

네이버 클라우드 플랫폼

NCP

[NCP] 네이버 클라우드에서 비용 모니터링 설정 및 알림 받기

안녕하세요. ManVSCloud 김수현입니다.

클라우드를 사용하다보면 비용에 대한 고민이 빠질 수 없습니다.

계정 탈취로 인한 비용 폭탄뿐만 아니라 학생 및 취준생들이 학습 용도로 실습 후 리소스를 삭제하는 것을 깜빡하여 과금으로 이어지는 경우가 잦게 발생합니다.

이러한 문제로 인해 타클라우드의 서적이나 교육에서도 비용 모니터링에 대한 안내나 리소스 삭제를 상당히 강조하고 있으며 네이버 클라우드 플랫폼에서도 동일하게 의도하지 않은 과금을 막기 위해 비용 모니터링은 반드시 필수로 적용해야할 부분입니다.

하지만 현재까지 네이버 클라우드에서 비용 모니터링을 설정하는 방법에 대한 서적이나 블로그 포스팅은 발견하지 못했습니다.

그러므로 오늘은 네이버 클라우드에서 청구 비용 모니터링을 생성하고 알람을 받는 방법에 대해 포스팅하고자 합니다.

이 포스팅에서 작성될 비용 모니터링의 플로우는 위 그림과 같습니다.

Cloud Insight에는 계정이 사용한 리소스의 비용을 모니터링 할 수 있는 지표가 없습니다.
그러므로 청구 비용에 대한 Metric 생성 및 데이터를 Cloud Insight로 보내주는 작업이 필요합니다.


How?

먼저 청구 비용에 대한 데이터를 보내는 작업은 Cloud Functions을 사용할 것입니다.
Cloud Functions은 네이버 클라우드의 Serverless 상품입니다.
서버 관리나 별도의 프로비저닝에 대한 부담 없이 코드가 실행된 만큼만 비용이 발생합니다.

또한 Cloud Insight로 주기적인 데이터 전송이 필요한데 Cloud Functions의 Trigger는 cron을 제공하므로 원하는 주기에 맞춰서 데이터 전송이 가능합니다.

물론 Server에서 이러한 작업을 하는 것도 가능하지만 오직 청구 비용의 데이터를 전송하기 위해 Server를 생성하는 것은 상당히 비용 효율적이지 못한 선택입니다.

그렇다면 청구 비용 데이터를 Cloud Insight로 보낸다고 하였는데 어디로 보내는가?

바로 Cloud Insight의 Custom Schema를 이용합니다.

Custom Schema는 CW_KEY를 생성할 수 있습니다.
(CW_KEY : Schema를 구분하기 위한 key로 데이터 전송 및 조회에 사용)

또한 Custom Schema를 생성 시 데이터를 수집할 대상 정보인 ID Dimension와 Metric을 생성해줄 수 있습니다.

즉, Cloud Functions은 Custom Schema에서 생성된 CW_KEY를 이용하여 Dimension 및 Metric 데이터를 Cloud Insight로 전송하고 수집된 데이터를 이용하여 Dashboard 생성, Event Rule 등을 이용하여 모니터링이 가능하는 것입니다.


A to Z

해당 A to Z 과정은 VPC 및 Subnet 등 네트워크 구성이 완료되어있다고 가정하고 진행합니다.

네트워크 구성 과정은 아래 URL을 통해 실습 후 진행 부탁드립니다.

1. Custom Schema 생성

1) 로그인 및 콘솔 접속
2) Cloud Insight (Monitoring) – Configuration – Custom Schema 클릭
3) [+ Custom Schema 생성] 클릭
4) 아래 값과 같이 설정(Product Type, Description 등 자유롭게 기입 가능)

# 기본 정보
CW_KEY (자동 생성됨)
Product Type : Account-Billing-Costs

# Schema 설정
· 수집 대상 설정
ID Dimension : memberId
Description : Schema for sending account billing cost data
Data Type : STRING

· Metric
Metric : total_cost
Description : Total cost per month
Data Type : INTEGER
Aggregation Cycle : Min1, Min5, Min30, Day1
Aggregation : MAX, COUNT, MIN, SUM, AVG
Unit : won

위 값과 동일하게 입력한 뒤 [생성]을 클릭하게 되면 Custom Schema가 생성됩니다.
생성된 Custom Schema를 클릭하여 [데이터 전송 예시]도 확인할 수 있습니다.

<전송할 Sample Data 형식>

{
	"cw_key": "777777777777777777",
	"data": {
		"memberId": "xgltddiwte8",
		"total_cost": 331
	}
}

위와 같은 JSON 형태로 Cloud Function에서 데이터를 전송해야합니다.
data 부분의 memberId는 계정명, total_cost 부분은 청구 비용이 들어가면 됩니다.

2. Cloud Functions으로 청구 비용 데이터 전송

1) Cloud Function 클릭 및 구독
2) Cloud Function – Trigger 클릭
3) [+ Trigger 생성] 클릭

# 트리거 종류 선택
트리거 종류 : cron

# 트리거 기본 정보
이름 : CloudInsight-Send-Data-Trigger
설명 : Cloud Insight로 Metric Data 전송용 트리거
디폴트 파라미터 (JSON) : – (공란)

# 트리거 기본 정보
상세 실행 옵션 : */1 * * * *

– 액션은 연결하지 않고 생성합니다. Trigger는 액션 생성 시 연결해주겠습니다.

4) Cloud Function – Action 클릭
5) [+ Package 생성] 클릭
패키지 이름 : CloudInsight-Send-Data-Pkg
패키지 설명 : Cloud Insight로 Custom Metric Data를 전송하기 위한 Cloud Function 패키지
디폴트 파라미터 : REGION, DMN_CD, CW_API_URL은 리전별, 민간용, 금융기관용, 공공기관용에따라 변경이 필요하니 참고하시기 바랍니다.
ex) DMN_CD : 민간용(PUB), 금융기관용(FIN), 공공기관용(GOV)

{"REGION":"KR","DMN_CD":"PUB","CW_API_URL":"https://cw.apigw.ntruss.com","CW_SENDDATA_API":"/cw_collector/real/data"}

6) [+ Action 생성] 클릭
7) Trigger 추가 후 [다음]

# 트리거 기본 정보
트리거 종류 : cron
이름 : CloudInsight-Send-Data-Trigger

8) Action 세부 내용 입력 후 [생성]
# 기본 정보
패키지 : CloudInsight-Send-Data-Pkg
타입 : 기본
이름 : CloudInsight-Send-Data-Pkg/Account-Cost-Action
설명 : 계정 비용에 대한 데이터(Custom Metric)를 Cloud Insight로 전송하는 Action

# 소스코드
언어 : Python 3.7
타입 : 코드

(코드는 더욱 간결하고 좋게 변경하실 수 있으면 변경하셔도 됩니다?
저는 아무래도 개발자가 아니다보니 동작하게만 해둔거라…)

import hashlib
import hmac
import base64
import requests
import time
import json
from datetime import datetime

def tstamp():
    ts = int(time.time() * 1000)
    ts = str(ts)
    
    return ts
    

def lookup_period():
    now = datetime.now()
    period = now.strftime("%Y%m")
    period = str(period)
    
    return period


def useAmount(args):
    
    timestamp = tstamp()
    per = lookup_period()
    
    access_key = args['NCLOUD_ACCESS_KEY']
    secret_key = args['NCLOUD_SECRET_KEY']
    secret_key = bytes(secret_key, 'UTF-8')
    
    method = "GET"

    uri = args['BILL_COSTLIST_API'] + "?startMonth=" + per + "&endMonth=" + per + "&responseFormatType=json"

    message = method + " " + uri + "\n" + timestamp + "\n" + access_key
    message = bytes(message, 'UTF-8')
    signingKey = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())


    http_header = {
            'x-ncp-apigw-signature-v2': signingKey,
            'x-ncp-apigw-timestamp': timestamp,
            'x-ncp-iam-access-key': access_key,
            'x-ncp-dmn_cd': args['DMN_CD']
            }



    response = requests.get(args['BILLING_API_URL'] + uri, headers=http_header)

    data = json.loads(response.text)
    data = data.get("getDemandCostListResponse")

    for cost in data['demandCostList']:
            useAmount = cost['useAmount']
            useAmount = str(useAmount)

    return useAmount
    
    
def main(args):
    
    timestamp = tstamp()
    amount = useAmount(args)
    api_server = args['CW_API_URL']
    uri = args['CW_SENDDATA_API']
    bill_key = args['BILL_CW_KEY']
    mem_id = args['MEM_ID']
    
    access_key = args['NCLOUD_ACCESS_KEY']
    secret_key = args['NCLOUD_SECRET_KEY']
    secret_key = bytes(secret_key, 'UTF-8')
    
    method = "POST"
    
    message = method + " " + uri + "\n" + timestamp + "\n" + access_key
    message = bytes(message, 'UTF-8')
    signingKey = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())
    
    http_header = {
            'x-ncp-apigw-signature-v2': signingKey,
            'x-ncp-apigw-timestamp': timestamp,
            'x-ncp-iam-access-key': access_key
            }
            
    payload = {
            "cw_key": bill_key,
            "data": {
            "total_cost": amount,
            "memberNo": mem_id
            }
        }
    
    response = requests.post(api_server + uri, headers=http_header, json=payload)
    data = json.loads(response.text)
    
    return data

# VPC 연결 정보
VPC : VPC 선택
Subnet : Subnet 선택
(현재는 KR-2 Zone에서 생성한 Subnet만 연결할 수 있습니다.)

# 옵션 설정
Main 함수 : main
액션 메모리 : 128MB
액션 Timeout : 60000
웹 액션 설정 : False


# 디폴트 파라미터
아래 파라미터에서 변경해주어야할 부분은 NCLOUD_ACCESS_KEY, NCLOUD_SECRET_KEY, BILL_CW_KEY, MEM_ID 총 4가지입니다.
(BILLING_API_URL 역시 금융기관용, 공공기관용일 경우 변경이 필요합니다.)

  • NCLOUD_ACCESS_KEY와 NCLOUD_SECRET_KEY는 계정의 인증키를 입력
  • BILL_CW_KEY는 위에서 Custom Schema 생성 후 발급된 cw_key를 입력
  • MEM_ID는 자신의 계정을 입력 (자유롭게)
{"BILLING_API_URL":"https://billingapi.apigw.ntruss.com","NCLOUD_ACCESS_KEY":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","BILL_CW_KEY":"777777777777777777","NCLOUD_SECRET_KEY":"ABCDEFGHIJKLMNOPQRSTUVWXYZ","BILL_COSTLIST_API":"/billing/v1/cost/getDemandCostList","MEM_ID":"example@naver.com"}

Action 생성 후 생성된 Action의 모니터링을 선택하여 위 그림과 같이 정상적으로 Code가 동작하는지 확인할 수 있습니다.

3. Event Rule 생성

  • Cloud Insight – Template 생성없이 Event Rule로 간략하게 포스팅하였습니다.

1) Cloud Insight(Monitoring) Configuration – Event Rule 클릭
2) [+ Event Rules 생성] 클릭
3) 아래를 참고하여 Event Rule 생성

# 감시 상품 선택
– 생성한 Custom Schema의 Product Type 선택 (Account-Billing-Costs)

# 감시 대상 설정
[전체 보기] 클릭 후 MEM_ID에 입력한 계정 선택

# 감시 항목 설정
[전체 보기] 클릭 후 total_cost 선택
레벨 : Critical
조건 : >= 300000
(청구 비용이 30만원 이상 발생 시 알림 발생)
집약 방법 : AVG
지속 시간 : 1 (min)

# 액션 설정
알림 메시지 발송 : 통보 대상자 선택

# 기본정보
규칙 이름 : Account-Billing-Cost-Event-Rule
설명 : 계정 청구 비용 이벤트 발생 시 알림을 위한 룰 (30만원 이상 사용 시 알림)

Dashboard에서 비용을 확인할 수도 있고,
아래와 같이 알림도 받을 수 있습니다.


Question

Q1. Cloud Insight에 대한 비용이 발생하지 않나요?

Answer : Cloud Insight 서비스는 현재 Beta 기간으로 한시적 무료 제공이 되고 있습니다.
또한 한시적 무료 제공이 끝나더라도 Custom Metric 수집 횟수에 대한 과금 구간은 무료에 해당된다고 볼 수 있습니다.

Cloud Insight 서비스의 무료 구간은 다음과 같습니다.

서비스구간기준
Dashboards3건 이하대시보드 수
Basic Metric전 구간 동일수집 횟수
Extended Metric432,000건 이하수집 횟수
Custom Metric432,000건 이하수집 횟수
Read API Calls1,000,000건 이하호출 수
Write API Calls1,000,000건 이하호출 수
Event Rule10건 이하Event Rule 수
Event SMS50건 이하발송 건수
Email Notifications1,000건 이하발송 건수

Q2. Cloud Functions에 대한 비용이 발생하지 않을까요?

Answer : Cloud Functions 역시 무료 구간이 있으며 비용이 크게 발생하지 않습니다.
Cloud Functions의 무료 구간은 다음과 같습니다.

구분사용량 구간기준
(실행) 요청1,000,000 이하1,000,000건
(컴퓨팅 사용) 소요시간400,000 이하GB-초

위 Cloud Funtions에서 생성한 기준으로 계산을 해봅시다.
(정상 작동 시 평균 실행 시간은 100~200ms 가 발생합니다.)

  • 평균 실행 시간 : 100~200 (밀리초)
  • 액션 메모리 : 128 (MB)
  • 월 요청 수 : 60(분) x 24(시간) x 30(일) = 43,200(회)

# 컴퓨팅 사용
· 총 컴퓨팅 시간(평균 실행 시간 * 월 요청수) : 200(밀리초) x 43,200(회)
= 8,640,000(밀리초) = 8,640(GB-초)

무료 구간(월) : 400,000(GB-초) 이므로 과금이 발생하지 않습니다.

# 실행 요청
· 월 요청 수 : 43,200(회)

무료 구간(월) : 1,000,000 (회)으로 과금이 발생하지 않습니다.

즉, 이 포스팅의 ‘청구 비용 모니터링’을 위해 Cloud Functions을 생성하여도
컴퓨팅 사용 비용 0원, 실행 요청 비용 0원이 발생합니다.

Q3. 어떤 API를 사용하였나요?

Answer : 네이버 클라우드에서 제공하는 getDemandCostList와 SendData를 사용하였습니다.


Personal Comments

이 포스팅으로 인해 의도하지 않은 비용 발생을 줄이고 네이버 클라우드를 사용하는 유저들이 이러한 문제로 Bad Experience가 생기지 않길 바랍니다.

특히 네이버 클라우드를 시작하는 학생들과 취준생들에게는 더욱 이 포스팅이 알려졌으면 합니다.

네이버 클라우드를 시작하게되면 VPC 생성 후 Server를 생성하거나 다른 서비스들 먼저 사용해보고 싶겠지만 잠시 미뤄두고 비용 모니터링 알림부터 구축하는 것이 예상치못한 과금을 막는 방법입니다.

p.s. 지속적인 달러 폭등… 네이버 클라우드 플랫폼은 더욱 비용 효율적인 클라우드가 되었습니다?
비용 모니터링 생성 후 마음껏 사용합시다!

긴 글 읽어주셔서 감사합니다.