建立和啟用執行個體的服務帳戶

本頁面說明如何建立服務帳戶,然後與虛擬機器執行個體搭配使用。服務帳戶是一種特殊帳戶,您可以在應用程式的程式碼中使用其憑證來存取其他 Google Cloud Platform 服務。

如要瞭解服務帳戶,請參閱服務帳戶總覽

事前準備

建立新的服務帳戶

您可以使用 Google Cloud Identity and Access Management (IAM) 建立及設定新的服務帳戶。建立帳戶之後,請將一或多個 IAM 角色授予該帳戶,然後授權執行個體以服務帳戶身分執行。

如要建立新的服務帳戶,請執行下列操作:

  1. 建立新的服務帳戶,方法請參閱 IAM 服務帳戶說明文件。

  2. 取得該服務帳戶的電子郵件。 您需要電子郵件,才能設定執行個體以該服務帳戶身分執行。請在主控台中驗證服務帳戶的電子郵件:

    1. 前往 GCP 主控台的「Service Accounts」(服務帳戶) 頁面。

      前往「Service Accounts」(服務帳戶) 頁面

    2. 如果出現提示,請選取專案。
    3. 找到新的服務帳戶,並記下該服務帳戶的電子郵件。

    一般來說,服務帳戶的電子郵件源自於服務帳戶 ID,格式如下:

    [SERVICE-ACCOUNT-NAME]@[PROJECT_ID].iam.gserviceaccount.com
    
  3. 將 IAM 角色授予該服務帳戶。若沒有授予任何角色,該服務帳戶將無法存取任何服務。如需完整的 IAM 角色清單,請參閱 IAM 說明文件中的瞭解角色

  4. 接下來,設定執行個體以服務帳戶身分執行。 請按照操作說明設定執行個體以服務帳戶身分執行

設定新的執行個體以服務帳戶身分執行

建立新的服務帳戶之後,即可建立新的虛擬機器執行個體,使其以該服務帳戶身分執行。如果您想要指派或變更現有執行個體的服務帳戶,請改為參閱變更服務帳戶以及執行個體的存取權限範圍一節。

您可以讓多個虛擬機器執行個體使用同一服務帳戶,但每一個虛擬機器執行個體只能有一個服務帳戶身分。如果您將同一個服務帳戶指派給多個虛擬機器執行個體,日後這個服務帳戶所發生的任何變更都會影響到所有使用這個服務帳戶的執行個體。這包括對已授予這個服務帳戶之 IAM 角色所做的任何變更。舉例來說,如果移除了某個角色,那麼使用這個服務帳戶的所有執行個體也會失去該角色所授予的權限。

您可以透過 Google Cloud Platform 主控台gcloud 指令列工具或直接透過 API,設定新的執行個體以服務帳戶身分執行。

主控台

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

    前往 VM 執行個體頁面

  2. 按一下 [建立執行個體]
  3. 在「Create a new instance」 (建立新執行個體) 頁面上,填入您要為執行個體 設定的屬性。
  4. 在 [身分及 API 存取權] 區段中,從下拉式清單中選擇您要使用的服務帳戶。
  5. 按一下 [Create] (建立) 來建立執行個體。

gcloud

如要建立新的執行個體,並使用 gcloud 命令列工具授權這個新執行個體以自訂服務帳戶身分執行,請將服務帳戶電子郵件及所需要的存取權範圍提供給執行個體。一般來說,您可以只設定 cloud-platform 存取範圍。授予虛擬機器執行個體的存取範圍與授予服務帳戶的 IAM 角色,這兩者的組合會決定服務帳戶對該執行個體有多少的存取權。只有存取範圍與 IAM 角色兩者都允許執行 API 方法的情況下,服務帳戶才能進行該動作。

