儲存和擷取執行個體中繼資料

每個執行個體都會將其中繼資料儲存在中繼資料伺服器上。您可以透過程式化的方式,從執行個體及 Compute Engine API 向此中繼資料伺服器查詢有關執行個體的資訊,例如執行個體的主機名稱、執行個體 ID、啟動與關閉指令碼、自訂中繼資料及服務帳戶資訊。您的執行個體可自動存取中繼資料伺服器 API,而無需其他任何授權。

中繼資料伺服器與開機關機指令碼搭配使用時會特別有用,因為您可以使用中繼資料伺服器,透過程式取得有關執行個體的唯一資訊,而無需其他授權。例如,您可以編寫啟動指令碼,取得執行個體外部 IP 的中繼資料鍵/值組合,並在指令碼中使用該 IP 設定資料庫。 由於所有執行個體上的預設中繼資料鍵都相同,因此您可以重複使用指令碼,而無需為每個執行個體進行更新。這可以協助您為應用程式建立較不易出錯的程式碼。

中繼資料以 key:value 格式儲存。每個執行個體都有一組執行個體可以存取的預設中繼資料項目。您也可以設定自訂中繼資料

如要存取中繼資料伺服器,您可以查詢中繼資料網址

目前版本:v1

Compute Engine 一次可提供超過一個的中繼資料版本,但我們建議您一律使用最新可用的中繼資料伺服器版本。任何時候,Google Compute Engine 都可將新項目新增至中繼資料伺服器,以及將新欄位新增至回應。請定期回來查看變化情況!

事前準備

此工作需要的權限

如要執行這項工作,您必須具備以下權限

  • 執行個體的 compute.instances.setMetadata 權限 (如要設定有關該執行個體的中繼資料)
  • 專案的 compute.projects.setCommonInstanceMetadata 權限 (如要設定全專案的中繼資料)
  • 專案的 compute.projects.get 權限 (如果只是要取得中繼資料)
  • 執行個體的 compute.instances.get 權限 (如果只是要取得中繼資料)

專案與執行個體中繼資料

可以在專案與執行個體層級指派中繼資料。專案層級中繼資料會傳播至專案內的所有虛擬機器執行個體,而執行個體層級中繼資料只會對該執行個體產生影響。

預設中繼資料鍵

