使用 Python 適用的 Cloud 用戶端程式庫

本文件說明如何在 Compute Engine 使用 Python 適用的 Cloud 用戶端程式庫。內容包括如何授權要求以及如何建立、列出及刪除執行個體。本練習探討如何使用 google-api-python-client 程式庫存取 Compute Engine 資源。您可以從本機或在 VM 執行個體上執行此範例,前提是您已正確為範例授權。

如需可用用戶端程式庫的完整清單,包括其他 Google 用戶端程式庫以及第三方開放原始碼程式庫,請參閱用戶端程式庫頁面

要跳過練習並檢視完整的程式碼範例,請造訪 GoogleCloudPlatform/python-docs-samples GitHub 頁面。

目標

  • 使用 oauth2client 程式庫執行 OAuth 2.0 驗證
  • 使用 google-python-client 程式庫建立執行個體
  • 使用 google-python-client 程式庫列出執行個體
  • 使用 google-python-client 程式庫刪除執行個體

費用

本教學課程使用 Google Cloud Platform 的計費元件,包括 Compute Engine。

新的 Google Cloud Platform 使用者可能符合免費試用的資格。

事前準備

  1. 登入您的 Google 帳戶。

    如果您沒有帳戶,請申請新帳戶

  2. 在 GCP Console 的專案選擇器頁面中,選取或建立 GCP 專案。

    前往專案選取器頁面

  3. 請確認您已啟用 Google Cloud Platform 專案的計費功能。瞭解如何確認您已啟用專案的計費功能

  4. 安裝 Cloud SDK
  5. 安裝 SDK 後,執行 gcloud auth application-default login
  6. 安裝 google-api-python-client 程式庫。一般而言,您可以執行:
    $ pip install --upgrade google-api-python-client

    如要進一步瞭解如何安裝這個程式庫,請參閱安裝操作說明。另外您也必須讓 Python 2.7 或 3.3+ 執行 Python 適用的 Google 用戶端程式庫。

  7. 啟用 Cloud Storage API。
  8. 建立 Cloud Storage 值區,並記下值區名稱以備後續使用。

授權要求

以下範例採用 OAuth 2.0 授權。使用 OAuth 2.0 驗證要求的方法有很多,但在此範例中,您將使用應用程式預設憑證。這可讓您在本機工作站上執行範例時透過 gcloud 重複使用憑證,或從 Compute Engine 或 App Engine 內執行範例時透過服務帳戶重複使用憑證。您應該已在事前準備一節中安裝並授權 gcloud 工具。

應用程式預設憑證會自動提供在 Google API 用戶端程式庫中。您僅需建構並初始化 API:

compute = googleapiclient.discovery.build('compute', 'v1')

舉例來說,以下這段程式碼是本範例採用的主要方法,可初始化 API 並建立部分呼叫以建立、列出及刪除執行個體:

def main(project, bucket, zone, instance_name, wait=True):
    compute = googleapiclient.discovery.build('compute', 'v1')

    print('Creating instance.')

    operation = create_instance(compute, project, zone, instance_name, bucket)
    wait_for_operation(compute, project, zone, operation['name'])

    instances = list_instances(compute, project, zone)

    print('Instances in project %s and zone %s:' % (project, zone))
    for instance in instances:
        print(' - ' + instance['name'])

    print("""
Instance created.
It will take a minute or two for the instance to complete work.
Check this URL: http://storage.googleapis.com/{}/output.png
Once the image is uploaded press enter to delete the instance.
""".format(bucket))

    if wait:
        input()

    print('Deleting instance.')

    operation = delete_instance(compute, project, zone, instance_name)
    wait_for_operation(compute, project, zone, operation['name'])

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('project_id', help='Your Google Cloud project ID.')
    parser.add_argument(
        'bucket_name', help='Your Google Cloud Storage bucket name.')
    parser.add_argument(
        '--zone',
        default='us-central1-f',
        help='Compute Engine zone to deploy to.')
    parser.add_argument(
        '--name', default='demo-instance', help='New instance name.')

    args = parser.parse_args()

    main(args.project_id, args.bucket_name, args.zone, args.name)

