Cloud 스케줄러로 Compute 인스턴스 예약

이 가이드에서는 Cloud 스케줄러와 Cloud Functions를 사용하여 Compute Engine 인스턴스를 정기적으로 자동으로 시작하고 중지하는 방법을 보여줍니다.

목표

  • Cloud Functions를 사용하여 Compute Engine 인스턴스를 시작하고 중지하는 함수 집합을 작성하고 배포합니다.
  • Cloud 스케줄러를 사용하여 인스턴스가 일반적인 업무 시간인 월~금 09:00~17:00에 실행되도록 예약하는 작업 집합을 작성합니다.

비용

이 가이드에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

  • Cloud 스케줄러
  • Cloud Functions
  • Cloud Pub/Sub
  • Compute Engine

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용합니다. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

  1. Cloud 스케줄러의 환경을 설정합니다.

    환경 설정하기

  2. Cloud Functions, Cloud Pub/Sub, Compute Engine API를 사용 설정합니다.

    API 사용 설정

애플리케이션 아키텍처

이 솔루션에는 다음과 같은 GCP 구성요소가 포함됩니다.

  1. Compute Engine 인스턴스: 정기적으로 실행하려고 하는 Compute Engine 인스턴스
  2. Cloud Functions 함수: 예약하려는 인스턴스를 시작하고 중지하는 함수
  3. Cloud Pub/Sub 메시지: 시작 및 중지 이벤트마다 전송되거나 수신되는 메시지
  4. Cloud 스케줄러 작업: 정해진 일정에 따라 호출을 실행하여 인스턴스를 시작하거나 중지하는 작업

Cloud 스케줄러를 이용하여 Cloud Pub/Sub를 통해 Compute Engine 인스턴스를 예약하는 과정을 보여주는 시스템 아키텍처 다이어그램

위치 요구사항

일부 구성요소는 특정 리전에서만 지원됩니다.

  1. Compute Engine 인스턴스: Compute Engine 리전 및 영역 아래에 나열된 모든 리전에서 지원됩니다.
  2. Cloud Functions 함수: Cloud Functions 위치에 나열된 리전에서 지원됩니다.
  3. Cloud Pub/Sub 메시지: Cloud Pub/Sub가 글로벌 서비스이므로 전 세계에서 지원됩니다.
  4. Cloud 스케줄러 작업: 모든 현재 App Engine 위치에서 지원됩니다.

권장사항: Cloud Pub/Sub 대신에 HTTP는 어떤가요?

Cloud Pub/Sub 트리거 대신에 Cloud Functions HTTP 트리거를 사용하여 이 아키텍처를 간소화하는 것이 좋습니다.

Cloud 스케줄러를 이용하여 HTTP를 통해 Compute Engine 인스턴스를 예약하는 과정을 보여주는 시스템 아키텍처 다이어그램

HTTP를 통해 예약할 경우 누구든지 Compute Engine 인스턴스를 예약할 수 있음을 보여주는 시스템 아키텍처 다이어그램

더 안전한 설정을 만들려면 Cloud Pub/Sub 함수를 사용하는 것이 좋습니다.

Compute Engine 인스턴스 설정

Console

  1. GCP Console에서 VM 인스턴스 페이지로 이동합니다.
    VM 인스턴스 페이지로 이동
  2. 인스턴스 만들기를 클릭합니다.
  3. 이름workday-instance로 설정합니다.
  4. 리전에서 us-west1을 선택합니다.
  5. 영역에서 us-west1-b를 선택합니다.
  6. 페이지 하단에 있는 만들기를 클릭합니다.

gcloud

gcloud compute instances create workday-instance \
    --network default \
    --zone us-west1-b

Cloud Pub/Sub로 Cloud Functions 함수 설정

함수 만들기 및 배포

Console

