インスタンス メタデータの保存と取得

すべてのインスタンスはメタデータをメタデータ サーバーに保存します。このメタデータ サーバーに対して、インスタンス内からも Compute Engine API からも、プログラムでクエリを実行できます。インスタンスのホスト名、インスタンス ID、起動スクリプト、シャットダウン スクリプト、カスタム メタデータ、サービス アカウント情報など、インスタンスに関する情報をクエリできます。インスタンスからメタデータ サーバーの API にアクセスするのに追加の承認は必要ありません。自動的にアクセスできるようになります。

メタデータ サーバーは、起動スクリプトおよびシャットダウン スクリプトと組み合わせて使用すると特に便利です。メタデータ サーバーを使用して、追加の承認を行わずに、インスタンスに関する固有の情報をプログラムで取得できるからです。たとえば、起動スクリプトでインスタンスの外部 IP のメタデータの Key-Value ペアを取得して、その IP を使用してデータベースを設定できます。デフォルトのメタデータキーはすべてのインスタンスで同じなので、スクリプトはそのまま再利用できます。インスタンスごとに更新する必要はありません。これにより、アプリケーションのコードの安定性が向上します。

メタデータは key:value 形式で保存されます。すべてのインスタンスがアクセスできるメタデータ エントリのデフォルト セットが用意されています。そのほかにカスタム メタデータを設定することもできます。

メタデータ サーバーにアクセスするには、メタデータ URL をクエリで取得します

v1beta1 サーバーと v0.1 メタデータ サーバー エンドポイントは非推奨であり、提供終了となります。v1 を使用するすべてのリクエストを必ず更新してください。詳細については、v1 メタデータ サーバー エンドポイントへの移行をご覧ください。

メタデータ サーバー エンドポイントのバージョンを確認する方法については、サーバー エンドポイントのバージョンの確認をご覧ください。

始める前に

このタスクに必要な権限

このタスクを実行するには、次の権限が必要です。

  • インスタンス メタデータを設定する場合、そのインスタンスに対する compute.instances.setMetadata
  • プロジェクト全体のメタデータを設定する場合、そのプロジェクトに対する compute.projects.setCommonInstanceMetadata
  • メタデータを取得するだけの場合、そのプロジェクトに対する compute.projects.get
  • メタデータを取得するだけの場合、そのインスタンスに対する compute.instances.get

プロジェクトとインスタンスのメタデータ

プロジェクトとインスタンスの両方にメタデータを割り当てることができます。プロジェクト メタデータはそのプロジェクト内のすべての仮想マシン(VM)インスタンスに反映されますが、インスタンス メタデータが影響するのはそのインスタンスだけです。

デフォルトのメタデータキー

Compute Engine では、インスタンスまたはプロジェクトに関する情報を提供する一連のデフォルト メタデータ エントリが定義されます。デフォルト メタデータは常にサーバーによって定義され、設定されます。これらのメタデータのペアを手動で編集することはできません。

プロジェクトで使用できるデフォルト メタデータを以下に示します。一部のメタデータ エントリは、他のメタデータキーを含むディレクトリです。区別のために、メタデータ名の末尾にスラッシュが付いています。たとえば、attributes/ は他のキーを含むディレクトリであり、numeric-project-id は値にマッピングされるメタデータキーです。

パスの基準: http://metadata.google.internal/computeMetadata/v1/project/
メタデータ エントリ 説明
attributes/ このプロジェクトに対して設定されたカスタム メタデータ値のディレクトリ。
attributes/disable-legacy-endpoints プロジェクト内のすべてのインスタンスの、以前のメタデータ サーバー エンドポイントを無効にします。プロジェクトで以前のエンドポイントを使用しない限り、常に disable-legacy-endpoints=TRUE を設定します。v1 エンドポイントを使用するようにアプリケーションを更新します。
attributes/enable-oslogin enable-oslogin=TRUE を設定すると、プロジェクトで OS ログインによる SSH 認証鍵管理機能が有効になります。
attributes/vmdnssetting プロジェクト内のインスタンスの内部 DNS 名のフォーマット方法を構成します。内部 DNS 名の詳細については、DNS 名の構成をご覧ください。
attributes/ssh-keys プロジェクトとインスタンスが SSH 認証鍵の管理に OS ログインを使用するよう構成されていない場合、この属性を使用すると、プロジェクト内のインスタンスに接続できる公開 SSH 認証鍵を構成できます。複数の SSH 認証鍵がある場合は改行文字(\n)で区切ります。この値は文字列です。OS ログインによって管理される SSH 認証鍵は、このメタデータ値では表示されません。

例: "user1:ssh-rsa mypublickey user1@host.com\nuser2:ssh-rsa mypublickey user2@host.com"

numeric-project-id インスタンスの数値プロジェクト ID(プロジェクト番号)。これは、Google Cloud Console に表示されるプロジェクト名と同じではありません。この値は、project-id メタデータ エントリの値とも異なります。
project-id プロジェクト ID

インスタンスで使用できるデフォルト メタデータを以下に示します。

パスの基準: http://metadata.google.internal/computeMetadata/v1/instance/
メタデータ エントリ 説明
attributes/ 起動またはシャットダウンの際にインスタンスに渡されるカスタム メタデータ値のディレクトリ。詳しくは、この後のカスタム メタデータの設定をご覧ください。
attributes/enable-oslogin enable-oslogin=TRUE を設定すると、このインスタンスで OS ログインによる SSH 認証鍵管理機能が有効になります。
attributes/vmdnssetting インスタンスの内部 DNS 名のフォーマット方法を構成します。内部 DNS 名の詳細については、DNS 名の構成をご覧ください。
attributes/ssh-keys インスタンスが SSH 認証鍵の管理に OS ログインを使用するよう構成されていない場合、この属性を使用すると、インスタンスに接続できる公開 SSH 認証鍵を構成できます。複数の SSH 認証鍵がある場合は改行文字(\n)で区切ります。この値は文字列です。OS ログインによって管理される SSH 認証鍵は、このメタデータ値では表示されません。