Google 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 Login 安全殼層 (SSH) 金鑰組管理功能。
attributes/vmdnssetting 設定如何針對專案中的執行個體將內部 DNS 名稱格式化。如要進一步瞭解內部 DNS 名稱,請參閱設定 DNS 名稱
attributes/ssh-keys 如果您的專案或執行個體未設定為使用 OS Login 來管理安全殼層 (SSH) 金鑰組,這個屬性能讓您設定可連線至此專案中執行個體的公開安全殼層 (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 Platform 主控台中可見的專案名稱不同。這個值與 project-id 中繼資料項目值不同。
project-id 專案 ID

以下是執行個體的預設中繼資料清單:

相對於 http://metadata.google.internal/computeMetadata/v1/instance/
中繼資料項目 說明
attributes/ 在啟動或關閉期間傳送至執行個體之自訂中繼資料值的目錄。請參閱以下指定自訂中繼資料
attributes/enable-oslogin 設定 enable-oslogin=TRUE 時,可在此執行個體中啟用 OS Login 安全殼層 (SSH) 金鑰組管理功能。
attributes/vmdnssetting 設定如何針對此執行個體將內部 DNS 名稱格式化。如要進一步瞭解內部 DNS 名稱,請參閱設定 DNS 名稱
attributes/ssh-keys 如果您的執行個體未設定為使用 OS Login 來管理安全殼層 (SSH) 金鑰組,這個屬性能讓您設定可連線至此執行個體的公開安全殼層 (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。這是由 Google Compute Engine 產生的唯一數值 ID。如果您不想要使用執行個體名稱,這對識別執行個體而言很有用。
machine-type 此執行個體機器類型的中繼資料值,格式如下:projects/[NUMERIC_PROJECT_ID]/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>/identity 對執行個體而言唯一的 JSON Web Token。您必須針對此執行個體中繼資料值,將「audience」參數包含在要求中。例如,「?audience=http://www.example.com」。請參閱驗證執行個體身分一文,瞭解如何要求及驗證執行個體身分憑證。
tags 與執行個體相關聯的任何標記
zone 此執行個體所在區域的中繼資料值,格式如下:projects/[NUMERIC_PROJECT_ID]/zones/[ZONE]

取得中繼資料

您可以從虛擬機器執行個體內提出對以下根網址的要求,查詢中繼資料伺服器的內容。請使用 http://metadata.google.internal/computeMetadata/v1/ 網址對中繼資料伺服器提出要求。

所有中繼資料值都會定義為這些根網址下的子路徑。

您只能從關聯執行個體內查詢預設中繼資料值,無法從其他執行個體,或直接從本機電腦查詢執行個體的預設中繼資料。您可以使用例如 curlwget 之類的標準工具,從執行個體查詢其中繼資料伺服器。

當您查詢中繼資料時,必須在所有要求中提供下列標頭:

Metadata-Flavor: Google

此標頭指示是在擷取中繼資料值的意圖之下傳送要求,而非隨意從不安全的來源傳送,並允許中繼資料伺服器傳回您要求的資料。如果您不提供此標頭,中繼資料伺服器會拒絕您的要求。

X-Forwarded-For 標頭

包含 X-Forwarded-For 標頭的任何要求都將自動遭到中繼資料伺服器的拒絕。此標頭一般指示要求經由 Proxy 傳送,可能不是由授權使用者提出的要求。基於安全性考量,將一律拒絕這類要求。

限制

請注意,使用 curl 指令從伺服器擷取中繼資料時,要求路徑不支援部分編碼字元。編碼字元僅在查詢路徑受到支援。

舉例來說,下列要求可能無法運作:

http://metadata.goog/computeMetadata/v1/instance/service-accounts/123456789-compute%40developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true

若要執行此要求,您必須將要求路徑 (%40) 中不支援的編碼字元替換為相等的可接受值 (@)。

http://metadata.goog/computeMetadata/v1/instance/service-accounts1234567898-compute@developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true

下表大致列出要求路徑中不支援的編碼字元。

編碼字元 可接受的值
%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/ 目錄,可以查詢該目錄的特定網址:

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

device-name
index
mode
type

查詢端點

如果中繼資料鍵不是目錄,就是傳回一或多個值的端點。例如,如要查詢特定磁碟的模式,請查詢下列端點:

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

READ_WRITE

每個端點都預設有回應的預先定義格式。某些端點可能會預設傳回 JSON 格式的資料,而其他端點則可能會將資料傳回為字串。您可以使用 alt=jsonalt=text 查詢參數覆寫預設資料格式規格,這兩個參數分別會傳回 JSON 字串格式的資料,或傳回為純文字表示。

例如,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

設定自訂中繼資料

您可以從 Google Cloud Platform 主控台gcloud 指令列工具或 Compute Engine API 設定執行個體或專案的自訂中繼資料。自訂中繼資料很適合用來將任意值傳入至您的專案或執行個體,也適合用於設定開機關機指令碼。

自訂中繼資料大小限制

Google Compute Engine 會對自訂中繼資料值的長度強制下列限制:

  • 每個個別中繼資料項目為 256 KB
  • 每個執行個體的所有中繼資料項目合併總計為 512 KB

特別的是,安全殼層 (SSH) 金鑰組會在 ssh-keys 金鑰下儲存為自訂中繼資料。 如果這個金鑰的中繼資料內容超出 256 KB 的限制,您將無法新增更多安全殼層 (SSH) 金鑰組。如果您遇到這個限制,請考慮移除不使用的金鑰以為新金鑰釋出中繼資料空間。

如果您直接提供開機關機指令碼內容,開機與關機指令碼內容也可能儲存為自訂中繼資料,並計入這些大小限制。為了避免發生這種情況,請將您的開機關機指令碼儲存為檔案,並將其放在例如 Google Cloud Storage 之類的外部位置託管,然後在建立執行個體時提供啟動指令碼網址。這些檔案將會下載到 VM 執行個體,而非儲存在中繼資料伺服器中。

設定執行個體中繼資料

請在 GCP 主控台gcloud 工具或 API 中為執行個體設定自訂中繼資料。執行個體中繼資料僅適用於特定執行個體。

在建立執行個體期間設定中繼資料

主控台

gcloud

透過 gcloud 指令列工具使用 --metadata 標記來設定自訂中繼資料。

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

API

在 API 中,提供自訂中繼資料做為要求中中繼資料屬性的一部分:

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

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

在執行中執行個體上更新中繼資料

主控台

  1. 前往「VM instances」(VM 執行個體) 頁面
  2. 按一下您要更新中繼資料的執行個體。
  3. 按一下頁面頂端的 [Edit] (編輯) 按鈕。
  4. 在「Custom metadata」(自訂中繼資料)下,按一下 [Add item] (新增項目) 或編輯現有中繼資料項目。
  5. 儲存變更。

gcloud

使用 gcloud 工具更新執行個體中繼資料是一個附加的動作。請僅指定您要新增或變更的中繼資料鍵。如果您提供的鍵已經存在,該鍵的值就會更新為新值。

透過 gcloud 指令列工具使用 instances add-metadata 指令:

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

如果您要將 lettuce=romaine 項目變更為 lettuce=green,請使用:

gcloud compute instances add-metadata INSTANCE --metadata lettuce=green

如果您要移除 lettuce=romaine 項目,請指定現有鍵並排除值。

gcloud compute instances remove-metadata INSTANCE --keys lettuce

API

在 API 中,對 instances().setMetadata 方法提出要求。請提供新中繼資料值與目前 fingerprint 值的清單。

指紋是由 Compute Engine 產生的隨機字元字串,可用來執行樂觀鎖定。請提供相符的指紋值,以執行您的要求。在每次要求之後,指紋都會變更,如果您提供不符的指紋,您的要求便會遭到拒絕。如此一來,一次就只能進行一項更新,而能夠防止發生衝突。

如要取得執行個體的目前指紋,請參閱執行個體的任何現有鍵/值組合。請傳送 instances().get 要求:

GET https://www.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 方法提出要求,並設定您的自訂中繼資料鍵/值組合。如果您想要保留執行個體的現有鍵/值組合,您必須將其包含在對新鍵/值組合提出的這個要求中:

POST https://www.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"
  }
 ]
}