시작 함수를 만듭니다.

  1. GCP Console에서 Cloud Functions 페이지로 이동합니다.
    Cloud Functions 페이지로 이동.
  2. 함수 만들기를 클릭합니다.
  3. 이름startInstancePubSub로 설정합니다.
  4. 할당 메모리를 기본값으로 그대로 둡니다.
  5. 트리거에서 Cloud Pub/Sub를 선택합니다.
  6. 주제에서 Create new topic...을 선택합니다.
  7. 새 게시/구독 주제 대화상자가 나타납니다.
    1. 이름start-instance-event를 입력합니다.
    2. 만들기를 클릭하여 대화상자를 닫습니다.
  8. 런타임에서 Node.js 6을 선택합니다.
  9. 코드 텍스트 블록 위에서 index.js 탭을 선택합니다.
  10. 시작 코드를 다음 코드로 바꿉니다.

    const Buffer = require('safe-buffer').Buffer;
    const Compute = require('@google-cloud/compute');
    const compute = new Compute();
    
    /**
     * Starts a Compute Engine instance.
     *
     * Expects a PubSub message with JSON-formatted event data containing the
     * following attributes:
     *  zone - the GCP zone the instance is located in.
     *  instance - the name of the instance.
     *
     * @param {!object} event Cloud Function PubSub message event.
     * @param {!object} callback Cloud Function PubSub callback indicating completion.
     */
    exports.startInstancePubSub = (event, callback) => {
      try {
        const pubsubMessage = event.data;
        const payload = _validatePayload(
          JSON.parse(Buffer.from(pubsubMessage.data, 'base64').toString())
        );
        compute
          .zone(payload.zone)
          .vm(payload.instance)
          .start()
          .then(data => {
            // Operation pending.
            const operation = data[0];
            return operation.promise();
          })
          .then(() => {
            // Operation complete. Instance successfully started.
            const message = 'Successfully started instance ' + payload.instance;
            console.log(message);
            callback(null, message);
          })
          .catch(err => {
            console.log(err);
            callback(err);
          });
      } catch (err) {
        console.log(err);
        callback(err);
      }
    };
    
    /**
     * Validates that a request payload contains the expected fields.
     *
     * @param {!object} payload the request payload to validate.
     * @returns {!object} the payload object.
     */
    function _validatePayload(payload) {
      if (!payload.zone) {
        throw new Error(`Attribute 'zone' missing from payload`);
      } else if (!payload.instance) {
        throw new Error(`Attribute 'instance' missing from payload`);
      }
      return payload;
    }
  11. 코드 텍스트 블록 위에서 package.json 탭을 선택합니다.

  12. 시작 코드를 다음 코드로 바꿉니다.

    {
      "name": "cloud-functions-schedule-instance",
      "version": "0.0.1",
      "private": true,
      "license": "Apache-2.0",
      "author": "Google Inc.",
      "repository": {
        "type": "git",
        "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
      },
      "engines": {
        "node": ">=8"
      },
      "scripts": {
        "test": "mocha test/*.test.js --timeout=20000"
      },
      "devDependencies": {
        "@google-cloud/nodejs-repo-tools": "^3.0.0",
        "mocha": "^5.2.0",
        "proxyquire": "^2.0.0",
        "sinon": "^7.0.0"
      },
      "dependencies": {
        "@google-cloud/compute": "^0.11.0",
        "safe-buffer": "^5.1.2"
      }
    }
    
  13. 실행할 함수startInstancePubSub를 입력합니다.

  14. 만들기를 클릭합니다.