例: "user1:ssh-rsa mypublickey user1@host.com\nuser2:ssh-rsa mypublickey user2@host.com"

cpu-platform インスタンスの CPU プラットフォーム。
description インスタンスの説明。--description フラグを使用して割り当てるか、API で設定します。
disks/ このインスタンスに接続されているディスクのディレクトリ。
guest-attributes/ 頻度の低いステータス通知、少量のデータ、または使用頻度の低いデータを公開する場合に使用できるカスタム インスタンス メタデータ値。これらの値は、起動スクリプトの終了を通知する場合に便利です。また、他のアプリケーションに頻度の低いステータス通知を提供する場合にも役立ちます。VM インスタンスのユーザーやプロセスは guest-attributes メタデータに名前空間とキーを書き込み、読み取ることができます。
hostname インスタンスのホスト名。
id インスタンスの ID。Compute Engine によって生成される一意の数値 ID です。インスタンス名を使用しない場合、インスタンスを識別するのに便利です。
machine-type このインスタンスのマシンタイプのメタデータ値。projects/projectnum/machineTypes/machine-type という形式になります。
name インスタンス名。
network-interfaces/ インスタンスのネットワーク インターフェースのディレクトリ。
network-interfaces/<index>/forwarded-ips/ ネットワーク インターフェース <index> で現在この仮想マシン インスタンスを指しているすべての外部 IP のディレクトリ。具体的には、このインスタンスにパケットを転送する転送ルールによって処理される外部 IP のリストを提供します。
scheduling/ インスタンスのスケジュール オプションを含むディレクトリ。
scheduling/on-host-maintenance インスタンスの透過的メンテナンス イベントの動作の設定。この値は、--on_host_maintenance フラグまたは API を使用して設定します。
scheduling/automatic-restart インスタンスの自動再起動の設定。この値は、‑‑automatic_restart フラグまたは API を使用して設定します。
scheduling/preemptible インスタンスがプリエンプティブルかどうかの設定。この値が TRUE の場合、インスタンスはプリエンプティブルです。この値は、インスタンスの作成時に設定され、変更することはできません。
maintenance-event 透過的メンテナンス イベントがこのインスタンスに影響を与えていることを示すパス。詳しくは、透過的メンテナンスの通知をご覧ください。
service-accounts/ インスタンスに関連付けられているサービス アカウントのディレクトリ。
service-accounts/service-account-name/token アプリケーションの認証に使用できる OAuth2 アクセス トークン。
service-accounts/service-account-name/identity インスタンスに固有の JSON ウェブトークン。このインスタンス メタデータ値のリクエストには、audience パラメータを含める必要があります。例: ?audience=http://www.example.com。インスタンス ID トークンのリクエストおよび確認方法の詳細については、インスタンスの ID の確認をご覧ください。
tags インスタンスに関連付けられているタグ
zone このインスタンスが実行されているゾーンのメタデータ値。形式は projects/projectnum/zones/zone となります。

メタデータの取得

メタデータ サーバーのコンテンツのクエリを実行するには、仮想マシン インスタンスから次のルート URL にリクエストを送信します。メタデータ サーバーにリクエストを送信するには、http://metadata.google.internal/computeMetadata/v1/ という URL を使用します。

すべてのメタデータ値は、これらのルート URL の下のサブパスとして定義されます。

デフォルト メタデータの値のクエリは、関連付けられているインスタンスからのみ実行できます。別のインスタンスから実行したり、直接ローカル コンピュータから実行したりすることはできません。curlwget などの標準のツールを使用して、インスタンスからメタデータ サーバーに接続できます。

メタデータのクエリを実行する際には、すべてのリクエストに次のヘッダーを含める必要があります。

Metadata-Flavor: Google

このヘッダーにより、そのリクエストがメタデータ値を取得する目的で送信されたものであり、安全でないソースから意図せず送信されたものではないことが示されるため、リクエストしたデータがメタデータ サーバーから返されるようになります。このヘッダーが含まれていないリクエストはメタデータ サーバーで拒否されます。

X-Forwarded-For ヘッダー

X-Forwarded-For ヘッダーを含むリクエストは、メタデータ サーバーで自動的に拒否されます。このヘッダーは、一般に、リクエストにプロキシが使用されていることを示します。この場合、承認されたユーザーからのリクエストではない可能性があります。そのようなリクエストは、セキュリティ上の理由からすべて拒否されます。

制限事項

curl コマンドを使用してサーバーからメタデータを取得する場合、一部のエンコードされた文字はリクエストパスでサポートされません。エンコードされた文字は、クエリパスでのみサポートされています。

たとえば、次のリクエストは機能しない場合があります。

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/123456789-compute%40developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true" -H "Metadata-Flavor: Google"

このリクエストを機能させるには、リクエストパスのサポートされていないエンコードされた文字(%40)を同等の許容値(@)に置き換える必要があります。

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/1234567898-compute@developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true" -H "Metadata-Flavor: Google"

以下の表に、リクエストパスでサポートされていないエンコード文字をまとめています。

エンコードされた文字 許容値
%21

!
%24

$
%27

'
%28

(
%29

)
%2A

*
%2C

,
%40

@

メタデータ情報のセキュリティ

メタデータ サーバーにリクエストを送信して情報を取得する際、そのリクエストやそれに対するメタデータ レスポンスが、仮想マシン インスタンスを実行する物理ホストの外に出ることはありません。

ディレクトリ リストのクエリ