如要從執行個體中移除所有中繼資料鍵/值組合,請指定 instances().setMetadata 要求並排除 items 屬性。請注意,您仍必須包含目前中繼資料指紋屬性,此要求才能成功:

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

{
 "fingerprint": "5rC_DXxBUZw="
}

設定全專案自訂中繼資料

請設定全專案中繼資料,將中繼資料套用至專案中的所有執行個體。 例如,如果您定義 baz=bat 的全專案中繼資料組合,該中繼資料組合會自動套用至專案中的所有執行個體。

主控台

  1. 前往「Metadata」(中繼資料) 頁面
  2. 按一下 [Edit] (編輯)
  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。多個鍵值組合使用空格分隔。

您可以視情況使用 --metadata-from-file 標記,指定要從中讀取中繼資料的一或多個檔案。您可以使用 project-info remove-metadata 指令移除中繼資料值。

API

在 API 中,向 projects().setCommonInstanceMetadata 方法提出要求,提供所有新中繼資料值與 fingerprint 值。

指紋是由 Compute Engine 產生的隨機字元字串,可用來執行樂觀鎖定。請提供相符的指紋值,以執行您的要求。在每次要求之後,指紋都會變更,如果您提供不符的指紋,您的要求便會遭到拒絕。如此一來,一次就只能進行一項更新,而能夠防止發生衝突。