중지 함수를 만듭니다.

  1. GCP Console의 Cloud Functions 페이지로 이동해야 합니다.
  2. 함수 만들기를 클릭합니다.
  3. 이름stopInstancePubSub로 설정합니다.
  4. 할당 메모리를 기본값으로 그대로 둡니다.
  5. 트리거에서 Cloud Pub/Sub를 선택합니다.
  6. 주제에서 Create new topic...을 선택합니다.
  7. 새 게시/구독 주제 대화상자가 나타납니다.
    1. 이름stop-instance-event를 입력합니다.
    2. 만들기를 클릭하여 대화상자를 닫습니다.
  8. 런타임에서 Node.js 6을 선택합니다.
  9. 코드 텍스트 블록 위에서 index.js 탭을 선택합니다.
  10. 시작 코드를 다음 코드로 바꿉니다.

    const Buffer = require('safe-buffer').Buffer;
    const Compute = require('@google-cloud/compute');
    const compute = new Compute();
    
    /**
     * Stops a Compute Engine instance.
     *
     * Expects a PubSub message with JSON-formatted event data containing the
     * following attributes:
     *  zone - the GCP zone the instance is located in.
     *  instance - the name of the instance.
     *
     * @param {!object} event Cloud Function PubSub message event.
     * @param {!object} callback Cloud Function PubSub callback indicating completion.
     */
    exports.stopInstancePubSub = (event, callback) => {
      try {
        const pubsubMessage = event.data;
        const payload = _validatePayload(
          JSON.parse(Buffer.from(pubsubMessage.data, 'base64').toString())
        );
        compute
          .zone(payload.zone)
          .vm(payload.instance)
          .stop()
          .then(data => {
            // Operation pending.
            const operation = data[0];
            return operation.promise();
          })
          .then(() => {
            // Operation complete. Instance successfully stopped.
            const message = 'Successfully stopped instance ' + payload.instance;
            console.log(message);
            callback(null, message);
          })
          .catch(err => {
            console.log(err);
            callback(err);
          });
      } catch (err) {
        console.log(err);
        callback(err);
      }
    };
    
    /**
     * Validates that a request payload contains the expected fields.
     *
     * @param {!object} payload the request payload to validate.
     * @returns {!object} the payload object.
     */
    function _validatePayload(payload) {
      if (!payload.zone) {
        throw new Error(`Attribute 'zone' missing from payload`);
      } else if (!payload.instance) {
        throw new Error(`Attribute 'instance' missing from payload`);
      }
      return payload;
    }
  11. 코드 텍스트 블록 위에서 package.json 탭을 선택합니다.

  12. 시작 코드를 다음 코드로 바꿉니다.

    {
      "name": "cloud-functions-schedule-instance",
      "version": "0.0.1",
      "private": true,
      "license": "Apache-2.0",
      "author": "Google Inc.",
      "repository": {
        "type": "git",
        "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
      },
      "engines": {
        "node": ">=8"
      },
      "scripts": {
        "test": "mocha test/*.test.js --timeout=20000"
      },
      "devDependencies": {
        "@google-cloud/nodejs-repo-tools": "^3.0.0",
        "mocha": "^5.2.0",
        "proxyquire": "^2.0.0",
        "sinon": "^7.0.0"
      },
      "dependencies": {
        "@google-cloud/compute": "^0.11.0",
        "safe-buffer": "^5.1.2"
      }
    }
    
  13. 실행할 함수stopInstancePubSub를 입력합니다.

  14. 만들기를 클릭합니다.

gcloud

Cloud Pub/Sub 주제를 만듭니다.

gcloud pubsub topics create start-instance-event
gcloud pubsub topics create stop-instance-event

코드 가져오기

  1. 코드를 다운로드합니다.

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    또는 zip 파일로 샘플을 다운로드하고 압축을 풀 수 있습니다.

  2. 해당 디렉토리로 이동합니다.

    cd nodejs-docs-samples/functions/scheduleinstance/
    

시작 및 중지 함수를 만듭니다.

nodejs-docs-samples/functions/scheduleinstance/ 디렉토리에 있어야 합니다.

gcloud functions deploy startInstancePubSub \
    --trigger-topic start-instance-event \
    --runtime nodejs6
gcloud functions deploy stopInstancePubSub \
    --trigger-topic stop-instance-event \
    --runtime nodejs6

(선택사항) 함수 작동 확인

Console