或者,您也可以選擇設定特定範圍,來授權存取服務將呼叫的特定 API 方法。舉例來說,如要呼叫 instances.insert 方法,將需要有 https://www.googleapis.com/auth/compute 範圍或 https://www.googleapis.com/auth/cloud-platform 範圍的相關授權,還有授予該方法存取權的相關 IAM 角色。您可以設定 compute 範圍取代 cloud-platform 範圍,藉此給予服務授權以在 Compute Engine 中呼叫方法,但無權在 Compute Engine 之外呼叫 API 方法。

gcloud compute instances create [INSTANCE_NAME] \
    --service-account [SERVICE_ACCOUNT_EMAIL] \
    --scopes [SCOPES,...]

其中:

  • [SERVICE_ACCOUNT_EMAIL] 是您要使用的服務帳戶電子郵件,例如:my-sa-123@my-project-123.iam.gserviceaccount.com。如果您不知道電子郵件是哪一個,請瞭解如何取得服務帳戶電子郵件
  • [INSTANCE_NAME] 是執行個體的名稱。
  • [SCOPES] 是以逗號分隔的完整範圍 URI 清單或範圍別名清單,這些內容由 --scopes 標記說明所提供。

例如:

gcloud compute instances create example-vm \
    --service-account 123-my-sa@my-project-123.iam.gserviceaccount.com \
    --scopes https://www.googleapis.com/auth/cloud-platform

gcloud 工具也會提供範圍別名而非較長的範圍 URI。舉例來說,Google Cloud Storage 完整存取權的範圍為 https://www.googleapis.com/auth/devstorage.full_control,此範圍的別名為 storage-full

您可以在 --scopes 標記說明的 instances create 頁面上查看範圍及範圍別名的清單。instances create 指令的說明也會列出這些範圍和別名:

gcloud compute instances create --help

指定別名,方法與指定一般範圍 URI 的相同。例如:

gcloud compute instances create [INSTANCE_NAME] \
    --service-account [SERVICE_ACCOUNT_EMAIL] \
    --scopes cloud-platform

API

在 API 中,建構一個標準要求來建立執行個體,但要加上 serviceAccounts 屬性。 取得您的服務帳戶電子郵件,然後加上 email 屬性,還有執行個體所需要的存取權範圍。一般來說,您可以只設定 cloud-platform 存取範圍。存取範圍與授予服務帳戶的 IAM 角色,這兩者的組合會決定服務帳戶對該執行個體有多少的存取權。只有存取範圍與 IAM 角色都允許執行 API 方法的情況下,服務帳戶才能進行該動作。

此外,您也可以選擇設定特定範圍,來授權存取服務將呼叫的特定 API 方法。舉例來說,如要呼叫 instances.insert 方法,將需要有 https://www.googleapis.com/auth/compute 範圍或 https://www.googleapis.com/auth/cloud-platform 範圍的相關授權。您可以設定 compute 範圍取代 cloud-platform 範圍,藉此給予服務授權以在 Compute Engine 中呼叫方法,但無權在 Compute Engine 之外呼叫 API 方法。

POST https://www.googleapis.com/compute/v1/projects/zones/[ZONE]/instances

{
  "machineType": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/machineTypes/[MACHINE_TYPE]",
  "name": "[INSTANCE_NAME]",
  "serviceAccounts": [
   {
    "email": "[SERVICE_ACCOUNT_EMAIL]",
    "scopes": ["https://www.googleapis.com/auth/cloud-platform"]
   }
  ],
  ...
}

設定執行個體以服務帳戶身分執行後,您可以在執行個體中將該服務帳戶憑證使用於以下幾個方面:

使用服務帳戶憑證驗證應用程式

設定執行個體以服務帳戶身分執行後,您可以使用該服務帳戶的憑證,驗證在執行個體上執行的應用程式。

透過用戶端程式庫驗證應用程式

用戶端程式庫可以使用應用程式預設憑證向 Google API 進行驗證,然後傳送要求到這些 API。應用程式預設憑證可讓應用程式從多個來源取得憑證,所以,您可以在本機先測試應用程式,再將其部署到 Compute Engine 執行個體,而不需要變更應用程式的程式碼。在本機開發應用程式時,應用程式可使用環境變數或 Google Cloud SDK 進行驗證。當應用程式在執行個體上執行時,可以使用已在該執行個體上啟用的服務帳戶進行驗證。