如要取得執行個體的目前指紋,請執行 project().get 要求並複製指紋值:

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

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

接下來,對 projects().setCommonInstanceMetadata 方法提出要求,並設定您的自訂中繼資料鍵/值組合:

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

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

查詢自訂中繼資料

請透過 GCP 主控台、gcloud 指令列工具或 API 查詢自訂執行個體或專案中繼資料。

主控台

如要查看全專案自訂中繼資料,請前往「Metadata」(中繼資料) 頁面。

查看執行個體的自訂中繼資料:

  1. 前往「VM instances」(VM 執行個體) 頁面
  2. 按一下您要檢視中繼資料的執行個體。
  3. 在「Custom metadata」(自訂中繼資料)下,查看執行個體的自訂中繼資料。

gcloud

查詢全專案中繼資料:

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

查詢執行個體中繼資料:

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

--flatten 標記可以用來將輸出的範圍限定在相關中繼資料鍵之內。以下範例是一個具有 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://www.googleapis.com/compute/v1/projects/myproject

如要查詢執行個體的中繼資料,請對 instance().get 方法執行空白要求:

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

設定和查詢訪客屬性

訪客屬性是應用程式在您的執行個體上執行時可以寫入的特定類型的自訂中繼資料。執行個體上的任何應用程式或使用者都可以讀取這些訪客屬性中繼資料值,以及將資料寫入其中。

使用訪客屬性的時機

請僅將訪客屬性用於不會經常變更的少量必要資料的用途。訪客屬性的最佳用途具有以下特性:

  • 每個 VM 執行個體的查詢數限制為每分鐘最多 10 次查詢。
  • 查詢作業每秒不超過 3 次查詢。如果超過這個次數上限,Compute Engine 可能會任意移除正在寫入的訪客屬性。您必須移除這項資料,才能確保將其他重要系統資料寫入伺服器。

訪客屬性適用於必須發布不頻繁和少量資料的情況。例如,訪客屬性適用於以下用途:

  • 開機指令碼可以透過在訪客屬性中設定自訂狀態值來表示初始化成功。
  • 設定管理代理程式可以將客體 OS 名稱和版本發布至訪客屬性。
  • 庫存管理代理程式可以將安裝在 VM 中的套件的清單發布至訪客屬性。
  • 工作負載自動化調度管理軟體可以透過在訪客屬性中設定自訂狀態值,將客體中作業完成信號通知軟體控制層。

訪客屬性不能取代事件串流、Cloud Pub/Sub 或其他形式的資料儲存空間和設定存放區。

對於執行個體內部的讀取和寫入作業,中繼資料伺服器會提供自動化的執行個體層級驗證和授權。每個執行個體都只能讀取或寫入自己的中繼資料伺服器。其他執行個體無法存取另一個執行個體的中繼資料伺服器。使用者和服務帳戶只有在具備提供 compute.instances.getGuestAttributes 權限的身分與存取權管理角色時,才能從執行個體外部讀取執行個體訪客屬性。

在執行個體上啟用訪客屬性

根據預設,訪客屬性會處於停用狀態。如要啟用訪客屬性,請在個別執行個體或全專案中繼資料中設定必要的中繼資料值:

主控台

在建立執行個體時,在執行個體中繼資料內設定 enable-guest-attributes

  1. 在 GCP 主控台中,前往「VM Instances」(VM 執行個體) 頁面。

    前往「VM instances」(VM 執行個體) 頁面

  2. 點選 [Create instance] (建立執行個體)
  3. 在「Create a new instance」(建立新執行個體) 頁面上,填入您要為執行個體設定的屬性。
  4. 在「Metadata」(中繼資料) 區段,新增鍵為 enable-guest-attributes、值為 TRUE 的中繼資料項目。
  5. 按一下 [Create] (建立),建立執行個體。