인스턴스 중지

  1. GCP Console에서 Cloud Functions 페이지로 이동합니다.
    Cloud Functions 페이지로 이동.
  2. stopInstancePubSub라는 함수를 클릭합니다.
  3. 다음과 같은 여러 개의 탭이 나타납니다. 일반, 트리거, 소스, 테스트. 테스트 탭을 클릭합니다.
  4. 트리거 이벤트에 다음을 입력합니다.

    {"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsImluc3RhbmNlIjoid29ya2RheS1pbnN0YW5jZSJ9Cg=="}
    

    • 이것은 {"zone":"us-west1-b", "instance":"workday-instance"}를 base64로 인코딩한 문자열입니다.

    • 문자열을 직접 인코딩하려면 온라인 base64 인코딩 툴을 자유롭게 사용해도 좋습니다.

  5. 함수 테스트 버튼을 클릭합니다.

  6. 실행이 완료되면 출력 밑에 Successfully stopped instance workday-instance가 출력됩니다. 실행이 완료되려면 최대 60초가 소요될 수 있습니다.

    • error: 'Error: function failed to load.'가 표시될 경우, 10초 또는 함수가 배포를 완료할 때까지 기다린 후 다시 시도하세요.

    • error: 'Error: function execution attempt timed out.'이 표시될 경우, 다음 단계로 이동하여 인스턴스가 종료되는 데 오래 걸리는지 확인합니다.

    • 실행이 완료되었지만 아무것도 표시되지 않는다면 시간이 초과되었을 것입니다. 다음 단계로 이동하여 인스턴스가 종료되는 데 오래 걸리는지 확인합니다.

  7. GCP Console에서 VM 인스턴스 페이지로 이동합니다.
    VM 인스턴스 페이지로 이동

  8. workday-instance라는 인스턴스의 이름 옆에 인스턴스가 중지되었음을 의미하는 회색 사각형이 있는지 확인합니다. 종료를 완료하는 데 최대 30초가 소요될 수 있습니다.

    • 완료가 안 되는 것처럼 보일 경우, 페이지 상단의 새로고침을 클릭해 보세요.

인스턴스 시작

  1. GCP Console에서 Cloud Functions 페이지로 이동합니다.
    Cloud Functions 페이지로 이동.
  2. startInstancePubSub라는 함수를 클릭합니다.
  3. 다음과 같은 여러 개의 탭이 나타납니다. 일반, 트리거, 소스, 테스트. 테스트 탭을 클릭합니다.
  4. 트리거 이벤트에 다음을 입력합니다.

    {"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsImluc3RhbmNlIjoid29ya2RheS1pbnN0YW5jZSJ9Cg=="}
    

    • 여기서도 마찬가지로 이것은 {"zone":"us-west1-b", "instance":"workday-instance"}를 base64로 인코딩한 문자열입니다.
  5. 함수 테스트 버튼을 클릭합니다.

  6. 실행이 완료되면 출력 밑에 Successfully started instance workday-instance가 출력됩니다.

  7. GCP Console에서 VM 인스턴스 페이지로 이동합니다.
    VM 인스턴스 페이지로 이동

  8. workday-instance라는 인스턴스의 이름 옆에 인스턴스가 실행되고 있음을 의미하는 녹색 체크 표시가 있는지 확인합니다. 시작을 완료하는 데 최대 30초가 소요될 수 있습니다.

gcloud

인스턴스 중지

  1. 인스턴스를 중지하는 함수를 호출합니다.

    gcloud functions call stopInstancePubSub \
        --data '{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsImluc3RhbmNlIjoid29ya2RheS1pbnN0YW5jZSJ9Cg=="}'
    
    • 이것은 {"zone":"us-west1-b", "instance":"workday-instance"}를 base64로 인코딩한 문자열입니다.

    • 문자열을 직접 인코딩하려면 필요한 툴을 자유롭게 사용해도 좋습니다. 아래는 base64 명령줄 도구를 사용한 예입니다.

      echo '{"zone":"us-west1-b", "instance":"workday-instance"}' | base64
      
      eyJ6b25lIjoidXMtd2VzdDEtYiIsImluc3RhbmNlIjoid29ya2RheS1pbnN0YW5jZSJ9Cg==
      

    함수가 완료되면 다음과 같이 표시됩니다.

    result: Successfully stopped instance workday-instance
    

    실행이 완료되려면 최대 60초가 소요될 수 있습니다.

    • 다음과 같은 오류가 표시될 경우:

      error: 'Error: function failed to load.`
      

      10초 또는 함수가 배포를 완료할 때까지 기다린 후 다시 시도하세요.

    • 다음과 같은 오류가 표시될 경우:

      error: `Error: function execution attempt timed out.`
      

      다음 단계로 이동하여 인스턴스가 종료되는 데 오래 걸리는지 확인합니다.

    • 아무 결과도 표시되지 않는 경우, 함수의 실행 시간이 초과되었을 것입니다. 다음 단계로 이동하여 인스턴스가 종료되는 데 오래 걸리는지 확인합니다.

  2. 인스턴스의 상태가 TERMINATED인지 확인합니다. 종료를 완료하는 데 최대 30초가 소요될 수 있습니다.

    gcloud compute instances describe workday-instance \
        --zone us-west1-b \
        | grep status
    
    status: TERMINATED
    