メタデータ サーバーでは、一部のメタデータキーを整理するためにディレクトリが使用されています。末尾にスラッシュが付いているメタデータ エントリがディレクトリです。たとえば、disks/ というエントリは、そのインスタンスに接続されているディスクのディレクトリです。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/" -H "Metadata-Flavor: Google"

0/
1/
2/

同様に、ディスク 0/ ディレクトリに関する詳細情報が必要な場合は、そのディレクトリの特定の URL をクエリで取得できます。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/" -H "Metadata-Flavor: Google"

device-name
index
mode
type

エンドポイントのクエリ

ディレクトリではないメタデータキーは、1 つ以上の値を返すエンドポイントです。たとえば、特定のディスクのモードを調べるには、次のエンドポイントに対してクエリを実行します。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/mode" -H "Metadata-Flavor: Google"

READ_WRITE

デフォルトでは、エンドポイントごとにレスポンスの形式があらかじめ定義されています。データを JSON 形式で返すエンドポイントもあれば、文字列として返すエンドポイントもあります。指定されているデフォルトのデータ形式をオーバーライドするには、クエリ パラメータの alt=json(データを JSON 文字列形式で返す)または alt=text(データの平文表現を返す)を使用します。

たとえば、tags キーではデータが自動的に JSON 形式で返されますが、これをテキスト形式で返されるように変更するには、alt=text クエリ パラメータを指定します。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google"

["bread","butter","cheese","cream","lettuce"]
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text" -H "Metadata-Flavor: Google"

bread
butter
cheese
cream
lettuce

メタデータの再帰クエリ

ディレクトリ以下のすべての内容が返されるようにするには、リクエストで recursive=true クエリ パラメータを使用します。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true" -H "Metadata-Flavor: Google"

[{"deviceName":"boot","index":0,"mode":"READ_WRITE","type":"PERSISTENT"},
{"deviceName":"persistent-disk-1","index":1,"mode":"READ_WRITE","type":"PERSISTENT"},
{"deviceName":"persistent-disk-2","index":2,"mode":"READ_ONLY","type":"PERSISTENT"}]

デフォルトでは、再帰クエリの結果は JSON 形式で返されます。これらの内容をテキスト形式で返されるようにするには、alt=text クエリ パラメータを追加します。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true&alt=text" -H "Metadata-Flavor: Google"

0/device-name boot
0/index 0
0/mode READ_WRITE
0/type PERSISTENT
1/device-name persistent-disk-1
1/index 1
1/mode READ_WRITE
1/type PERSISTENT
2/device-name persistent-disk-1
2/index 2
2/mode READ_ONLY
2/type PERSISTENT

ブール値の設定

ブール値、TRUEFALSE のいずれかを受け入れるフィールドについては、次の値も使用できます。

ステータス 選択できる値
TRUE Y、Yes、1
FALSE N、No、0

ブール値では大文字と小文字は区別されません。たとえば、Falsefalse、または FALSE を使用して機能を無効にすることができます。

カスタム メタデータの設定

インスタンスまたはプロジェクトのカスタム メタデータは、Google Cloud Consolegcloud コマンドライン ツール、Compute Engine API のいずれかで設定できます。カスタム メタデータは、プロジェクトまたはインスタンスに任意の値を渡す場合や、起動スクリプトとシャットダウン スクリプトを設定する場合に役立ちます。

カスタム メタデータ サイズの制限

Compute Engine では、すべてのメタデータ エントリに対して合計で 512 KB の制限が適用されます。次のように、各 keyvalue に最大サイズの制限も適用されます。

  • 各メタデータ key の上限は 128 バイトです。
  • 各メタデータ value の上限は 256 KB です。

特に、SSH 認証鍵は ssh-keys キーの下にカスタム メタデータとして保存されます。このキーのメタデータ コンテンツが 256 KB の上限を超えると、SSH 認証鍵を追加できなくなります。この上限に達した場合は、新しいキーのメタデータ スペースを解放するために未使用のキーを削除することを検討してください。

起動スクリプトまたはシャットダウン スクリプトの内容を直接指定する場合、起動スクリプトとシャットダウン スクリプトの内容もカスタム メタデータとして保存され、これらのサイズ上限にカウントされることがあります。これを避けるには、起動スクリプトまたはシャットダウン スクリプトを Cloud Storage などの外部の場所でホストされるファイルとして保存し、インスタンスの作成時に起動スクリプトの URL を指定します。これらのファイルは、メタデータ サーバーに保存される代わりに VM インスタンスにダウンロードされます。

インスタンス メタデータの設定

Cloud Consolegcloud ツール、API のいずれかで、インスタンスのカスタム メタデータを設定します。インスタンス メタデータは、特定のインスタンスにのみ適用されます。

インスタンス作成時のメタデータの設定

Console

  1. Cloud Console で、[VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. [インスタンスを作成] をクリックします。
  3. [新しいインスタンスの作成] ページで、インスタンスのプロパティを入力します。
  4. [メタデータ] セクションで、カスタム メタデータの Key-Value ペアを必要な数だけ入力します。
  5. [作成] をクリックしてインスタンスを作成します。

gcloud

gcloud コマンドライン ツールで --metadata フラグを使用して、カスタム メタデータを設定します。

gcloud compute instances create example-instance \
    --metadata foo=bar

API

API では、リクエストのメタデータ プロパティの一部としてカスタム メタデータを渡します。

POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances

{
  "...
        }
      ]
    }
  ],
  "metadata": {
    "items": [
      {
       "key": "foo",
       "value": "bar"
      }
    ]
  },
  ..
}

実行中のインスタンスのメタデータの更新