本範例使用 Python 用戶端程式庫向 Cloud Storage API 進行驗證,並要求列出專案中的值區。本範例採用以下程序:

  1. 取得 Cloud Storage API 的必要驗證憑證,然後使用 build() 方法和憑證初始化 Cloud Storage 服務。
  2. 列出 Cloud Storage 中的值區。

您可以在有權管理 Google Cloud Storage 中值區的執行個體上執行本範例。

import argparse

import googleapiclient.discovery

def create_service():
    # Construct the service object for interacting with the Cloud Storage API -
    # the 'storage' service, at version 'v1'.
    # Authentication is provided by application default credentials.
    # When running locally, these are available after running
    # `gcloud auth application-default login`. When running on Compute
    # Engine, these are available from the environment.
    return googleapiclient.discovery.build('storage', 'v1')

def list_buckets(service, project_id):
    buckets = service.buckets().list(project=project_id).execute()
    return buckets

def main(project_id):
    service = create_service()
    buckets = list_buckets(service, project_id)
    print(buckets)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('project_id', help='Your Google Cloud Project ID.')

    args = parser.parse_args()

    main(args.project_id)

直接透過存取權限驗證應用程式

對於某些應用程式,您可能需要要求 OAuth2 存取憑證並直接使用,而不透過用戶端程式庫或使用 gcloudgsutil 工具。取得及使用這些存取憑證來驗證應用程式有幾種方式。譬如,您可以使用 curl 建立一個簡單的要求,或使用 Python 之類的程式設計語言,則更有彈性。

curl

如要使用 curl 要求存取憑證並傳送要求給 API,請執行下列操作:

  1. 在應用程式執行所在的執行個體,執行下列指令,查詢中繼資料伺服器以取得存取憑證:

    $ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
    -H "Metadata-Flavor: Google"

    這個要求會傳回類似以下的回應:

    {
          "access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAS08i85nHq39HE3C2LTrCARA",
          "expires_in":3599,
          "token_type":"Bearer"
     }
  2. 複製回應中的 access_token 屬性值,使用它來傳送要求給 API。舉例來說,下列要求會列印專案中特定區域的執行個體清單:

    $ curl https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances \
    -H "Authorization":"Bearer [ACCESS_TOKEN]"
    

    其中:

    • [PROJECT_ID] 是這項要求的專案 ID。
    • [ZONE] 是列出之執行個體所在的區域。
    • [ACCESS_TOKEN] 是步驟 1 中所取得的存取憑證值。

    如需進一步瞭解要求中可設定的參數,請參閱參數說明文件。

Python

本範例將示範如何在 Python 應用程式中要求 Google Cloud Storage API 存取憑證。本範例採用以下程序:

  1. 向中繼資料伺服器要求憑證。
  2. 從伺服器的回應中摘錄存取憑證。
  3. 使用該存取憑證對 Google Cloud Storage 提出要求。
  4. 如果要求有成功,指令碼就會列印回應。
import argparse

import requests

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

def get_access_token():
    url = '{}instance/service-accounts/{}/token'.format(
        METADATA_URL, SERVICE_ACCOUNT)

    # Request an access token from the metadata server.
    r = requests.get(url, headers=METADATA_HEADERS)
    r.raise_for_status()

    # Extract the access token from the response.
    access_token = r.json()['access_token']

    return access_token

def list_buckets(project_id, access_token):
    url = 'https://www.googleapis.com/storage/v1/b'
    params = {
        'project': project_id
    }
    headers = {
        'Authorization': 'Bearer {}'.format(access_token)
    }

    r = requests.get(url, params=params, headers=headers)
    r.raise_for_status()

    return r.json()