列出執行個體

使用 Python 適用的 Cloud 用戶端程式庫時,您可以透過 compute.instances().list 方法列出執行個體。您必須提供要列出執行個體的專案 ID 和區域。例如:

def list_instances(compute, project, zone):
    result = compute.instances().list(project=project, zone=zone).execute()
    return result['items'] if 'items' in result else None

新增執行個體

如要新增執行個體,請使用 instances().insert 方法並指定新執行個體的屬性。您可以在要求主體中指定這些屬性;如要進一步瞭解每個屬性,請參閱 instances.insert 的 API 參考資料

建立新的執行個體時,您的要求必須至少提供下列屬性值:

  • 執行個體名稱
  • 根永久磁碟
  • 機器類型
  • 區域
  • 網路介面

本範例會在您選擇的區域中啟動具備下列屬性的執行個體:

  • 機器類型:n1-standard-1
  • 根永久磁碟:以最新 Debian 8 映像檔為基礎的新永久磁碟
  • 具備下列範圍的 Compute Engine 預設服務帳戶

    • https://www.googleapis.com/auth/devstorage.read_write 用於讓執行個體可在 Cloud Storage 中讀取並寫入檔案
    • https://www.googleapis.com/auth/logging.write 用於讓執行個體記錄檔可以上傳至 Stackdriver Logging
  • 指定執行個體應在啟動時執行的中繼資料

def create_instance(compute, project, zone, name, bucket):
    # Get the latest Debian Jessie image.
    image_response = compute.images().getFromFamily(
        project='debian-cloud', family='debian-9').execute()
    source_disk_image = image_response['selfLink']

    # Configure the machine
    machine_type = "zones/%s/machineTypes/n1-standard-1" % zone
    startup_script = open(
        os.path.join(
            os.path.dirname(__file__), 'startup-script.sh'), 'r').read()
    image_url = "http://storage.googleapis.com/gce-demo-input/photo.jpg"
    image_caption = "Ready for dessert?"

    config = {
        'name': name,
        'machineType': machine_type,

        # Specify the boot disk and the image to use as a source.
        'disks': [
            {
                'boot': True,
                'autoDelete': True,
                'initializeParams': {
                    'sourceImage': source_disk_image,
                }
            }
        ],

        # Specify a network interface with NAT to access the public
        # internet.
        'networkInterfaces': [{
            'network': 'global/networks/default',
            'accessConfigs': [
                {'type': 'ONE_TO_ONE_NAT', 'name': 'External NAT'}
            ]
        }],

        # Allow the instance to access cloud storage and logging.
        'serviceAccounts': [{
            'email': 'default',
            'scopes': [
                'https://www.googleapis.com/auth/devstorage.read_write',
                'https://www.googleapis.com/auth/logging.write'
            ]
        }],

        # Metadata is readable from the instance and allows you to
        # pass configuration from deployment scripts to instances.
        'metadata': {
            'items': [{
                # Startup script is automatically executed by the
                # instance upon startup.
                'key': 'startup-script',
                'value': startup_script
            }, {
                'key': 'url',
                'value': image_url
            }, {
                'key': 'text',
                'value': image_caption
            }, {
                'key': 'bucket',
                'value': bucket
            }]
        }
    }

    return compute.instances().insert(
        project=project,
        zone=zone,
        body=config).execute()

下列各節說明執行個體建立參數。

根永久磁碟

所有執行個體都必須從根永久磁碟啟動,根永久磁碟內含啟動執行個體所需的一切必要檔案。在建立根永久磁碟時,您必須指定要套用至磁碟的來源 OS 映像檔。在上述範例中,您會在建立執行個體的同時建立以 Debian 8 為基礎的根永久磁碟。然而,您也可以事先建立磁碟並連結至執行個體。

執行個體中繼資料