在全專案範圍的中繼資料內設定 enable-guest-attributes,以將其套用至您專案中的所有執行個體:

  1. 前往「Metadata」(中繼資料) 頁面
  2. 按一下 [Edit] (編輯)
  3. 新增鍵為 enable-guest-attributes、值為 TRUE 的中繼資料項目。或者,將值設為 FALSE 則可停用這項功能。
  4. 按一下 [Save] (儲存) 以套用變更內容。

在現有執行個體的中繼資料內設定 enable-guest-attributes

  1. 前往「VM instances」(VM 執行個體) 頁面
  2. 按一下您要設定中繼資料值的執行個體名稱。
  3. 在執行個體詳細資料頁面頂端,按一下 [Edit] (編輯) 即可編輯執行個體設定。
  4. 在「Custom metadata」(自訂中繼資料) 下,新增鍵為 enable-guest-attributes、值為 TRUE 的中繼資料項目。或者,將值設為 FALSE 則可為執行個體停用這項功能。
  5. 在執行個體詳細資料頁面的底端,按一下 [Save] (儲存) 將變更套用到執行個體。

gcloud

在建立執行個體時,在執行個體中繼資料內設定 enable-oslogin-2fa

使用 gcloud 指令列工具中的 gcloud compute instances create 指令,然後設定 enable-guest-attributes=TRUE 以啟用訪客屬性:

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-attributes 設為 FALSE,以停用訪客屬性。

在現有執行個體的中繼資料內設定 enable-guest-attributes

使用 gcloud 指令列工具中的 instances add-metadata 指令,然後設定 enable-guest-attributes=TRUE 以啟用訪客屬性:

gcloud compute instances add-metadata [INSTANCE_NAME] --metadata enable-guest-attributes=TRUE

您也可以將 enable-guest-attributes 設定為 FALSE,讓執行個體停用訪客屬性。

設定訪客屬性

在虛擬機器中執行的任何程序都可以寫入訪客屬性值,包括沒有 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 中的路徑。

取得訪客屬性

如果使用者或服務帳戶具有提供 compute.instances.getGuestAttributes 權限的身分與存取權管理角色,他們就可以讀取訪客屬性。或者,執行個體中的任何使用者或應用程式都可以讀取該特定執行個體的中繼資料值。

在虛擬機器中執行的任何程序都可以寫入訪客屬性值,其中包括沒有 sudo 或管理員層級權限的指令碼和應用程式。例如,您可以在執行個體中使用 curl 要求從 guest-attributes 中繼資料路徑中讀取值:

curl http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/[NAMESPACE]/[KEY] -H "Metadata-Flavor: Google"

其中:[KEY] 是您要從中讀取中繼資料值的 guest-attributes 內的路徑。

或者,您也可以在一個要求中傳回所有訪客屬性值:

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

其中:

  • [NAMESPACE][KEY] 的邏輯分組。訪客屬性必須具有命名空間。
  • [KEY] 是儲存值的 guest-attributes 中的路徑。

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] 是要從中讀取訪客屬性中繼資料值的執行個體的名稱。
  • [KEY] 是儲存值的 guest-attributes 中繼資料內的路徑。
  • [ZONE] 是執行個體所在的區域。

API

使用 compute.instances.getguestattributes API 方法:

GET https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]/getGuestAttributes?queryPath=[NAMESPACE]/[KEY]

其中:

  • [PROJECT_ID] 是您的專案 ID。
  • [ZONE] 是執行個體的所在區域。
  • [INSTANCE_NAME] 是要從中讀取訪客屬性中繼資料值的執行個體的名稱。
  • [KEY] 是儲存值的 guest-attributes 中繼資料內的路徑。