def main(project_id):
    access_token = get_access_token()
    buckets = list_buckets(project_id, access_token)
    print(buckets)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('project_id', help='Your Google Cloud project ID.')

    args = parser.parse_args()

    main(args.project_id)

存取憑證會在短時間內失效。中繼資料伺服器會快取存取憑證,直到存取憑證離到期日剩下 60 秒時才停止。您可以要求新的憑證,其時間與次數不限,但是您的應用程式必須具有有效的存取憑證,才能成功呼叫 API。

在執行個體上使用服務帳戶驗證工具

某些應用程式可能會使用來自 gcloudgsutil 工具的指令,根據預設,大多數的 Compute Engine 映像檔都會隨附這些指令。這些工具能自動辨識執行個體的服務帳戶及授予服務帳戶的相關權限。具體來說,如果您將正確的角色授予服務帳戶,則無需使用 gcloud auth login,即可從執行個體中使用 gcloudgsutil 工具。

辨識這個服務帳戶的作業會自動發生,並且只會套用至執行個體所隨附的 gcloudgsutil 工具。如果您建立新的工具或新增自訂工具,將需要使用用戶端程式庫或藉由直接在應用程式中使用存取權限的方式,授權應用程式。

為了利用自動辨識服務帳戶的功能,請將適當的 IAM 角色授予服務帳戶,並設定執行個體以服務帳戶身分執行。 舉例來說,如果您將 roles/storage.objectAdmin 角色授予服務帳戶,則 gsutil 工具可以自動管理及存取 Google Cloud Storage 物件。

同理,如果您為服務帳戶啟用了 roles/compute.instanceAdmin.v1,則 gcloud compute 工具可以自動管理執行個體。

變更執行個體的服務帳戶與存取範圍

如果您想以不同的身分執行 VM,或是確定執行個體需要不同的一組範圍才能呼叫所需的 API 時,可以變更現有執行個體的服務帳戶及存取範圍。舉例來說,您可以變更存取範圍來授予新 API 的存取權,或者變更執行個體,使其以您所建立的服務帳戶身分 (而不使用 Compute Engine 預設服務帳戶) 來執行。

如要變更執行個體的服務帳戶與存取範圍,您必須暫時停止執行個體。如果要停止執行個體,請參閱停止執行個體說明文件。變更服務帳戶或存取權範圍後,請記得重新啟動執行個體。請使用下列其中一種方法,變更已停止之執行個體的服務帳戶或存取權範圍。

主控台

  1. 前往 Compute Engine 的「VM instances」(VM 執行個體) 頁面。

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

  2. 按一下您要變更其服務帳戶的 VM 執行個體。
  3. 如果執行個體未處於停止狀態,請按一下 [Stop] (停止) 按鈕。等待執行個體完全停止。
  4. 接下來,按一下 [Edit] (編輯) 按鈕。
  5. 向下捲動到「Service Account」(服務帳戶) 區段。
  6. 從下拉式選單中,選取所要的服務帳戶。
  7. 如要變更範圍,請在「Access Scopes」(存取權範圍) 區段中,設定符合需求的適當範圍。最佳做法是,只指定 VM 執行個體所需要的存取權範圍。如果不確定該如何設定適當的存取權範圍,請選擇 [Allow full access to all Cloud APIs] (允許所有 Cloud API 的完整存取權),然後務必藉由設定 IAM 角色來限制存取權。
  8. 按一下 [Save] (儲存) 按鈕儲存變更。

gcloud

使用 instances set-service-account 指令並提供執行個體名稱、服務帳戶電子郵件和所需要的範圍。您也可以移除執行個體的服務帳戶和存取範圍,來有效防止執行個體存取任何 Google Cloud Platform 服務:

gcloud compute instances set-service-account [INSTANCE_NAME] \
   [--service-account [SERVICE_ACCOUNT_EMAIL] | --no-service-account] \
   [--no-scopes | --scopes [SCOPES,...]]