建立執行個體時,您可能會想要包含執行個體中繼資料,例如開機指令碼、設定變數及安全殼層 (SSH) 金鑰組。在上面的範例中,您在要求主體中使用了 metadata 欄位以指定執行個體的開機指令碼,並指定一些設定變數做為鍵/值組合。開機指令碼 (如下所列) 會顯示如何讀取這些變數並使用這些變數將文字套用至映像檔並上傳至 Cloud Storage

apt-get update
apt-get -y install imagemagick

# Use the metadata server to get the configuration specified during
# instance creation. Read more about metadata here:
# https://cloud.google.com/compute/docs/metadata#querying
IMAGE_URL=$(curl http://metadata/computeMetadata/v1/instance/attributes/url -H "Metadata-Flavor: Google")
TEXT=$(curl http://metadata/computeMetadata/v1/instance/attributes/text -H "Metadata-Flavor: Google")
CS_BUCKET=$(curl http://metadata/computeMetadata/v1/instance/attributes/bucket -H "Metadata-Flavor: Google")

mkdir image-output
cd image-output
wget $IMAGE_URL
convert * -pointsize 30 -fill white -stroke black -gravity center -annotate +10+40 "$TEXT" output.png

# Create a Google Cloud Storage bucket.
gsutil mb gs://$CS_BUCKET

# Store the image in the Google Cloud Storage bucket and allow all users
# to read it.
gsutil cp -a public-read output.png gs://$CS_BUCKET/output.png

刪除執行個體

如要刪除執行個體,您需要呼叫 instances().delete 方法並提供要刪除的執行個體的名稱、區域,以及專案 ID。由於您為開機磁碟設定了 autoDelete 參數,在刪除執行個體時,也會刪除開機磁碟。此設定預設為關閉,但如果您需要同時刪除磁碟與執行個體,此設定就能派上用場。

def delete_instance(compute, project, zone, name):
    return compute.instances().delete(
        project=project,
        zone=zone,
        instance=name).execute()

執行範例

要執行完整範例,請下載程式碼並在指令列上執行。請務必下載 create_instance.py 檔案和 startup-script.sh 檔案。執行範例:

python create_instance.py --name [INSTANCE_NAME] --zone [ZONE] [PROJECT_ID] [CLOUD_STORAGE_BUCKET]

其中:

  • [INSTANCE_NAME] 是要建立的執行個體名稱。
  • [ZONE] 是此要求的所需區域。
  • [PROJECT_ID] 是專案 ID。
  • [CLOUD_STORAGE_BUCKET] 是您原本設定的值區名稱,但沒有 gs:// 前置字串。

例如:

python python-example.py --name example-instance --zone us-central1-a example-project my-gcs-bucket

等待作業完成

對 Compute Engine API 提出修改執行個體等資源的要求會立即傳回確認要求的回覆。此確認可讓您檢查要求作業的狀態。作業可能需要幾分鐘才可完成,因此最好等到完成後再繼續其他作業。此輔助程式方法會等到作業完成後才會傳回:

def wait_for_operation(compute, project, zone, operation):
    print('Waiting for operation to finish...')
    while True:
        result = compute.zoneOperations().get(
            project=project,
            zone=zone,
            operation=operation).execute()

        if result['status'] == 'DONE':
            print("done.")
            if 'error' in result:
                raise Exception(result['error'])
            return result

        time.sleep(1)

清除所用資源

如要避免系統向您的 Google Cloud Platform 帳戶收取您在本教學課程中使用資源的相關費用:

刪除 Cloud Storage 值區

如要刪除 Cloud Storage 值區:

  1. 前往 GCP Console 的「Cloud Storage Browser」(Cloud Storage 瀏覽器) 頁面。

    前往「Cloud Storage Browser」(Cloud Storage 瀏覽器) 頁面

  2. 按一下您要刪除的值區的核取方塊。
  3. 按一下「Delete」(刪除) 圖示 以刪除值區。

後續步驟

  • 下載並檢視完整程式碼範例。完整範例內含同時使用所有方法的小範例。請依照自身需求下載、變更或執行範例。
  • 檢閱 API 參考資料,瞭解如何透過 API 執行其他工作。