如要擷取 [NAMESPACE] 的所有鍵,請省略 [KEY]

GET https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]/getGuestAttributes?queryPath=[NAMESPACE]

如要擷取執行個體中每個命名空間中的所有鍵,請完全省略 [NAMESPACE]queryPath

GET https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]/getGuestAttributes

如果您有 OAuth 憑證,也可以使用 curl

curl -H "Authorization: Bearer [OAUTH_TOKEN]" https://www.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][KEY] 的邏輯分組。訪客屬性必須具有命名空間。
  • [KEY] 是儲存值的 guest-attributes 中繼資料內的路徑。

刪除訪客屬性

您也可以刪除訪客屬性。例如,使用 curl 刪除特定鍵:

curl -X DELETE http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/[NAMESPACE]/[KEY] -H "Metadata-Flavor: Google"

其中:

  • [NAMESPACE][KEY] 的邏輯分組。訪客屬性必須具有命名空間。
  • [KEY] 是儲存值的 guest-attributes 中的路徑。

停用機構或資料夾的訪客屬性

如果您不希望機構或資料夾中的任何執行個體啟用訪客屬性,則可以完全覆寫和停用該功能。

在機構或資料夾上設定 constraints/compute.disableGuestAttributesAccess 限制:

gcloud resource-manager org-policies enable-enforce \
    constraints/compute.disableGuestAttributesAccess --project [PROJECT_ID]

其中:[PROJECT_ID] 是您的專案名稱。

請參閱使用限制一文,以進一步瞭解如何設定和管理對於機構的限制。

等待更新

在中繼資料值可在您的執行個體執行中時變更的前提下,中繼資料伺服器可讓您使用等待變更功能收到中繼資料變更通知。此功能可讓您執行等待 HTTP GET 要求,該要求只會在您指定的中繼資料已變更時傳回。您可以對自訂中繼資料或伺服器定義的中繼資料使用此功能,以便當您的執行個體或專案發生任何變更,或者有人更新自訂中繼資料時,您就可以透過程式方式對變更做出反應。例如,您可對 tags 鍵執行要求,如此就只會在標記中繼資料的內容變更時才傳回要求。要求傳回時,會提供該中繼資料鍵的新值。

如要執行等待變更要求,請查詢中繼資料鍵並附加 ?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

您也能夠以遞迴方式,對目錄的內容執行等待變更要求:

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"}

等待變更功能也可讓您與您的要求進行比對以及設定逾時

使用 ETag

當您提交簡單的等待變更查詢時,如果在中繼資料內容中發生任何變更,中繼資料伺服器就會傳回回應。但是,在中繼資料更新與等待變更要求之間發出了繼承競爭狀況,所以找到一種可靠的方法來知道您正在取得最新的中繼資料值很有幫助。

為了達成此目標,您可以使用 last_etag 查詢參數,它會將您提供的 ETag 值與儲存在中繼資料伺服器中的 ETag 值進行比較。如果 ETag 值相符,則將會接受等待變更要求。如果 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 值:

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']

設定逾時

如果您想要您的等待變更要求在一定的秒數之後逾時,可以設定 timeout_sec=<timeout-in-seconds> 查詢參數。timeout_sec 參數會將您要求的等待時間限制於您指定的秒數,而當要求達到該限制時,就會傳回中繼資料鍵的目前值。以下是將逾時設定為 360 秒後的等待變更要求範例:

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

當您設定 timeout_sec 參數時,無論中繼資料值是否已實際發生變更,要求都一律會在指定秒數之後傳回。您只能為逾時設定整數值。

狀態碼

當您執行等待變更要求時,中繼資料伺服器會傳回標準 HTTP 狀態碼以指示成功或失敗。發生錯誤時,網路狀況可能會導致中繼資料伺服器拒絕您的要求,並傳回錯誤碼。在這種情況下,您應將應用程式設計成能夠容錯,並且能夠辨識及處理這些錯誤。