其中:

  • [SERVICE_ACCOUNT_EMAIL] 是您要使用的服務帳戶電子郵件,例如:my-sa-123@my-project-123.iam.gserviceaccount.com
  • [INSTANCE_NAME] 是執行個體的名稱。
  • [SCOPES] 是以逗號分隔的完整範圍 URI 清單或範圍別名清單,這些內容由 --scopes 標記說明所提供。如果您想移除執行個體的所有範圍,請改用 --no-scopes 標記。

舉例來說,下列指令會將服務帳戶 my-sa-123@my-project-123.iam.gserviceaccount.com 指派給一個名稱為 example-instance 的執行個體,並在該執行個體上設定相關存取權範圍,以允許對 Compute Engine 進行讀寫,以及對 Google Cloud Storage 進行唯讀:

gcloud compute instances set-service-account example-instance \
   --service-account my-sa-123@my-project-123.iam.gserviceaccount.com \
   --scopes compute-rw,storage-ro

API

在 API 中,對 setServiceAccount 方法提出 POST 要求:

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

其中:

  • [PROJECT_ID] 是這項要求的專案 ID。
  • [ZONE] 是這個執行個體所屬的區域。
  • [INSTANCE_NAME] 是執行個體的名稱。

在要求主體中,提供服務帳戶的電子郵件地址,及執行個體所需要的範圍 URI

{
  "email": "[SERVICE_ACCOUNT_EMAIL]",
  "scopes": [
    "[SCOPE_URI]",
    "[SCOPE_URI]",
    ...
  ]
}

舉例來說,下列要求會使用服務帳戶電子郵件 my-sa-123@my-project-123.iam.gserviceaccount.com 並設定 Google Cloud Storage 和 Google BigQuery 範圍:

{
  "email": "my-sa-123@my-project-123.iam.gserviceaccount.com",
  "scopes": [
    "https://www.googleapis.com/auth/bigquery",
    "https://www.googleapis.com/auth/devstorage.read_only"
  ]
}

取得服務帳戶電子郵件

為了識別服務帳戶,您需要服務帳戶電子郵件。請透過下列其中一個選項,取得服務帳戶電子郵件:

主控台

  1. 前往 GCP 主控台的「服務帳戶」頁面。

    前往服務帳戶頁面

  2. 如果出現提示,請選取專案。「Service Accounts」(服務帳戶) 頁面會列出專案的所有服務帳戶及其電子郵件。

gcloud

從本機電腦使用 gcloud compute instances describe 指令:

gcloud compute instances describe [INSTANCE_NAME] --format json
{
      ...
      "serviceAccounts":[
         {
            "email":"123845678986-compute@developer.gserviceaccount.com",
            "scopes":[
               "https://www.googleapis.com/auth/devstorage.full_control"
            ]
         }
      ]
      ...
   }

如果執行個體沒有使用任何服務帳戶,您會收到一個沒有 serviceAccounts 屬性的回應。

中繼資料伺服器

直接從執行個體本身,查詢中繼資料伺服器。對 http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/ 提出要求:

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

如果您在建立執行個體時啟用了一或多個服務帳戶,curl 指令會傳回類似以下的輸出:

123845678986-compute@developer.gserviceaccount.com/
default/

如果執行個體沒有使用任何服務帳戶,您會收到沒有內容的回應。

API

對 Service Accounts API 提出要求

使用 Compute Engine 預設服務帳戶

如果您熟悉 Compute Engine 預設服務帳戶,並且想使用預設服務帳戶所提供的憑證,而不建立新的服務帳戶時,可以將 IAM 角色授予預設服務帳戶。

根據預設,所有的 Compute Engine 執行個體都能以預設服務帳戶身分執行。使用 gcloud 指令列工具或 GCP 主控台建立執行個體,並省略任何服務帳戶規格時,系統便會將預設服務帳戶指派給執行個體。

