G-genの佐々木です。当記事では Google Cloud（旧称GCP） のサーバレスコンピューティングサービスである Cloud Functions を使用して、
Google Compute Engine (GCE) インスタンスからマシンイメージを定期的に取得する方法を紹介します。
Cloud Functions の概要については以下の記事をご一読ください。
- マシンイメージとは
- 今回のテーマ
- 構成図
- 関数のサービスアカウントに必要な権限
- Pub/SubトリガーのCloud Functions関数を作成
- Cloud Schedulerジョブの設定
- ジョブの実行結果
- 料金について
# マシンイメージとは
マシンイメージ とは、 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 を使用します。処理の流れは以下の通りです。
- Cloud Schedulerでcronを設定し、指定した時間にPub/Subに対してメッセージをパブリッシュします。
- Pub/Subにメッセージがパブリッシュされると、Pub/SubトリガーによりCloud Functions関数が呼び出されます。
- 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トピックを作成していきます。
③Pub/Subトピックの作成画面が表示されるので、トピックIDを入力して
[トピックを作成]をクリックします。
④作成したPub/Subトピックを設定し、
[保存]をクリックします。
⑤
ランタイム、ビルド、接続、セキュリティの設定を開き、 ランタイムタブの ランタイム サービス アカウント項目でCloud Functions関数用に作成したサービスアカウントを選択します。選択後、 [次へ]をクリックします。
⑥コードの編集画面に進むので、
ランタイムを Python 3.9に設定し、この画面から、あらかじめ存在する main.pyと requirements.txtの2つのファイルを編集していきます。
## 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' 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式でジョブの実行間隔を指定します。それぞれ入力したら [続行]をクリックします。
③
実行内容を構成する では、ターゲット タイプとして Pub/Sub を選択し、 Cloud Functions 関数作成時に作成した Pub/Sub トピックを設定します。
メッセージ本文も必須項目になっていますが、今回は特にメッセージ内容は問わないので適当に入力してください。
全て入力したら
[作成] をクリックします。
ここまで設定が完了すれば、Cloud Schedulerが指定された時間にPub/Subトピックにメッセージを送信し、Pub/SubからCloud Functions関数がトリガーされます。指定した時間になるのを待ちましょう。
待ち切れない場合はコンソールからジョブを手動実行することも可能です。（
操作から ジョブを強制実行するをクリックしてください）
# ジョブの実行結果
コンソールからジョブの実行結果を確認します。
前回の実行結果 が 成功 になっていればOKです。
ジョブの成功を確認したら、 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冠のクラウドネイティブなエンジニア。