Console

  1. Google Cloud Console で、[VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. メタデータを更新するインスタンスをクリックします。
  3. ページの上部にある [編集] ボタンをクリックします。
  4. [カスタム メタデータ] で [項目を追加] をクリックするか、既存のメタデータ エントリを編集します。
  5. 変更を保存します。

gcloud

gcloud ツールでは、追加アクションを使用してインスタンス メタデータを更新します。追加または変更するメタデータキーのみを指定します。指定したキーがすでに存在する場合は、そのキーの値が新しい値で更新されます。

gcloud コマンドライン ツールで、instances add-metadata コマンドを使用します。

gcloud compute instances add-metadata instance-name \
      --metadata bread=mayo,cheese=cheddar,lettuce=romaine

lettuce=romaine エントリを lettuce=green に変更するには、次のコマンドを使用します。

gcloud compute instances add-metadata instance-name \
    --metadata lettuce=green

lettuce=romaine エントリを削除するには、値を含めずにこの既存のキーを指定します。

gcloud compute instances remove-metadata instance-name \
    --keys lettuce

API

API では、instances().setMetadata メソッドにリクエストを送信します。新しいメタデータ値のリストと、最新の fingerprint 値を渡します。

フィンガープリントとは、Compute Engine によって生成されるランダムな文字列で、楽観的ロックを実行するために使用されます。リクエストを実行するには、一致するフィンガープリント値を指定します。フィンガープリントはリクエストのたびに変更され、一致しないフィンガープリントを指定するとリクエストが拒否されます。これにより、一度に実行できる更新が 1 つだけになるため、競合が防止されます。

インスタンスの最新のフィンガープリントを取得して、そのインスタンスの既存の Key-Value ペアを表示するには、instances().get リクエストを送信します。

GET https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance

{
 ...
 "name": "example-instance",
 "metadata": {
  "kind": "compute#metadata",
  "fingerprint": "zhma6O1w2l8="
  "items": [
   {
    "key": "foo",
    "value": "bar"
   }
  ]
 },
 ...
}

次に、instances().setMetadata メソッドにリクエストを送信して、カスタム メタデータの Key-Value ペアを設定します。インスタンスの既存の Key-Value ペアを保持する場合は、新しい Key-Value ペアとともにこのリクエストに含める必要があります。

POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata

{
 "fingerprint": "zhma6O1w2l8=",
 "items": [
  {
   "key": "foo",
   "value": "bar"
  },
  {
   "key": "baz",
   "value": "bat"
  }
 ]
}

インスタンスのすべてのメタデータの Key-Value ペアを削除するには、items プロパティを含めずに instances().setMetadata リクエストを指定します。instances().setMetadata リクエストには最新のメタデータ フィンガープリント プロパティを含める必要があります。含まれていないとリクエストが失敗します。

POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata

{
"fingerprint": "5rC_DXxBUZw="
}

プロジェクト全体のカスタム メタデータの設定

プロジェクト全体のメタデータを設定すると、そのメタデータがプロジェクトのすべてのインスタンスに適用されます。たとえば、baz=bat というプロジェクト全体のメタデータペアを定義すると、そのメタデータペアは、プロジェクトのすべてのインスタンスに自動的に適用されます。

Console

  1. Google Cloud Console で、[メタデータ] ページに移動します。

    [メタデータ] ページに移動

  2. [編集] をクリックします。
  3. メタデータ エントリを追加または編集します。
  4. 変更を保存します。

gcloud

gcloud コマンドライン ツールで、project-info add-metadata コマンドを使用します。次に例を示します。

gcloud compute project-info add-metadata \
    --metadata foo=bar,baz=bat

describe コマンドでメタデータを表示します。

gcloud compute project-info describe

次のようなレスポンスが表示されます。

...
commonInstanceMetadata:
  fingerprint: RfOFY_-eS64=
  items:
  - key: baz
    value: bat
  - key: foo
    value: bar
  - key: ssh-keys
...
等号を使用して、メタデータの Key-Value ペアを 1 つ指定します(例: key=value)。複数の Key-Value ペアを指定するにはスペースで区切ります。

--metadata-from-file フラグを使用して、メタデータの読み取り元のファイルを 1 つ以上指定することもできます。メタデータ値を削除するには project-info remove-metadata コマンドを使用します。

API

API で projects().setCommonInstanceMetadata メソッドに対するリクエストを行い、新しいメタデータ値をすべて指定します。

楽観的ロックを実行するには、必要に応じてフィンガープリントを指定します。フィンガープリントとは、Compute Engine によって生成されるランダムな文字列です。フィンガープリントはリクエストのたびに変更され、一致しないフィンガープリントを指定するとリクエストが拒否されます。

フィンガープリントを指定しない場合、整合性のチェックは行われず、projects().setCommonInstanceMetadata リクエストは成功します。この動作は、フィンガープリントを常に必要とする instances().setMetadata とは異なります。

インスタンスの最新のフィンガープリントを取得するには、project().get リクエストを実行して、フィンガープリント値をコピーします。

GET https://compute.googleapis.com/compute/v1/projects/myproject

{
 "name": "myproject",
 "commonInstanceMetadata": {
  "kind": "compute#metadata",
  "fingerprint": "FikclA7UBC0=",
  ...
}

次に、projects().setCommonInstanceMetadata メソッドにリクエストを送信して、カスタム メタデータの Key-Value ペアを設定します。

POST https://compute.googleapis.com/compute/v1/projects/myproject/setCommonInstanceMetadata

{
 "fingerprint": "FikclA7UBC0=",
 "items": [
  {
   "key": "foo",
   "value": "bar"
  }
 ]
}

カスタム メタデータのクエリ

インスタンスまたはプロジェクトのカスタム メタデータのクエリを実行するには、Cloud Console、gcloud コマンドライン ツール、または API を使用します。

Console

プロジェクト全体のカスタム メタデータを表示するには、[メタデータ] ページに移動します。

インスタンスのカスタム メタデータを表示するには:

  1. [VM インスタンス] ページに移動します。
  2. メタデータを表示するインスタンスをクリックします。
  3. [カスタム メタデータ] にインスタンスのカスタム メタデータが表示されます。

gcloud

プロジェクト メタデータのクエリを実行するには、次のコマンドを使用します。

gcloud compute project-info describe \
    --flatten="commonInstanceMetadata[]"

インスタンス メタデータのクエリを実行するには、次のコマンドを使用します。

gcloud compute instances describe example-instance \
    --flatten="metadata[]"

--flatten フラグを使用すると、関連するメタデータキーで出力のスコープを指定できます。たとえば、次のインスタンスでは、カスタム メタデータの Key-Value ペアは foo:bar です。

$ gcloud compute instances describe example-instance

...
metadata:
  fingerprint: Cad2L9eKNR0=
  items:
  - key: foo
    value: bar
  kind: compute#metadata
...

キー foo の値を問い合わせるには、次のコマンドを実行します。

gcloud compute instances describe example-instance \
    --flatten="metadata[foo]"

---
  bar

API

プロジェクト メタデータのクエリを実行するには、projects().get メソッドに対する空のリクエストを実行します。

GET https://compute.googleapis.com/compute/v1/projects/myproject

インスタンス メタデータのクエリを実行するには、instance().get メソッドに対する空のリクエストを実行します。

GET https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance

ゲスト属性の設定とクエリ

ゲスト属性は、インスタンスでの実行中にアプリケーションから書き込み可能な特定の型のカスタム メタデータです。インスタンスのアプリケーションまたはユーザーは、ゲスト属性メタデータ値にデータを書き込み、読み取ることができます。

ゲスト属性を使用するタイミング

ゲスト属性は、頻繁に変更されない少量のデータが必要なユースケースにのみ使用します。ゲスト属性は次のようなユースケースに使用します。

  • 1 つの VM インスタンスで 1 分間に実行できるクエリの数が最大 10 件に制限されている。
  • 1 秒間に増加できるクエリ数が 3 件までに制限されている。この制限を超えると、Compute Engine が書き込み中のゲスト属性を削除することがあります。他の重要なシステムデータがサーバーに確実に書き込まれるようにするため、このようなデータの削除が必要になります。

ゲスト属性は、使用頻度の低い少量のデータを公開する場合にも使用できます。たとえば、ゲスト属性は次のようなユースケースに使用されます。

  • ゲスト属性にカスタム ステータス値を設定し、起動スクリプトで、初期化の成功を通知できるようにする。
  • 構成管理エージェントで、ゲスト OS の名前とバージョンをゲスト属性に公開できるようにする。
  • インベントリ管理エージェントで、VM インスタンスにインストールされているパッケージのリストをゲスト属性に公開できるようにする。
  • ゲスト属性にカスタム ステータス値を設定し、ワークロード オーケストレーション ソフトウェアで、ゲスト内のオペレーションの完了をソフトウェア制御プレーンに通知できるようにする。

ゲスト属性は、イベント ストリーミング、Pub/Sub、または他の形式のデータ ストレージや構成リポジトリに代わるものではありません。

インスタンス内で読み取りと書き込みを行うため、メタデータ サーバーはインスタンス レベルで認証と承認を自動的に行います。各インスタンスは、自身のメタデータ サーバーに対してのみ読み書きが許可されます。他のインスタンスは別のインスタンスのメタデータ サーバーにアクセスできません。ユーザーまたはサービス アカウントがインスタンスの外部からインスタンスのゲスト属性を読み取るには、compute.instances.getGuestAttributes 権限を含む Identity and Access Management(IAM)ロールが必要です。

インスタンスでゲスト属性を有効にする

ゲスト属性はデフォルトで無効になっています。ゲスト属性を有効にするには、個々のインスタンスまたはプロジェクト全体のメタデータに必要なメタデータ値を設定します。

Console

インスタンスを作成するときにインスタンス メタデータの中で enable-guest-attributes を設定するには:

  1. Google Cloud Console で、[VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. [インスタンスを作成] をクリックします。
  3. 新しいインスタンスの作成ページで、インスタンスに必要なプロパティを入力します。
  4. [メタデータ] セクションで、キーが enable-guest-attributes で、値が TRUE であるメタデータ エントリを追加します。
  5. [作成] をクリックしてインスタンスを作成します。

プロジェクト全体のメタデータで enable-guest-attributes を設定し、プロジェクト内のすべてのインスタンスに適用するには:

  1. Google Cloud Console で、[メタデータ] ページに移動します。

    [メタデータ] ページに移動

  2. [編集] をクリックします。
  3. キーが enable-guest-attributes で値が TRUE のメタデータ エントリを追加します。この機能を無効にする場合は値を FALSE に設定します。
  4. [保存] をクリックして変更を適用します。

既存のインスタンスのメタデータに enable-guest-attributes を設定するには:

  1. Google Cloud Console で、[VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. メタデータ値を設定するインスタンスの名前をクリックします。
  3. インスタンスの詳細ページの上部にある [編集] をクリックしてインスタンス設定の編集画面を開きます。
  4. [カスタム メタデータ] で、キーが enable-guest-attributes、値が TRUE であるメタデータ エントリを追加します。インスタンスでこの機能を無効にする場合は、値を FALSE に設定します。
  5. インスタンスの詳細ページの一番下にある [保存] をクリックして変更内容をインスタンスに適用します。

gcloud

インスタンスを作成するときにインスタンス メタデータの中で enable-guest-attributes を設定するには:

gcloud コマンドライン ツールで gcloud compute instances create コマンドを使用し、enable-guest-attributes=TRUE を設定してゲスト属性を有効にします。ここで、instance-name は実際のインスタンスの名前に置き換えます。

gcloud compute instances create instance-name \
    --metadata enable-guest-attributes=TRUE

プロジェクト全体のメタデータで enable-guest-attributes を設定し、プロジェクト内のすべてのインスタンスに適用するには:

gcloud コマンドライン ツールで project-info add-metadata コマンドを使用し、enable-guest-attributes=TRUE を設定してゲスト属性を有効にします。

gcloud compute project-info add-metadata \
    --metadata enable-guest-attributes=TRUE

また、enable-guest-attributesFALSE に設定して、ゲスト属性を無効にすることもできます。

既存のインスタンスのメタデータに enable-guest-attributes を設定するには:

gcloud コマンドライン ツールで instances add-metadata コマンドを使用し、enable-guest-attributes=TRUE を設定してゲスト属性を有効にします。ここで、instance-name は実際のインスタンスの名前に置き換えます。

gcloud compute instances add-metadata instance-name \
    --metadata enable-guest-attributes=TRUE

また、enable-guest-attributesFALSE に設定して、インスタンスでゲスト属性の使用を無効にすることもできます。

ゲスト属性の設定

仮想マシン インスタンスで実行中のプロセスはゲスト属性に値を書き込むことができます。sudo や管理者レベルの権限がないスクリプトやアプリケーションも書き込むことができます。インスタンス外のユーザーまたはサービス アカウントは、ゲスト属性にメタデータ値を書き込むことができません。

たとえば、インスタンス内から curl リクエストを使用して、guest-attributes メタデータパスに値を書き込むことができます。

curl -X PUT --data "value" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"

以下を置き換えます。

  • namespace: 実際の key の論理グループ。ゲスト属性には名前空間が必要です。
  • value: 書き込む値。
  • key: 値を保存する guest-attributes 内のメタデータパス。

文字、数字、アンダースコア(_)、namespacekey フィールドのハイフン(-)のみを使用できます。

ゲスト属性の取得

ユーザーまたはサービス アカウントがゲスト属性を読み取るには、compute.instances.getGuestAttributes 権限を含む IAM ロールが必要です。インスタンス内のユーザーやアプリケーションは、そのインスタンスのメタデータ値を読み取ることができます。

仮想マシンで実行中のプロセスはゲスト属性に値を書き込むことができます。sudo や管理者レベルの権限がないスクリプトやアプリケーションも書き込むことができます。たとえば、インスタンス内から curl リクエストを使用して、guest-attributes メタデータパスから値を読み取ることができます。

curl http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"

以下を置き換えます。

  • namespace: クエリを実行する guest-attributes キーの名前空間。
  • key: メタデータ値を読み取る guest-attributes 内のパス。

1 つのリクエストですべてのゲスト属性値を取得することもできます。namespace はクエリを実行する guest-attributes キーの名前空間に置き換えます。

curl http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/ -H "Metadata-Flavor: Google"

gcloud

gcloud コマンドライン ツールを使用して、インスタンスからゲスト属性のメタデータ値を読み取ります。たとえば、インスタンスからすべての値を取得できます。

gcloud compute instances get-guest-attributes instance-name \
    --zone zone

特定の名前空間のすべての値を取得するには、--query-path フラグと定義済みの名前空間を使用します。

gcloud compute instances get-guest-attributes instance-name \
    --query-path=namespace \
    --zone zone

特定の名前空間にあるすべての値を取得するには、--query-path フラグ、名前空間、定義済みの値のキーを使用します。

gcloud compute instances get-guest-attributes instance-name \
    --query-path=namespace/key \
    --zone zone

以下を置き換えます。

  • instance-name: ゲスト属性のメタデータ値を読み取るインスタンスの名前。
  • namespace: クエリを実行する guest-attributes キーの名前空間。
  • key: 値が格納される guest-attributes メタデータ内部のパス。
  • zone: インスタンスが配置されているゾーン。

API

compute.instances.getguestattributes API メソッドを使用します。

GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace/key

以下を置き換えます。

  • project-id: 実際のプロジェクト ID。
  • zone: インスタンスが配置されているゾーン。
  • instance-name: ゲスト属性のメタデータ値を読み取るインスタンスの名前。
  • namespace: クエリを実行する guest-attributes キーの名前空間。
  • key: 値が格納される guest-attributes メタデータ内部のパス。

namespace のすべてのキーを取得するには、key を省略します。

GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace

インスタンスの各名前空間のすべてのキーを取得するには、namespacequeryPath を完全に省略します。

GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes

また、OAuth トークンがある場合は、curl を使用できます。

curl -H "Authorization: Bearer oauth-token" https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace/key

以下を置き換えます。

  • oauth-token: 実際の OAuth トークン。
  • project-id: 実際のプロジェクト ID。
  • zone: インスタンスが配置されているゾーン。
  • instance-name: ゲスト属性のメタデータ値を読み取るインスタンスの名前。
  • namespace: クエリを実行する guest-attributes キーの名前空間。
  • key: 値が格納される guest-attributes メタデータ内部のパス。

ゲスト属性の削除

ゲスト属性は削除することもできます。たとえば、curl を使用して特定のキーを削除します。

curl -X DELETE http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"

以下を置き換えます。

  • namespace: 削除する guest-attributes キーの名前空間。
  • key: 値が格納される guest-attributes 内のパス。

組織またはフォルダでゲスト属性を無効にする

組織またはフォルダ内のすべてのインスタンスでゲスト属性を無効にする場合は、ゲスト属性の機能を完全に無効にします。

組織またはフォルダに constraints/compute.disableGuestAttributesAccess 制約を設定し、project-id を実際のプロジェクトの名前に置き換えます。

gcloud resource-manager org-policies enable-enforce \
    constraints/compute.disableGuestAttributesAccess \
    --project project-id

組織に制約を設定して管理する方法については、制約の使用をご覧ください。

更新の待機

メタデータ値はインスタンスの実行中に変更される可能性があるため、メタデータ サーバーでは、wait-for-change 機能を使用して、メタデータの変更について通知を受けることができます。この機能を使用すると、指定したメタデータが変更されていた場合にのみ結果が返される、待機 HTTP GET リクエストを実行できます。この機能は、カスタム メタデータやサーバー定義メタデータでも使用できます。したがって、インスタンスやプロジェクトに変更が加えられた場合でも、カスタム メタデータが更新された場合でも、プログラムでその変更に対処できます。たとえば、tags キーに対するリクエストを実行すると、tags メタデータの内容が変更されていた場合にのみ結果が返されます。返される結果には、そのメタデータキーの新しい値が含まれます。

wait-for-change リクエストを実行するには、メタデータキーのクエリを実行し、?wait_for_change=true クエリ パラメータを追加します。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google"

指定したメタデータキーが変更されると、クエリで新しい値が返されるようになります。この例では、setInstanceTags メソッドにリクエストが送信されると新しい値が返されるようになります。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google"

cheese
lettuce

wait-for-change リクエストは、ディレクトリの内容に対して再帰的に実行することもできます。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google"

変更があった場合は、新しい内容が返されます。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google"

{"cheese":"lettuce","cookies":"cream"}

wait-for-change 機能では、リクエストとの照合タイムアウトの設定もできます。

ETag の使用

単純な wait-for-change クエリを送信すると、そのメタデータの内容が変更されていた場合にレスポンスが返されます。しかし、メタデータの更新と wait-for-change リクエストの送信の間には固有の競合状態があるため、取得するメタデータ値が最新であることを確認できる確実な方法があると便利です。

その方法として使用できるのが last_etag クエリ パラメータです。このクエリ パラメータは、リクエストで指定された ETag 値と、メタデータ サーバーに保存されている ETag 値を比較します。ETag 値が一致した場合は、wait-for-change リクエストが受け入れられます。ETag 値が一致しない場合は、前回 ETag 値を取得してからメタデータの内容が変更されていることになります。この場合は、その最新の値が直ちに返されます。

メタデータキーの最新の ETag 値を取得するには、そのキーに対するリクエストを送信して、ヘッダーを表示します。curl でこれを行うには、-v フラグを使用します。

user@myinst:~$ curl -v "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google"
* About to connect() to metadata port 80 (#0)
*   Trying 169.254.169.254... connected
* Connected to metadata (169.254.169.254) port 80 (#0)
> GET /computeMetadata/v1/instance/tags HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
> Host: metadata
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/text
< ETag: 411261ca6c9e654e
< Date: Wed, 13 Feb 2013 22:43:45 GMT
< Server: Metadata Server for VM
< Content-Length: 26
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
<
cheese
lettuce

次に、その ETag 値を使用して wait-for-change リクエストを送信します。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&last_etag=411261ca6c9e654e" -H "Metadata-Flavor: Google"

指定した ETag 値がメタデータ サーバーで照合され、値が変更されていた場合は、メタデータキーの新しい内容が返されます。

次の Python サンプルは、メタデータ サーバーの変更をプログラムで監視する方法を示しています。

last_etag = '0'

while True:
    r = requests.get(
        url,
        params={'last_etag': last_etag, 'wait_for_change': True},
        headers=METADATA_HEADERS)

    # During maintenance the service can return a 503, so these should
    # be retried.
    if r.status_code == 503:
        time.sleep(1)
        continue
    r.raise_for_status()

    last_etag = r.headers['etag']

タイムアウトの設定

wait-for-change リクエストで、一定の秒数が経過するとリクエストがタイムアウトになるようにするには、timeout_sec=<timeout-in-seconds> クエリ パラメータを設定します。timeout_sec パラメータは、リクエストの待機時間を指定の秒数に制限します。その制限に達すると、メタデータキーの現在の内容が返されます。360 秒後にタイムアウトになるように設定された wait-for-change リクエストの例を次に示します。

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&timeout_sec=360" -H "Metadata-Flavor: Google"

timeout_sec パラメータを設定した場合、指定の秒数が経過すると、メタデータ値が実際に変更されているかどうかに関係なく、常に結果が返されます。タイムアウトに設定できるのは整数値だけです。

ステータス コード

wait-for-change リクエストを実行すると、リクエストが成功したかどうかを示す標準の HTTP ステータス コードが返されます。結果がエラーになる場合は、ネットワークの状態が原因でリクエストが失敗して、エラーコードが返されている可能性があります。そのような場合は、それらのエラーが認識されて適切に処理されるようにして、アプリケーションをフォールト トレラントにする必要があります。

メタデータ サーバーから返される可能性があるステータスを以下に示します。

ステータス 説明
HTTP 200 成功です。値が変更されたか、指定されている timeout_sec に達したため、リクエストは正常に終了しました。
Error 400 リクエストが無効です。クエリを修正してリクエストを再試行してください。
Error 404 指定したメタデータ値は存在しません。このエラーは、変更の待機中にメタデータが削除された場合にも返されます。
Error 503 一時的なサーバーエラーか一時的なメンテナンス イベントが発生しました。リクエストを再試行してください。

ライブ マイグレーションの通知取得

メタデータ サーバーは、scheduling/ ディレクトリと maintenance-event 属性を通して、インスタンスのスケジュール オプションと設定に関する情報を提供します。これらの属性を使用すると、仮想マシンのインスタンスのスケジュール オプションに関する情報を確認できます。また、このメタデータを使用すると、maintenance-event 属性を通じてメンテナンス イベントがいつ実施されるかを確認できます。デフォルトでは、すべての仮想マシン インスタンスにライブ マイグレーションが設定されています。このため、VM インスタンスにライブ マイグレーションが行われる前に、メタデータ サーバーがメンテナンス イベントの通知を受信します。メンテナンス時に VM インスタンスを停止するように選択している場合には、Compute Engine は VM インスタンスを自動的に停止します。automaticRestart 属性が設定されている場合には、インスタンスを再起動します。メンテナンス イベントとイベント発生時のインスタンスの動作については、スケジュール オプションと設定をご覧ください。

メンテナンス イベントが発生した際に通知を受けるようにするには、maintenance-event 属性に対するクエリを定期的に実行します。この属性の値は、メンテナンス イベントが開始される 60 秒前に変更されるため、アプリケーションのコードで、メンテナンス イベントの前に実行するタスク(データのバックアップ、ログの更新など)をトリガーするために使用できます。Compute Engine には、メンテナンス イベントの通知を確認できる Python スクリプトのサンプルが用意されています。

Compute Engine は、次の場合にのみ 60 秒警告を表示します。

  • メンテナンス イベントの発生時にライブ マイグレーションを実行するようにインスタンスの可用性オプションが設定されている。

  • 前回のメンテナンス イベント後に少なくとも 1 回 maintenance-event 属性に対するクエリを実行している。maintenance-event 属性に対するクエリが一度も実行されていない場合や前回のマイグレーション後に実行されていない場合は、Compute Engine により、そのインスタンスでのメンテナンス イベントの事前警告は不要と見なされます。この場合、60 秒警告はスキップされて、直ちにメンテナンス イベントが開始されます。60 秒警告がスキップされないようにするには、クライアント コードでマイグレーション イベントの合間に少なくとも 1 回 maintenance-event 属性に対するクエリが実行されるようにしてください。

maintenance-event 属性に対するクエリを実行するには、次のコマンドを使用します。

user@myinst:~$ curl http://metadata.google.internal/computeMetadata/v1/instance/maintenance-event -H "Metadata-Flavor: Google"

NONE

maintenance-event 属性の初期値とデフォルト値は NONE です。

  • GPU インスタンスの場合、属性は、メンテナンス イベント中に NONE から TERMINATE_ON_HOST_MAINTENANCE に変更されます。この属性は、停止イベントの開始 60 分前に更新されます。

  • GPU を使用しないスケジュール オプションが migrate のインスタンスの場合、maintenance-event 属性は次のように変更されます。

    1. マイグレーション イベントの開始時に、値は NONE から MIGRATE_ON_HOST_MAINTENANCE に変更されます。この属性は、停止イベントの開始 60 秒前に更新されます。
    2. イベントの期間中、VM インスタンスがライブ マイグレーションされている間、値は MIGRATE_ON_HOST_MAINTENANCE のままとなります。
    3. メンテナンス イベントが終了すると NONE に戻ります。

maintenance-event 属性を更新の待機機能とともに使用すると、メンテナンス イベントの開始時と終了時にスクリプトやアプリケーションに通知できます。これにより、イベントの前後に実行するアクションを自動化できます。次の Python サンプルは、この 2 つの機能を組み合わせて実装する方法を示しています。

メンテナンス イベントをクエリする Python スクリプトのサンプル


import time

import requests

METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/'
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}

def wait_for_maintenance(callback):
    url = METADATA_URL + 'instance/maintenance-event'
    last_maintenance_event = None
    last_etag = '0'

    while True:
        r = requests.get(
            url,
            params={'last_etag': last_etag, 'wait_for_change': True},
            headers=METADATA_HEADERS)

        # During maintenance the service can return a 503, so these should
        # be retried.
        if r.status_code == 503:
            time.sleep(1)
            continue
        r.raise_for_status()

        last_etag = r.headers['etag']

        if r.text == 'NONE':
            maintenance_event = None
        else:
            maintenance_event = r.text

        if maintenance_event != last_maintenance_event:
            last_maintenance_event = maintenance_event
            callback(maintenance_event)

def maintenance_callback(event):
    if event:
        print('Undergoing host maintenance: {}'.format(event))
    else:
        print('Finished host maintenance')

def main():
    wait_for_maintenance(maintenance_callback)

if __name__ == '__main__':
    main()

サーバー エンドポイントのバージョンの確認

最新バージョン: v1

Compute Engine では、複数のバージョンのメタデータが提供されることがありますが、常に最新のバージョンを使用することをおすすめします。Compute Engine では、メタデータ サーバーへの新しいエントリの追加や、レスポンスへの新しいフィールドの追加が常に行われています。定期的に変更の有無を確認してください。

メタデータ サーバー エンドポイントのバージョンを確認するには、サーバーへのリクエストに使用している URI を確認します。

メタデータ エンドポイントのバージョン URI
v0.1(非推奨) http://metadata.google.internal/0.1/meta-data/…
v1beta1(非推奨) http://metadata.google.internal/computeMetadata/v1beta1/…
v1 http://metadata.google.internal/computeMetadata/v1/…

以前のエンドポイントの無効化

v0.1 と v1beta1 のメタデータ サーバー エンドポイントのシャットダウンに備えて、これらのエンドポイントをプロジェクト レベルまたはインスタンス レベルで無効にできます。

v0.1 と v1beta1 のメタデータ サーバー エンドポイントを無効にするには、カスタム メタデータを設定する手順に従って、disable-legacy-endpoints=TRUE を設定します。

たとえば、メタデータ サーバー エンドポイントを無効にするには、プロジェクト レベルで gcloud コマンドライン ツールを使用し、次のコマンドを実行します。

gcloud compute project-info add-metadata \
    --metadata disable-legacy-endpoints=TRUE 

v1 メタデータ サーバー エンドポイントへの移行

v0.1 または v1beta1 からの v1 エンドポイントへの移行については、v1 メタデータ サーバー エンドポイントへの移行をご覧ください。

次のステップ