將 IAM 角色指派給預設服務帳戶之前,請注意以下幾點:

  • 將 IAM 角色授予預設服務帳戶時,所有以預設服務帳戶身分執行的執行個體都會受影響。舉例來說,如果您將 roles/storage.objectAdmin 角色授予預設服務帳戶,那麼所有以預設服務帳戶 (帳戶具有必要存取權範圍) 身分執行的執行個體,也會獲得 roles/storage.objectAdmin 角色所授予的權限。同理,如果您藉由省略特定角色來限制存取權,這也會影響所有以預設服務帳戶身分執行的執行個體。

  • 您必須撤銷服務帳戶的專案編輯者權限。系統預設會將服務帳戶新增為專案的專案編輯者。如果要使用 IAM 角色,您必須撤銷專案編輯者權限。

如果您不確定是否要將 IAM 角色授予預設服務帳戶,請改為建立新的服務帳戶

請按照下列操作說明,將 IAM 角色授予預設服務帳戶:

  1. 前往 GCP 的 IAM 頁面。

    前往 IAM 頁面

  2. 如果出現提示,請選取專案。
  3. 找出名稱為「Compute Engine Default Service Account」(Compute Engine 預設服務帳戶) 的服務帳戶。
  4. 在「Role」(角色) 欄中,展開 Compute Engine 預設服務帳戶的下拉式選單。
  5. 移除「Editor」(編輯者) 存取權並儲存變更。
  6. 接下來,將 IAM 角色授予服務帳戶。

所有目前以預設服務帳戶身分執行的虛擬機器執行個體,現在都可以根據您授予該帳戶的 IAM 角色,存取其他的 Google Cloud Platform API。

如果您想要設定新的執行個體以預設服務帳戶身分執行,請按照下列操作說明:

主控台

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

    前往 VM 執行個體頁面

  2. 按一下 [建立執行個體]
  3. 在「Create a new instance」 (建立新執行個體) 頁面上,填入您要為執行個體 設定的屬性。
  4. 在 [身分及 API 存取權] 區段中,從下拉式清單選擇 [Compute Engine 預設服務帳戶]
  5. 按一下 [Create] (建立) 來建立執行個體。

gcloud

如要使用預設服務帳戶建立新的執行個體,並授權所有 Google Cloud Platform 服務的完整存取權,請執行下列操作:

gcloud compute instances create [INSTANCE_NAME] \
     --scopes cloud-platform

API

在 API 中,建構一個標準要求來建立執行個體,但要加上 serviceAccounts 屬性。 取得預設服務帳戶 ID,並將其加入作為服務帳戶的 email。然後,在 scopes 屬性中設定一或多個範圍。

POST https://www.googleapis.com/compute/v1/projects/zones/[ZONE]/instances

{
  "machineType": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/machineTypes/[MACHINE_TYPE]",
  "name": "[INSTANCE_NAME]",
  "serviceAccounts": [
   {
    "email": "[DEFAULT_SERVICE_ACCOUNT_EMAIL]",
    "scopes": ["https://www.googleapis.com/auth/cloud-platform"]
   }
  ],
  ...
}

最佳做法

一般來說,Google 建議所有需要呼叫 Google API 的執行個體,都應該以具有該執行個體執行其工作所需的最低權限的服務帳戶身分來執行。也就是說,您在實際操作時必須按照下列程序,設定執行個體的服務帳戶:

  1. 建立新的服務帳戶,而不使用 Compute Engine 預設服務帳戶。
  2. 只針對該服務帳戶所需要的資源,授予相關的 IAM 角色。
  3. 設定執行個體以該服務帳戶身分執行。
  4. https://www.googleapis.com/auth/cloud-platform 範圍授予執行個體,允許對所有 Google Cloud APIs 的完整存取權,讓執行個體的 IAM 權限能徹底取決於服務帳戶的 IAM 角色。

請避免授予超過所需的存取權,並定期檢查服務帳戶權限,以確保合乎時宜。

後續步驟

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

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

這個網頁
Compute Engine 說明文件