このチュートリアルは、読者が次の内容を理解していることを前提としています。
目標
- 未使用の IP アドレスを削除する: Google Cloud では、静的 IP アドレスがロードバランサや仮想マシン(VM)インスタンスに接続されている場合、その静的 IP アドレスは無料のリソースになります。静的 IP アドレスが予約されている場合、それが使用されていなくても、1 時間ごとに課金されます。静的 IP アドレスと大規模な動的プロビジョニングが不可欠なアプリでは、このコストが時間の経過とともに極めて大きくなる可能性があります。
- 孤立ディスクまたは未使用の永続ディスクを削除する: 永続ディスクが、VM にアタッチされずに作成された場合、またはマシンに複数のディスクがあり、1 つ以上のディスクが切断された場合、その永続ディスクは未使用になるか孤立します。
- 低価格なストレージ クラスへ移行する: Google Cloud では、複数のクラスのオブジェクト ストレージを提供しています。ニーズに合ったクラスを使用してください。
アーキテクチャ
次の図は、デプロイの最初の部分を示しています。ここでは、未使用の IP アドレスを特定してクリーンアップするために Cloud Functions の関数のスケジュールを設定します。
最初の例では、次の内容について説明します。
- 静的外部 IP アドレスと使用されていない個別の静的外部 IP アドレスを使用した Compute Engine VM を作成する。
- 未使用のアドレスを特定するための Cloud Function をデプロイする。
- HTTP トリガーを使用して実行する関数をスケジュールする Cloud Scheduler ジョブを作成する。
次の図では、Cloud Functions の関数をスケジュールし、アタッチされていない孤立した永続ディスクを特定してクリーンアップします。
2 番目の例では、次の内容について説明します。
- 2 つの永続ディスクと接続されていない個別の永続ディスクを使用した Compute Engine VM を作成する。ディスクの 1 つは、VM から接続解除されることにより孤立します。
- Cloud Function をデプロイし、接続されていない孤立した永続ディスクを特定する。
- HTTP トリガーを使用して Cloud Function の実行をスケジュールする Cloud Scheduler ジョブを作成する。
次の図では、Monitoring アラート ポリシーから Cloud Functions の関数をトリガーし、ストレージ バケットをより低コストなストレージ クラスに移行しています。
3 番目の例では、次の内容について説明します。
- 2 つのストレージ バケットを作成し、ファイルをサービング バケットに追加して、トラフィックを生成する。
- バケット使用率を可視化するモニタリング ダッシュボードを作成する。
- Cloud Functions の関数をデプロイし、アイドル状態のバケットをより低価格なストレージ クラスに移行する。
- Monitoring アラート ポリシーから受信した通知をシミュレートすることを目的としたペイロードを使用して、関数をトリガーします。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
- Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Compute Engine, Cloud Functions, and Cloud Storage API を有効にします。
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Compute Engine, Cloud Functions, and Cloud Storage API を有効にします。
-
Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。
Google Cloud コンソールの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。Google Cloud CLI がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。
このドキュメントのすべてのコマンドは、Cloud Shell から実行します。
環境設定
このセクションでは、このアーキテクチャに必要なインフラストラクチャと ID を構成します。
Cloud Shell でリポジトリのクローンを作成し、
gcf-automated-resource-cleanup
ディレクトリに移動します。git clone https://github.com/GoogleCloudPlatform/gcf-automated-resource-cleanup.git && cd gcf-automated-resource-cleanup/
環境変数を設定し、リポジトリ フォルダを
$WORKDIR
フォルダに設定します。ここで、すべてのコマンドを実行します。export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) WORKDIR=$(pwd)
オープンソースの負荷生成ツールである Apache Bench をインストールします。
sudo apt-get install apache2-utils
未使用の IP アドレスのクリーンアップ
このセクションでは、次の手順を行います。
- 2 つの静的 IP アドレスを作成する。
- 静的 IP アドレスを使用する VM を作成する。
- Cloud Functions コードを確認する。
- Cloud Functions の関数をデプロイする。
- Cloud Scheduler ジョブを使用して Cloud Functions の関数をテストする。
IP アドレスの作成
Cloud Shell で、
unused-ip
ディレクトリに移動します。cd $WORKDIR/unused-ip
IP アドレスの名前を変数としてエクスポートします。
export USED_IP=used-ip-address export UNUSED_IP=unused-ip-address
2 つの静的 IP アドレスを作成します。
gcloud compute addresses create $USED_IP \ --project=$PROJECT_ID --region=us-central1 gcloud compute addresses create $UNUSED_IP \ --project=$PROJECT_ID --region=us-central1
この例では
us-central1
リージョンを使用していますが、別のリージョンを選択することもできます。その場合、このドキュメントの以降の操作で、指定したリージョンを一貫して参照してください。2 つのアドレスが作成されたことを確認します。
gcloud compute addresses list --filter="region:(us-central1)"
出力でステータスが
RESERVED
の場合、IP アドレスが使用されていないことを意味します。NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 RESERVED
使用される IP アドレスを環境変数として設定します。
export USED_IP_ADDRESS=$(gcloud compute addresses describe $USED_IP \ --region=us-central1 --format=json | jq -r '.address')
VM の作成
Cloud Shell で、インスタンスを作成します。
gcloud compute instances create static-ip-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --subnet=default \ --address=$USED_IP_ADDRESS
IP アドレスの 1 つが現在使用中であることを確認します。
gcloud compute addresses list --filter="region:(us-central1)"
出力は次のようになります。
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
Cloud Functions の関数コードの確認
Cloud Shell で、コードのメイン セクションを出力します。
cat $WORKDIR/unused-ip/function.js | grep "const compute" -A 31
出力は次のとおりです。
const compute = new Compute(); compute.getAddresses(function(err, addresses){ // gets all addresses across regions if(err){ console.log("there was an error: " + err); } if (addresses == null) { console.log("no addresses found"); return; } console.log("there are " + addresses.length + " addresses"); // iterate through addresses for (let item of addresses){ // get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used AND if it's at least ageToDelete days old: if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){ // delete address item.delete(function(err, operation, apiResponse2){ if (err) { console.log("could not delete address: " + err); } }) } }) } // return number of addresses evaluated res.send("there are " + addresses.length + " total addresses"); }); }
上記のコードサンプルでは、次の点に注意してください。
compute.getAddresses(function(err, addresses){ // gets all addresses across regions
getAddresses
メソッドを使用して、プロジェクト内のすべてのリージョンの IP アドレスを取得します。// get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used: if (metadata.status=='RESERVED'){
各 IP アドレスのメタデータを取得し、その
STATUS
フィールドを確認します。if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){
IP アドレスが使用中かどうかを確認し、ヘルパー関数を使用して期間を計算し、その期間を定数(この例のために
0
に設定)と比較します。// delete address item.delete(function(err, operation, apiResponse2){
IP アドレスを削除します。
Cloud Functions の関数のデプロイ
Cloud Shell で、Cloud Functions の関数をデプロイします。
gcloud functions deploy unused_ip_function --trigger-http --runtime=nodejs8
トリガー URL を環境変数として設定します。
export FUNCTION_URL=$(gcloud functions describe unused_ip_function \ --format=json | jq -r '.httpsTrigger.url')
Cloud Functions の関数のスケジュール設定とテスト
Cloud Shell で、毎日午前 2 時に Cloud Function を実行する Cloud Scheduler タスクを作成します。
gcloud scheduler jobs create http unused-ip-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
ジョブを手動でトリガーしてテストします。
gcloud scheduler jobs run unused-ip-job
未使用の IP アドレスが削除されたことを確認します。
gcloud compute addresses list --filter="region:(us-central1)"
出力は次のようになります。
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
未使用および孤立した永続ディスクのクリーンアップ
このセクションでは、次の手順を行います。
- 2 つの永続ディスクを作成する。
- ディスクの 1 つを使用する VM を作成する。
- ディスクを VM から切断する。
- Cloud Functions 関数のコードを確認する。
- Cloud Functions 関数をデプロイする。
- Cloud Scheduler ジョブを使用して Cloud Functions の関数をテストする。
永続ディスクの作成
Cloud Shell で、
unattached-pd
ディレクトリに移動します。cd $WORKDIR/unattached-pd
ディスクの名前を環境変数としてエクスポートします。
export ORPHANED_DISK=orphaned-disk export UNUSED_DISK=unused-disk
2 つのディスクを作成します。
gcloud beta compute disks create $ORPHANED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a gcloud beta compute disks create $UNUSED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a
2 つのディスクが作成されたことを確認します。
gcloud compute disks list
出力は次のとおりです。
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS orphaned-disk us-central1-a zone 500 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY unused-disk us-central1-a zone 500 pd-standard READY
VM の作成とディスクの検査
Cloud Shell で、インスタンスを作成します。
gcloud compute instances create disk-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --disk=name=$ORPHANED_DISK,device-name=$ORPHANED_DISK,mode=rw,boot=no
VM に接続されたディスクを検査します。
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
出力は次のようになります。
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "users": [ "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/instances/disk-instance" ], "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
上記のコードサンプルでは、次の点に注意してください。
users
は、ディスクが接続されている VM を示します。lastAttachTimestamp
は、ディスクが VM に最後に接続された日時を示します。
VM に接続されていないディスクを検査します。
gcloud compute disks describe $UNUSED_DISK \ --zone=us-central1-a \ --format=json | jq
出力は次のようになります。
{ "creationTimestamp": "2019-06-12T12:21:30.905-07:00", "id": "1313096191791918677", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "name": "unused-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/unused-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
上のコードサンプルでは、次の点が重要になります。
- ディスクに
users
が表示されていないのは、現在 VM によって使用されていないためです。 - ディスクに
lastAttachedTimestamp
が表示されていないのは、使用されたことがないためです。
- ディスクに
孤立した永続ディスクを VM から接続解除します。
gcloud compute instances detach-disk disk-instance \ --device-name=$ORPHANED_DISK \ --zone=us-central1-a
孤立したディスクを検査します。
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
出力は次のようになります。
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "lastDetachTimestamp": "2019-06-12T12:34:56.040-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
上のコードサンプルでは、次の点が重要になります。
- ディスクに
users
が表示されていない場合は、現在使用されていないことを示しています。 - 今度は、ディスクが VM から最後に切り離された日時(つまり、ディスクが最後に使用された日時)を示す
lastDetachTimestamp
エントリがあります。 lastAttachTimestamp
フィールドはまだ存在します。
- ディスクに
Cloud Functions の関数コードの確認
Cloud Shell で、プロジェクト内のすべての永続ディスクを取得するコードのセクションを出力します。
cat $WORKDIR/unattached-pd/main.py | grep "(request)" -A 12
出力は次のとおりです。
def delete_unattached_pds(request): # get list of disks and iterate through it: disksRequest = compute.disks().aggregatedList(project=project) while disksRequest is not None: diskResponse = disksRequest.execute() for name, disks_scoped_list in diskResponse['items'].items(): if disks_scoped_list.get('warning') is None: # got disks for disk in disks_scoped_list['disks']: # iterate through disks diskName = disk['name'] diskZone = str((disk['zone'])).rsplit('/',1)[1] print (diskName) print (diskZone)
この関数は、
aggregatedList
メソッドを使用して、実行中の Google Cloud プロジェクト内のすべての永続ディスクを取得し、各ディスクを反復処理します。lastAttachTimestamp
フィールドを確認し、存在しない場合はディスクを削除するコードのセクションを出力します。cat $WORKDIR/unattached-pd/main.py | grep "handle never" -A 11
出力は次のとおりです。
# handle never attached disk - delete it # lastAttachedTimestamp is not present if disk.get("lastAttachTimestamp") is None: print ("disk " + diskName + " was never attached - deleting") deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") Continue
このセクションは、
lastAttachTimestamp
が存在しない場合、つまりこのディスクが一度も使用されなかった場合に、ディスクを削除します。ディスクが孤立している場合は経過時間を計算し、スナップショットを作成して削除するコードのセクションを出力します。
cat $WORKDIR/unattached-pd/main.py | grep "handle detached" -A 32
出力は次のとおりです。
# handle detached disk - snapshot and delete # lastAttachTimestamp is present AND users is not present AND it meets the age criterium if disk.get("users") is None \ and disk.get("lastDetachTimestamp") is not None \ and diskAge(disk['lastDetachTimestamp'])>=deleteAge: print ("disk " + diskName + " has no users and has been detached") print ("disk meets age criteria for deletion") # take a snapshot snapShotName = diskName + str(int(time.time())) print ("taking snapshot: " + snapShotName) snapshotBody = { "name": snapShotName } snapshotRequest = compute.disks().createSnapshot(project=project, zone=diskZone, disk=diskName, body=snapshotBody) snapshotResponse = snapshotRequest.execute() waitForZoneOperation(snapshotResponse, project, diskZone) print ("snapshot completed") # delete the disk print ("deleting disk " + diskName) deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") continue
コードのこのセクションは、ディスクに
users
が表示され、lastDetachTimestamp
が存在する場合に使用されます。つまり、ディスクが現在使用中ではありませんが、ある時点で使用されていたことを意味します。この場合、Cloud Functions の関数はディスクのスナップショットを作成してデータを保持してから、ディスクを削除します。
Cloud Functions の関数のデプロイ
Cloud Shell で、Cloud Functions の関数をデプロイします。
gcloud functions deploy delete_unattached_pds \ --trigger-http --runtime=python37
Cloud Functions の関数のトリガー URL を環境変数として設定します。
export FUNCTION_URL=$(gcloud functions describe delete_unattached_pds \ --format=json | jq -r '.httpsTrigger.url')
Cloud Functions の関数のスケジュール設定とテスト
Cloud Shell で、毎日午前 2 時に Cloud Function を実行する Cloud Scheduler タスクを作成します。
gcloud scheduler jobs create http unattached-pd-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
ジョブをテストします。
gcloud scheduler jobs run unattached-pd-job
孤立ディスクのスナップショットが作成されたことを確認します。
gcloud compute snapshots list
出力は次のようになります。
NAME DISK_SIZE_GB SRC_DISK STATUS orphaned-disk1560455894 500 us-central1-a/disks/orphaned-disk READY
未使用のディスクと孤立ディスクが削除されたことを確認します。
gcloud compute disks list
出力は次のとおりです。
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS disk-instance us-central1-a zone 10 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY
ストレージ バケットの低価格なストレージ クラスへの移行
Google Cloud のストレージ オブジェクトのライフサイクル ルールを使用すると、作成日やライブ状態などの一連の属性に基づいて、オブジェクトを異なるストレージ クラスへ自動的に移動できます。ただし、これらのルールはオブジェクトがアクセスされたかどうかは把握していません。一定の時間アクセスされていない場合、新しいオブジェクトを Nearline Storage に移動することもできます。
このセクションでは、次の手順を行います。
- 2 つの Cloud Storage バケットを作成する。
- バケットの 1 つにオブジェクトを追加する。
- バケット オブジェクト アクセスを監視するように Monitoring を構成する。
- オブジェクトを Regional Storage バケットから Nearline Storage バケットに移行する Cloud Functions の関数コードを確認する。
- Cloud Functions の関数をデプロイする。
- Monitoring アラートを使用して Cloud Functions の関数をテストする。
Cloud Storage バケットの作成とファイルの追加
Cloud Shell で、
migrate-storage
ディレクトリに移動します。cd $WORKDIR/migrate-storage
後でストレージ クラスを変更するために使用される
serving-bucket
Cloud Storage バケットを作成します。export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-serving-bucket
バケットを公開します。
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket
バケットにテキスト ファイルを追加します。
gsutil cp $WORKDIR/migrate-storage/testfile.txt \ gs://${PROJECT_ID}-serving-bucket
ファイルを公開します。
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket/testfile.txt
ファイルにアクセスできることを確認します。
curl http://storage.googleapis.com/${PROJECT_ID}-serving-bucket/testfile.txt
出力は次のとおりです。
this is a test
データを提供しない
idle-bucket
という名前の 2 番目のバケットを作成します。gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-idle-bucket
Cloud Monitoring ワークスペースを設定する
このセクションでは、バケットの使用状況を監視して、バケット オブジェクトが使用されていないときを把握できるよう Cloud Monitoring を構成します。提供バケットが使用されていない場合、Cloud Functions の関数はバケットを Regional Storage クラスから Nearline Storage クラスに移行します。
Google Cloud コンソールで [Monitoring] に移動します。
[New Workspace] を選択し、[Add] をクリックします。
初期構成が完了するまで待ちます。
Cloud Monitoring ダッシュボードを作成する
Monitoring で、ダッシュボードに移動し、[ダッシュボードを作成] をクリックします。
[グラフを追加] をクリックします。
[名前] フィールドに「
Bucket Access
」と入力します。Cloud Storage バケットのリクエスト コンテンツ指標を検索するには、[Find resource and metric] フィールドに「
request
」と入力し、gcs_bucket
リソースの [リクエスト数] 指標を選択します。バケット名で指標をグループ化するには、[グループ条件] プルダウン リストで [
bucket_name
] をクリックします。メソッド名でフィルタリングするには、[フィルタ] フィールドに「ReadObject」と入力し、[適用] をクリックします。
[保存] をクリックします。
[名前] フィールドに「
Bucket Usage
」と入力します。ダッシュボードにアクセスできることを確認するには、ダッシュボード上にポインタを置き、バケットの使用状況が表示されることを確認します。
バケット内のオブジェクト アクセスを監視できるよう、Monitoring を構成しました。Cloud Storage バケットへのトラフィックがないため、グラフにはデータが表示されません。
提供バケットの負荷の生成
Monitoring が構成されたので、Apache Bench を使用してトラフィックを提供バケットに送信します。
Cloud Shell で、提供バケット内のオブジェクトにリクエストを送信します。
ab -n 10000 \ http://storage.googleapis.com/$PROJECT_ID-serving-bucket/testfile.txt
Google Cloud コンソールで [Monitoring] に移動します。
バケットの使用状況ダッシュボードを選択するには、ダッシュボード上にポインタを置いて [バケットの使用状況] を選択します。提供バケットにのみトラフィックがあることを確認します。アイドル状態のバケットにはトラフィックがないため、
request_count metric
時系列は提供バケットに対してのみ表示されます。
Cloud Functions の関数の確認とデプロイ
Cloud Shell で、Cloud Functions の関数を使用してストレージ バケットを Nearline Storage クラスに移行するコードを出力します。
cat $WORKDIR/migrate-storage/main.py | grep "migrate_storage(" -A 15
出力は次のとおりです。
def migrate_storage(request): # process incoming request to get the bucket to be migrated: request_json = request.get_json(force=True) # bucket names are globally unique bucket_name = request_json['incident']['resource_name'] # create storage client storage_client = storage.Client() # get bucket bucket = storage_client.get_bucket(bucket_name) # update storage class bucket.storage_class = "NEARLINE" bucket.patch()
Cloud Functions の関数は、リクエストで渡されたバケット名を使用して、ストレージ クラスを Nearline Storage に変更します。
Cloud Functions の関数をデプロイします。
gcloud functions deploy migrate_storage --trigger-http --runtime=python37
次のセクションで使用する環境変数としてトリガー URL を設定します。
export FUNCTION_URL=$(gcloud functions describe migrate_storage \ --format=json | jq -r '.httpsTrigger.url')
アラート自動化のテストと検証
アイドル状態のバケットに名前を付けます。
export IDLE_BUCKET_NAME=$PROJECT_ID-idle-bucket
incident.json
ファイルを使用して、デプロイした Cloud Functions の関数にテスト通知を送信します。envsubst < $WORKDIR/migrate-storage/incident.json | curl -X POST \ -H "Content-Type: application/json" $FUNCTION_URL -d @-
出力は次のとおりです。
OK
出力は改行で終了せずに、すぐにコマンド プロンプトが続きます。
アイドル状態のバケットが Nearline Storage に移行されたことを確認します。
gsutil defstorageclass get gs://$PROJECT_ID-idle-bucket
出力は次のとおりです。
gs://automating-cost-optimization-idle-bucket: NEARLINE
本番環境に関する考慮事項
独自の Google Cloud 環境でコストの最適化を自動化する場合は、次の点を考慮してください。
- 一般的な考慮事項: Google Cloud リソースを変更または削除する権限を持つ Cloud Functions のセキュリティを強化する必要があります。
- 無駄の特定: このチュートリアルでは、無駄な支出に関するいくつかの例について説明しています。一般的に、3 つのカテゴリのいずれかに分類される例がこの他にも多くあります。
- オーバー プロビジョニングされたリソース: 必要以上の CPU パワーとメモリを搭載した VM など、特定のワークロードに必要以上に大きくプロビジョニングされたリソース。
- アイドル状態のリソース: 完全に未使用のリソース。
- パートタイムでアイドル状態になるリソース: 営業時間中にのみ使用されるリソース。
- クリーンアップの自動化: このチュートリアルでは、ディスクのスナップショットを作成して削除するために、複数の非同期操作を含む複数のステップによるプロセスが必要でした。未使用の IP アドレスなどの他の Google Cloud リソースは、同期オペレーションを使用できます。
- 大規模なデプロイ: このチュートリアルでは、Google Cloud プロジェクト ID は Cloud Functions の関数コードで定義されます。このようなソリューションを大規模にデプロイするには、Cloud Billing または Cloud Resource Manager API を使用して、請求先アカウントまたは組織を持つプロジェクトのリストを取得することを検討してください。次に、これらの Google Cloud プロジェクト ID を変数として関数に渡します。このような構成では、リソースをクリーンアップまたは削除できるプロジェクトに Cloud Functions の関数のサービス アカウントを追加する必要があります。Cloud Deployment Manager や Terraform などの自動デプロイ フレームワークを使用することをおすすめします。
- アラートの自動化: このドキュメントでは、Monitoring アラートからのモック ペイロードを使用して、ストレージ クラスの移行をトリガーする方法について説明します。Monitoring アラート ポリシーは、最大 23 時間 59 分間にわたって評価できます。本番環境では、この制限はストレージ クラスを移行する前に、バケットがアイドル状態であると見なすほど長くない場合があります。Cloud Storage バケットでデータアクセスの監査ログを有効にし、これらの監査ログを使用するパイプラインを作成して、過去 30 日間にサービス提供にバケットが使用されたかどうかを評価することを検討してください。詳細については、監査ログについてでご確認ください。また、集約シンクを作成してログを Pub/Sub と Dataflow パイプラインに送信することをおすすめします。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
プロジェクトの削除
- Google Cloud コンソールで、[リソースの管理] ページに移動します。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
次のステップ
- コスト管理に関する動画を見る。
- コスト管理に関するホームページにアクセスする。
- Cloud Billing に関するドキュメントを確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センター をご覧ください。