인스턴스 시작

  1. 인스턴스를 시작하는 함수를 호출합니다.

    gcloud functions call startInstancePubSub \
        --data '{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsImluc3RhbmNlIjoid29ya2RheS1pbnN0YW5jZSJ9Cg=="}'
    
    • 여기서도 마찬가지로 이것은 {"zone":"us-west1-b", "instance":"workday-instance"}를 base64로 인코딩한 문자열입니다.

    함수가 완료되면 다음과 같이 표시됩니다.

    result: Successfully started instance workday-instance
    
  2. 인스턴스의 상태가 RUNNING인지 확인합니다. 시작을 완료하는 데 최대 30초가 소요될 수 있습니다.

    gcloud compute instances describe workday-instance \
        --zone us-west1-b \
        | grep status
    
    status: RUNNING
    

Cloud Pub/Sub를 호출하는 Cloud 스케줄러 작업 설정

작업 만들기

Console

시작 작업을 만듭니다.

  1. GCP Console에서 Cloud 스케줄러 페이지로 이동합니다.
    Cloud 스케줄러 페이지로 이동.
  2. 작업 만들기를 클릭합니다.
  3. 이름startup-workday-instance로 설정합니다.
  4. 빈도0 9 * * 1-5를 입력합니다.
  5. 시간대에서, 원하는 국가와 시간대를 선택합니다. 이 예에서는 United StatesLos Angeles를 사용합니다.
  6. 대상에서 Pub/Sub를 선택합니다.
  7. 주제start-instance-event를 입력합니다.
  8. 페이로드에 다음을 입력합니다.
    {"zone":"us-west1-b","instance":"workday-instance"}
    
  9. 만들기를 클릭합니다.

중지 작업을 만듭니다.

  1. GCP Console의 Cloud Functions 페이지로 이동해야 합니다.
  2. 작업 만들기를 클릭합니다.
  3. 이름shutdown-workday-instance로 설정합니다.
  4. 빈도0 17 * * 1-5를 입력합니다.
  5. 시간대에서, 원하는 국가와 시간대를 선택합니다. 이 예에서는 United StatesLos Angeles를 사용합니다.
  6. 대상에서 Pub/Sub를 선택합니다.
  7. 주제stop-instance-event를 입력합니다.
  8. 페이로드에 다음을 입력합니다.
    {"zone":"us-west1-b","instance":"workday-instance"}
    
  9. 만들기를 클릭합니다.

gcloud

시작 작업을 만듭니다.

gcloud beta scheduler jobs create pubsub startup-workday-instance \
    --schedule '0 9 * * 1-5' \
    --topic start-instance-event \
    --message-body '{"zone":"us-west1-b","instance":"workday-instance"}' \
    --time-zone 'America/Los_Angeles'

중지 작업을 만듭니다.

gcloud beta scheduler jobs create pubsub shutdown-workday-instance \
    --schedule '0 17 * * 1-5' \
    --topic stop-instance-event \
    --message-body '{"zone":"us-west1-b","instance":"workday-instance"}' \
    --time-zone 'America/Los_Angeles'

(선택사항) 작업이 작동하는지 확인

Console

