Cloud Functionsを使用してCompute Engineのマシンイメージを自動で取得する

記事タイトルとURLをコピーする

G-genの佐々木です。当記事では Google Cloud(旧称GCP) のサーバレスコンピューティングサービスである Cloud Functions を使用して、 Google Compute Engine (GCE) インスタンスからマシンイメージを定期的に取得する方法を紹介します。

Cloud Functions の概要については以下の記事をご一読ください。

blog.g-gen.co.jp

マシンイメージとは

マシンイメージ とは、 GCE インスタンスの プロパティ、メタデータ、権限、接続されている全てのディスクのデータを格納するリソースで、インスタンスの複製やバックアップに使用することができます。

Amazon Web Services (AWS) の EC2 における AMI (Amazon Machine Image) 機能 によく似たリソースです。 Google Cloudでは今年1月に一般公開となりました。

マシンイメージはディスクの スナップショットと異なり、複数のディスクを含めたインスタンス全体の構成情報を保存するため、インスタンスの複製や復元を より手軽 に行うことができます。

今回のテーマ

GCE では、ディスクのスナップショットはスナップショットスケジュールを使用することで定期的な取得が可能です。しかしながらマシンイメージの方では、スケジュールを設定することは できません

そこで Compute Engine APIのクライアントライブラリ を用いて、マシンイメージ取得の API を呼び出すコードを Cloud Functions 関数に実装します。

この関数を定期実行することでマシンイメージの取得を自動化することができます。

今回は Python 用のクライアントライブラリを使用して Cloud Functions 関数を作成していきます。

構成図

Pub/Sub トリガーの Cloud Functions を使用します。処理の流れは以下の通りです。

マシンイメージの定期取得 - 構成図

  1. Cloud Schedulerでcronを設定し、指定した時間にPub/Subに対してメッセージをパブリッシュします。
  2. Pub/Subにメッセージがパブリッシュされると、Pub/SubトリガーによりCloud Functions関数が呼び出されます。
  3. Cloud Functions関数のコードからCompute Engine APIを呼び出し、GCEインスタンスのマシンイメージを取得します。

a, bはCloud Functions関数を用いた定期実行処理の基本形なので、様々なタスクに応用することができるでしょう。

関数のサービスアカウントに必要な権限

Cloud Functions関数から他のGoogle Cloudリソースを操作する場合、サービスアカウントに必要なロールをアタッチし、そのサービスアカウントを関数に設定します。

