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

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

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

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

如要存取中繼資料伺服器,請查詢 http://metadata.google.internal/computeMetadata/v1/ 網址。詳情請參閱查詢中繼資料一文。

目前版本: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 登入安全殼層 (SSH) 金鑰組管理功能。
attributes/vmdnssetting 設定如何針對專案中的執行個體將內部 DNS 名稱格式化。如要進一步瞭解內部 DNS 名稱,請參閱設定 DNS 名稱
attributes/ssh-keys 如果您的專案或執行個體未設為使用 OS 登入來管理 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 登入安全殼層 (SSH) 金鑰組管理功能。
attributes/vmdnssetting 設定如何針對此執行個體將內部 DNS 名稱格式化。如要進一步瞭解內部 DNS 名稱,請參閱設定 DNS 名稱
attributes/ssh-keys 如果您的執行個體未設為使用 OS 登入來管理 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/ 附加至此執行個體的磁碟目錄。
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 傳送,可能不是由授權使用者提出的要求。針對安全上的理由,所有此類要求都會遭到拒絕。

中繼資料資訊是否安全?

當您提出從中繼資料伺服器取得資訊的要求時,您的要求與後續中繼資料回應永遠不會離開執行虛擬機器執行個體的實體主機。

查詢目錄清單

中繼資料伺服器使用目錄來組織某些中繼資料鍵。任何以斜線結尾的中繼資料項目都是目錄。例如,disks/ 項目就是附加至該執行個體的磁碟目錄:

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

0/
1/
2/

同樣的,如果您需要更多有關 1/ 目錄的資訊,可向特定網址查詢該目錄:

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

device-name
index
mode
type

查詢端點

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

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/1/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 執行個體頁面。
  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. 前往中繼資料頁面。
  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 查詢自訂執行個體或專案中繼資料。

主控台

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

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

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

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

等待更新

在中繼資料值可在您的執行個體執行中時變更的前提下,中繼資料伺服器可讓您使用等待變更功能收到中繼資料變更通知。此功能可讓您執行等待 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 說明文件