인스턴스 중지

  1. GCP Console에서 Cloud 스케줄러 페이지로 이동합니다.
    Cloud 스케줄러 페이지로 이동.
  2. shutdown-workday-instance라는 작업에서 페이지의 오른쪽 끝에 있는 지금 실행 버튼을 클릭합니다.
  3. GCP Console에서 VM 인스턴스 페이지로 이동합니다.
    VM 인스턴스 페이지로 이동
  4. workday-instance라는 인스턴스의 이름 옆에 인스턴스가 중지되었음을 의미하는 회색 사각형이 있는지 확인합니다. 종료를 완료하는 데 최대 30초가 소요될 수 있습니다.

인스턴스 시작

  1. GCP Console에서 Cloud 스케줄러 페이지로 이동합니다.
    Cloud 스케줄러 페이지로 이동.
  2. startup-workday-instance라는 작업에서 페이지의 오른쪽 끝에 있는 지금 실행 버튼을 클릭합니다.
  3. GCP Console에서 VM 인스턴스 페이지로 이동합니다.
    VM 인스턴스 페이지로 이동
  4. workday-instance라는 인스턴스의 이름 옆에 인스턴스가 실행되고 있음을 의미하는 녹색 체크 표시가 있는지 확인합니다. 시작을 완료하는 데 최대 30초가 소요될 수 있습니다.

gcloud

인스턴스 중지

  1. 인스턴스를 중지하는 스케줄러 작업을 실행합니다.

    gcloud beta scheduler jobs run shutdown-workday-instance
    
  2. 인스턴스의 상태가 TERMINATED인지 확인합니다. 종료를 완료하는 데 최대 30초가 소요될 수 있습니다.

    gcloud compute instances describe workday-instance \
        --zone us-west1-b \
        | grep status
    
    status: TERMINATED
    

인스턴스 시작

  1. 인스턴스를 시작하는 스케줄러 작업을 실행합니다.

    gcloud beta scheduler jobs run startup-workday-instance
    
  2. 인스턴스의 상태가 RUNNING인지 확인합니다. 시작을 완료하는 데 최대 30초가 소요될 수 있습니다.

    gcloud compute instances describe workday-instance \
        --zone us-west1-b \
        | grep status
    
    status: RUNNING
    

삭제

인스턴스 예약 가이드를 완료했으면 이후에 요금이 청구되지 않도록 GCP에서 만든 리소스를 삭제할 수 있습니다. 다음 섹션은 이러한 리소스를 삭제하거나 사용 중지하는 방법을 설명합니다.

Cloud 스케줄러 작업 삭제

  1. GCP Console에서 Cloud 스케줄러 페이지로 이동합니다.

    Cloud 스케줄러 페이지로 이동.

  2. 작업 옆에 있는 체크박스를 클릭합니다.

  3. 페이지 상단의 작업 삭제 버튼을 클릭하고 삭제를 확인합니다.

Cloud Pub/Sub 주제 삭제

  1. GCP Console에서 Cloud Pub/Sub 페이지로 이동합니다.

    Cloud Pub/Sub 페이지로 이동

  2. 주제 옆에 있는 체크박스를 클릭합니다.

  3. 페이지 상단의 삭제를 클릭하고 삭제를 확인합니다.

Cloud Functions 함수 삭제

  1. GCP Console에서 Cloud Functions 페이지로 이동합니다.

    Cloud Functions 페이지로 이동.

  2. 함수 옆에 있는 체크박스를 클릭합니다.

  3. 페이지 상단의 삭제 버튼을 클릭하고 삭제를 확인합니다.

Compute Engine 인스턴스 삭제

Compute Engine 인스턴스를 삭제하는 방법은 다음과 같습니다.

  1. Cloud Console에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스 페이지로 이동

  2. 삭제할 인스턴스의 체크박스를 클릭합니다.
  3. 삭제 를 클릭하여 인스턴스를 삭제합니다.

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 가이드에서 만든 프로젝트를 삭제하는 것입니다.

프로젝트를 삭제하는 방법은 다음과 같습니다.

  1. Cloud Console에서 리소스 관리 페이지로 이동합니다.

    리소스 관리 페이지로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제 를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

다음 단계

  • 다른 Google Cloud Platform 기능 직접 사용해 보기. 가이드를 살펴보세요.