マシンイメージの作成には最低でも以下の権限が必要です。(参考

  • プロジェクトに対する compute.machineImages.create 権限
  • 対象となるインスタンスへの compute.instances.useReadOnly 権限
  • ディスクへの compute.disks.createSnapshot 権限

事前定義されたロールを使用する場合、マシンイメージの作成には最低でもCompute インスタンス管理者のロールを付与しなければならないので、本番運用する場合はカスタムロールを作成することをおすすめします。

Pub/SubトリガーのCloud Functions関数を作成

今回は単純な処理なので、コンソール上からCloud Functions関数を作成していきます。

Cloud Functionsのコンソールから[関数の作成]をクリックし、関数の作成画面に進みます。

基本項目では、任意の関数名とリージョンを設定します。

トリガー項目でトリガーのタイプをCloud Pub/Subに設定し、新たにPub/Subトピックを作成していきます。

Cloud Functions作成画面からPub/Subトピックを作成

③Pub/Subトピックの作成画面が表示されるので、トピックIDを入力して[トピックを作成]をクリックします。

トピックの作成

④作成したPub/Subトピックを設定し、[保存]をクリックします。

Pub/Subトピック設定後、完了をクリック

ランタイム、ビルド、接続、セキュリティの設定を開き、ランタイムタブのランタイム サービス アカウント項目でCloud Functions関数用に作成したサービスアカウントを選択します。選択後、[次へ]をクリックします。

事前作成したサービスアカウントの設定

⑥コードの編集画面に進むので、ランタイムPython 3.9に設定し、この画面から、あらかじめ存在するmain.pyrequirements.txtの2つのファイルを編集していきます。

ランタイムをPythonに設定

requirements.txt の中身

ここに追記した外部ライブラリは、関数内で使用することができるようになります。

今回はCompute Engine APIのクライアントライブラリを追記するだけでOKです。

# Function dependencies, for example:
# package>=version
google-cloud-compute==1.3.2

main.pyの中身

Pub/Subトリガーの場合、デフォルトではhello_pubsub関数の部分から実行されます。

今回はマシンイメージ取得対象のGCEインスタンスの情報をコード内に直接記述していますが、複数のインスタンスで使用したい場合は、バックアップ対象一覧のファイルを別途用意したり、バックアップ対象であることを示すラベルがついたインスタンスの一覧を取得する処理を入れたりするのが良いでしょう。

また 同名のマシンイメージは取得できない ため、取得日をマシンイメージの名前末尾に付与する処理を入れています。

from google.cloud.compute_v1.services.machine_images import MachineImagesClient
from google.cloud.compute_v1.types import MachineImage, InsertMachineImageRequest
from datetime import datetime, timezone, timedelta
 
 
# マシンイメージ取得対象インスタンスの情報
project_id = '{プロジェクトID}'  # 対象インスタンスが存在するプロジェクトID
instance_name = '{インスタンス名}'  # 対象インスタンスの名前
instance_zone = '{ゾーン}'  # 対象インスタンスが存在するゾーン
 
# インスタンスの情報をURL形式にする
url = f'https://www.googleapis.com/compute/v1/projects/{project_id}/zones/{instance_zone}/instances/{instance_name}'
 
 
def hello_pubsub(event, context):
 
  client = MachineImagesClient()
 
  # マシンイメージの名前末尾に付与する日付の情報 (UTC→JSTの変換もここで実施)
  today = datetime.now(timezone(timedelta(hours=9))).strftime('%Y-%m-%d')
 
  # マシンイメージ取得リクエストの中身
  mimg_info = MachineImage(
    name = f'mimg-{instance_name}-{today}',  # マシンイメージの名前
    source_instance = url  # 取得対象インスタンスの情報
  )
  mimg_request = InsertMachineImageRequest(
    project = project_id,
    machine_image_resource = mimg_info
  )
  
  # マシンイメージの取得
  client.insert(
    request = mimg_request
  )

コードの編集が終わったら、画面右下の [デプロイ] をクリックし、関数のデプロイが完了するまで数分待ちます。

Cloud Schedulerジョブの設定

Cloud Functions関数を作成する際に一緒に作成したPub/Subトピックに対し、定期的にメッセージを送るジョブを設定します。

①Cloud Schedulerのコンソール画面に移動し、[ジョブを作成]をクリックします。

ジョブの作成画面の各項目を入力していきます。頻度項目はcron式でジョブの実行間隔を指定します。それぞれ入力したら[続行]をクリックします。

Cloud Scheduler スケジュールを定義

実行内容を構成する では、ターゲット タイプとして Pub/Sub を選択し、 Cloud Functions 関数作成時に作成した Pub/Sub トピックを設定します。

メッセージ本文も必須項目になっていますが、今回は特にメッセージ内容は問わないので適当に入力してください。

全て入力したら [作成] をクリックします。

Cloud Scheduler 実行内容の構成

ここまで設定が完了すれば、Cloud Schedulerが指定された時間にPub/Subトピックにメッセージを送信し、Pub/SubからCloud Functions関数がトリガーされます。指定した時間になるのを待ちましょう。

待ち切れない場合はコンソールからジョブを手動実行することも可能です。(操作からジョブを強制実行するをクリックしてください)

ジョブの実行結果

コンソールからジョブの実行結果を確認します。 前回の実行結果成功 になっていればOKです。

Cloud Scheduler ジョブの実行結果

ジョブの成功を確認したら、 Compute Engine のコンソールでマシンイメージ一覧を開きます。

作成されたマシンイメージが一覧に表示されるはずです。

作成されたマシンイメージの確認

このままでは毎日マシンイメージが作成されるので、検証目的であればCloud Schedulerのジョブを停止、もしくは削除するのを忘れないようにしましょう。

料金について

マシンイメージを作成するまでの処理を実行するリソースは全て サーバレス であり、インフラを管理する必要がありません。そして、この程度の処理内容であれば僅かな課金で済むでしょう。

今回の処理に使用したサービスの料金を以下に記載します。

サービスの種類 料金 備考
Cloud Scheduler ジョブ1つあたり $0.10/月 毎月ジョブ3つまで無料(プロジェクトではなくアカウント単位の個数)
Cloud Pub/Sub データ量1TBあたり $40.00/月 最初の10GBまで無料
Cloud Functions こちらの記事を参照 今回のケースでは月30回ほどの実行

また、ここで作成されるマシンイメージについては便利である反面、スナップショットと比べると料金が割高になる欠点もあります。

以下はasia-northeast1(東京リージョン)にそれぞれ作成した場合の料金です。(参考

タイプ 料金
スナップショット 1GBあたり$0.034/月
マシンイメージ 1GBあたり$0.065/月

料金を少しでも節約したい場合は、今回紹介した仕組みを応用し、マシンイメージ名の日付情報を用いて古いものを定期的に削除するなど、マシンイメージの世代管理の仕組みを用意することも必要となるでしょう。

佐々木 駿太(記事一覧)

クラウドソリューション部

2022年6月にG-genにジョイン。Google Cloud認定4冠、AWS 5冠、Azure 3冠、Salesforce 1冠のクラウドネイティブなエンジニア。

Professional Cloud Architect、Professional Cloud Network Engineerなどを所持