中繼資料伺服器可能傳回的狀態有:

狀態 說明
HTTP 200 成功!值已變更,或者您已達到指定的 timeout_sec,且要求已成功傳回。
Error 400 您的要求無效。請修正查詢,並重試要求。
Error 404 您指定的中繼資料值不再存在。如果您的中繼資料在您等待變更時遭到刪除,中繼資料伺服器也會傳回此錯誤。
Error 503 發生暫時伺服器錯誤或暫時維護事件。 重試要求。

取得即時遷移通知

中繼資料伺服器透過 scheduling/ 目錄和 maintenance-event 屬性,提供執行個體排程選項與設定的相關資訊。您可以使用這些屬性瞭解虛擬機器執行個體的相關排程選項,並使用此中繼資料,在即將發生維護事件時,透過 maintenance-event 屬性通知您。所有虛擬機器執行個體預設都設定為即時遷移,如此中繼資料伺服器就會在即時遷移 VM 執行個體之前收到維護事件通知。如果您選擇在維護期間終止您的 VM 執行個體,並且設定了 automaticRestart 屬性,Compute Engine 將會自動終止並視情況重新啟動您的 VM 執行個體。如要進一步瞭解維護事件與事件期間的執行個體行為,請參閱排程選項與設定一文。

您可以定期查詢 maintenance-event 屬性,瞭解何時會發生維護事件。這個屬性的值將會在維護事件開始前 60 秒發生,讓您的應用程式程式碼能夠在維護事件之前觸發您要執行的任何工作,例如備份資料或更新記錄。Compute Engine 也提供範例 Python 指令碼,以示範如何檢查維護事件通知。

只有在以下情況下,Compute Engine 才會提供 60 秒的警告:

  • 您已將執行個體的可用性選項設定為在維護期間即時遷移。

  • 您在上次維護事件之後已查詢 maintenance-event 屬性至少一次。如果您從未查詢過 maintenance-event 屬性,或自從上次遷移之後並未查詢該屬性,Compute Engine 會假定執行個體並不需要維護事件的提前警告。維護事件會立即啟動,跳過 60 秒的警告期。如果您不想跳過 60 秒的警告期,請確保您的用戶端程式碼在兩次遷移事件之間查詢 maintenance-event 屬性至少一次。

查詢 maintenance-event 屬性:

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

NONE

maintenance-event 屬性的初始與預設值為 NONE。在透明維護事件開始前,maintenance-event 值:

  1. 會從 NONE 變更為 MIGRATE_ON_HOST_MAINTENANCE
  2. 在事件期間及您的 VM 正在進行即時遷移時,值會保持為 MIGRATE_ON_HOST_MAINTENANCE
  3. 當維護事件結束時,值會恢復為 NONE

您可以透過等待更新功能使用 maintenance-event 屬性,通知您的指令碼與應用程式維護事件何時即將開始及結束。這可以讓您自動執行您想要在事件之前或之後執行的任意動作。以下 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

v1 中繼資料伺服器的功能與舊版的 v1beta1 伺服器稍有不同。以下是需要針對新中繼資料伺服器進行的一些更改:

  • 更新中繼資料要求以包含 Metadata-Flavor: Google 標頭

    新中繼資料伺服器需要所有要求都提供 Metadata-Flavor: Google 標頭,這表示要求是在擷取中繼資料值的意圖之下提出的,請更新您的要求以包含此新標頭。例如,對 disks/ 屬性提出的要求現在看起來像以下這樣:

    user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/" -H "Metadata-Flavor: Google"
    
  • 更新使用 X-Forwarded-For 標頭的要求

    伺服器會自動拒絕這些要求,因為這一般表示要求是透過 Proxy 傳送的。請更新您的要求,使其不包含此標頭。

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Compute Engine 說明文件