启动脚本是一种文件,用于在虚拟机实例 (VM) 的启动过程中执行任务。启动脚本可以应用于项目中的所有虚拟机或单个虚拟机。虚拟机级层元数据指定的启动脚本会替换项目级层元数据指定的启动脚本,并且启动脚本仅在网络可用时运行。本文档介绍如何在 Linux 虚拟机实例上使用启动脚本。如需了解如何添加项目级层启动脚本,请参阅 gcloud compute project-info add-metadata
。
对于 Linux 启动脚本,您可以使用 bash 或非 bash 文件。如需使用非 bash 文件,请通过将 #!
添加到文件的顶部来指定解释器。例如,如需使用 Python 3 启动脚本,请将 #! /usr/bin/python3
添加到文件的顶部。
如果您使用本文档中的某个过程来指定启动脚本,Compute Engine 将执行以下操作:
将启动脚本复制到虚拟机
设置启动脚本的运行权限
在虚拟机启动时以
root
用户身份运行启动脚本
如需了解与启动脚本有关的各种任务以及何时执行各个任务,请参阅概览。
准备工作
- 阅读启动脚本概览。
- 了解元数据服务器。
-
如果您尚未设置身份验证,请进行设置。身份验证是通过其进行身份验证以访问 Google Cloud 服务和 API 的过程。如需从本地开发环境运行代码或示例,您可以按如下方式向 Compute Engine 进行身份验证。
Select the tab for how you plan to use the samples on this page:
Console
When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.
gcloud
-
安装 Google Cloud CLI,然后通过运行以下命令初始化 Google Cloud CLI:
gcloud init
- Set a default region and zone.
在 Google Cloud 控制台中,转到创建实例页面。
对于启动磁盘,选择更改,然后选择 Linux 操作系统。
展开高级选项部分,然后执行以下操作:
- 展开管理部分。
在自动化部分中,添加以下启动脚本:
#! /bin/bash apt update apt -y install apache2 cat <<EOF > /var/www/html/index.html <html><body><p>Linux startup script added directly.</p></body></html> EOF
点击创建。
在 Google Cloud 控制台中,转到虚拟机实例页面。
点击虚拟机的名称。
点击修改。
在自动化下,添加启动脚本的内容。
VM_NAME:虚拟机的名称
ZONE:虚拟机的可用区
PROJECT_ID:项目 ID
ZONE:要在其中创建虚拟机的可用区
使用
instances.get
方法获取虚拟机的tags.fingerprint
值。GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
请替换以下内容:
PROJECT_ID:项目 ID
ZONE:虚拟机的可用区
VM_NAME:虚拟机所在的区域
在对
instances.setMetadata
方法 的调用中使用fingerprint
值以及启动脚本的元数据键和值来传递启动脚本:POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setMetadata { "fingerprint": FINGERPRINT, "items": [ { "key": "startup-script", "value": "#! /bin/bash\napt update\napt -y install apache2\ncat <<EOF > /var/www/html/index.html\n<html><body><p>Linux startup script added directly.</p></body></html>\nEOF" } ], ... }
请替换以下内容:
PROJECT_ID:项目 ID
ZONE:虚拟机的可用区
VM_NAME:虚拟机所在的区域
FINGERPRINT:使用
instances.get
方法获取的tags.fingerprint
值
创建本地文件以存储启动脚本。
请注意从 gcloud CLI 到启动脚本的相对路径。
将以下启动脚本添加到文件:
#! /bin/bash apt update apt -y install apache2 cat <<EOF > /var/www/html/index.html <html><body><p>Linux startup script from a local file.</p></body></html> EOF
VM_NAME:虚拟机的名称
FILE_PATH:启动脚本文件的相对路径
VM_NAME:虚拟机的名称
ZONE:虚拟机的可用区
FILE_PATH:启动脚本文件的相对路径
创建文件以存储启动脚本。本示例使用 bash (
.sh
) 文件。将以下内容添加到 bash 文件中,该文件将安装 Apache 并创建一个简单的网页:
#! /bin/bash apt update apt -y install apache2 cat <<EOF > /var/www/html/index.html <html><body><p>Linux startup script from Cloud Storage.</p></body></html> EOF
默认情况下,项目所有者和项目编辑者可以访问同一项目中的 Cloud Storage 文件,除非有显式访问权限控制禁止这么做。
如果 Cloud Storage 存储桶或对象的安全性低于元数据,则在修改启动脚本和虚拟机重新启动时,存在提权风险。这是因为虚拟机重新启动后,启动脚本会作为
root
运行,然后可以使用关联服务账号的权限访问其他资源。在 Google Cloud 控制台中,转到创建实例页面。
指定虚拟机详情。
对于启动磁盘,选择更改,然后选择 Linux 操作系统。
在身份和 API 访问权限部分,选择具有 Storage Object Viewer 角色 (
roles/storage.objectViewer
) 的服务账号。展开高级选项部分,然后执行以下操作:
- 展开管理部分。
在元数据部分中,添加以下内容的值:
键:元数据键。设置为
startup-script-url
以从 Cloud Storage 添加启动脚本。值:元数据值。使用以下格式之一设置启动脚本文件的 Cloud Storage 位置:
- 要求验证身份的网址:
https://storage.googleapis.com/BUCKET/FILE
- gsutil URI:
gs://BUCKET/FILE
请替换以下内容:
- BUCKET:包含启动脚本文件的存储桶的名称
- FILE:启动脚本文件的名称
- 要求验证身份的网址:
如需创建虚拟机,请点击创建。
在 Google Cloud 控制台中,前往虚拟机实例页面。
点击虚拟机的名称。
点击修改。
在元数据下,添加以下值:
键:
startup-script-url
值:启动脚本文件的 Cloud Storage 位置,其中使用以下格式之一:
- 要求验证身份的网址:
https://storage.googleapis.com/BUCKET/FILE
- gsutil URI:
gs://BUCKET/FILE
- 要求验证身份的网址:
VM_NAME:虚拟机的名称。
CLOUD_STORAGE_URL:元数据值。使用以下格式之一设置启动脚本文件的 Cloud Storage 位置:
- 要求验证身份的网址:
https://storage.googleapis.com/BUCKET/FILE
- gsutil URI:
gs://BUCKET/FILE
- 要求验证身份的网址:
VM_NAME:虚拟机的名称。
ZONE:虚拟机的可用区。
CLOUD_STORAGE_URL:元数据值。使用以下格式之一设置启动脚本文件的 Cloud Storage 位置:
- 要求验证身份的网址:
https://storage.googleapis.com/BUCKET/FILE
- gsutil URI:
gs://BUCKET/FILE
- 要求验证身份的网址:
PROJECT_ID:项目 ID。
ZONE:要在其中创建新虚拟机的可用区。
CLOUD_STORAGE_URL:元数据值。使用以下格式之一设置启动脚本文件的 Cloud Storage 位置:
- 要求验证身份的网址:
https://storage.googleapis.com/BUCKET/FILE
- gsutil URI:
gs://BUCKET/FILE
- 要求验证身份的网址:
使用
instances.get
方法获取虚拟机的tags.fingerprint
值。GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
请替换以下内容:
PROJECT_ID:项目 ID
ZONE:虚拟机的可用区
VM_NAME:虚拟机所在的区域
在对
instances.setMetadata
方法 的调用中使用fingerprint
值以及启动脚本的元数据键和值来传递启动脚本:POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setMetadata { "fingerprint": FINGERPRINT, "items": [ { "key": "startup-script-url", "value": "CLOUD_STORAGE_URL" } ], ... }
请替换以下内容:
PROJECT_ID:项目 ID。
ZONE:虚拟机的可用区。
VM_NAME:虚拟机的可用区。
FINGERPRINT:使用
instances.get
方法获取的tags.fingerprint
值。CLOUD_STORAGE_URL:元数据值。使用以下格式之一设置为启动脚本文件的 Cloud Storage 位置:
- 要求验证身份的网址:
https://storage.googleapis.com/BUCKET/FILE
- gsutil URI:
gs://BUCKET/FILE
- 要求验证身份的网址:
创建用于查询元数据键值的启动脚本。例如,以下 bash 文件 (
.sh
) 启动脚本会查询foo
元数据键的值。#! /bin/bash METADATA_VALUE=$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/foo -H "Metadata-Flavor: Google") apt update apt -y install apache2 cat <<EOF > /var/www/html/index.html <html><body><p>Accessing metadata value of foo: $METADATA_VALUE</p></body></html> EOF
在创建虚拟机时使用以下
gcloud compute instances create
命令设置foo
元数据键的值。在本示例中,将启动脚本从本地文件传递到虚拟机。gcloud
gcloud compute instances create VM_NAME \ --image-project=debian-cloud \ --image-family=debian-10 \ --metadata-from-file=startup-script=FILE_PATH \ --metadata=foo=bar
请替换以下内容:
VM_NAME:虚拟机的名称
FILE_PATH:启动脚本文件的相对路径
如需详细了解如何指定元数据键值对,请参阅设置自定义元数据。
在本地工作站中,在网络浏览器中查看外部 IP,以验证启动脚本是否输出
foo
的值。您可能需要等待大约 1 分钟来完成示例启动脚本。运行以下命令:
sudo google_metadata_script_runner startup
连接到实例并运行以下命令。
sudo journalctl -u google-startup-scripts.service
在 Google Cloud 控制台中通过串行端口 1 查看输出,并检查是否有
google_metadata_script_runner
事件。了解如何在 Windows 虚拟机上使用启动脚本。
了解如何排查启动脚本问题。
了解如何添加关停脚本。
详细了解如何存储和检索元数据。
REST
如需在本地开发环境中使用本页面上的 REST API 示例,请使用您提供给 gcloud CLI 的凭据。
如需了解详情,请参阅 Google Cloud 身份验证文档中的使用 REST 时进行身份验证。
Linux 启动脚本的元数据键
启动脚本将从元数据键指定的位置传递给虚拟机。元数据键指定启动脚本是存储在本地、存储在 Cloud Storage 中,还是直接传递给虚拟机。使用的元数据键可能还取决于启动脚本的大小。
下表显示可用于 Linux 启动脚本的元数据键,并提供根据启动脚本的存储位置和大小要使用哪个键的相关信息。
元数据键 用于 startup-script
传递在本地存储或直接添加且大小最大为 256 KB 的 bash 或非 bash 启动脚本 startup-script-url
传递存储在 Cloud Storage 中且大小超过 256 KB 的 bash 或非 bash 启动脚本。您在此处输入的字符串会按原样用于运行 gsutil
。如果您的startup-script-url
包含空格字符,请不要将空格替换为%20
或向startup-script-url
字符串添加英文双引号 (""
)。Linux 启动脚本的执行顺序
您可以使用多个启动脚本。存储在本地或直接添加的启动脚本会在 Cloud Storage 中存储的启动脚本之前执行。下表根据元数据键显示 Linux 启动脚本的执行顺序。
元数据键 执行顺序 startup-script
初始启动后每次启动期间的第一次 startup-script-url
初始启动后每次启动期间的第二次 直接传递 Linux 启动脚本
您可以在创建虚拟机时直接将启动脚本的内容添加到虚拟机。以下过程演示如何使用安装了 Apache 和创建基本网页的启动脚本来创建虚拟机。
控制台
将 Linux 启动脚本直接传递到新虚拟机
将 Linux 启动脚本直接传递到现有虚拟机
验证启动脚本
虚拟机启动后,在网络浏览器中查看外部 IP 以验证启动脚本是否创建了网站。您可能需要等待大约 1 分钟来完成示例启动脚本。
gcloud
将 Linux 启动脚本直接传递到新虚拟机
在创建时使用以下
gcloud compute instances create
命令直接将启动脚本的内容直接传递到虚拟机。gcloud compute instances create VM_NAME \ --image-project=debian-cloud \ --image-family=debian-10 \ --metadata=startup-script='#! /bin/bash apt update apt -y install apache2 cat <<EOF > /var/www/html/index.html <html><body><p>Linux startup script added directly.</p></body></html> EOF'
将 VM_NAME 替换为虚拟机名称。
将 Linux 启动脚本直接传递到现有虚拟机
使用以下
gcloud compute instances add-metadata
命令将启动脚本直接添加到现有虚拟机:gcloud compute instances add-metadata VM_NAME \ --zone=ZONE \ --metadata=startup-script='#! /bin/bash apt update apt -y install apache2 cat <<EOF > /var/www/html/index.html <html><body><p>Linux startup script added directly.</p></body></html> EOF'
请替换以下内容:
验证启动脚本
虚拟机启动后,在网络浏览器中查看外部 IP 以验证启动脚本是否创建了网站。您可能需要等待大约 1 分钟来完成示例启动脚本。
REST
将 Linux 启动脚本直接传递到新虚拟机
在创建时使用以下
instances.insert
方法直接将启动脚本的内容直接传递到虚拟机。POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances { ... "networkInterfaces": [ { "accessConfigs": [ { "type": "ONE_TO_ONE_NAT" } ] } ], "metadata": { "items": [ { "key": "startup-script", "value": "#! /bin/bash\napt update\napt -y install apache2\ncat <<EOF > /var/www/html/index.html\n<html><body><p>Linux startup script added directly.</p></body></html>\nEOF" } ] }, ... }
请替换以下内容:
将 Linux 启动脚本直接传递到现有虚拟机
验证启动脚本
虚拟机启动后,在网络浏览器中查看外部 IP 以验证启动脚本是否创建了网站。您可能需要等待大约 1 分钟来完成示例启动脚本。
从本地文件传递 Linux 启动脚本
您可以将启动脚本存储在工作站上的本地文件中,并在创建时将本地文件作为元数据传递到虚拟机。您不能将虚拟机上存储的文件用作启动脚本。
在将 Linux 启动脚本从本地文件传递到虚拟机之前,请执行以下操作:
gcloud
将 Linux 启动脚本从本地文件传递到新虚拟机
使用带有
--metadata-from-file
标志的gcloud compute instances create
命令创建一个虚拟机,并传递要用作启动脚本的本地文件的内容。gcloud compute instances create VM_NAME \ --image-project=debian-cloud \ --image-family=debian-10 \ --metadata-from-file=startup-script=FILE_PATH
请替换以下内容:
将 Linux 启动脚本从本地文件传递到现有虚拟机
使用以下
gcloud compute instances add-metadata
命令,将本地文件从本地文件传递到现有虚拟机:gcloud compute instances add-metadata VM_NAME \ --zone=ZONE \ --metadata-from-file startup-script=FILE_PATH
请替换以下内容:
验证启动脚本
在网络浏览器中查看外部 IP 以验证启动脚本是否已创建网站。您可能需要等待大约 1 分钟来完成示例启动脚本。
从 Cloud Storage 传递 Linux 启动脚本
您可以将启动脚本存储在 Cloud Storage 中,并在创建脚本时将其传递到虚拟机。将启动脚本添加到 Cloud Storage 后,您将获得一个网址,用于在创建虚拟机时引用启动脚本。
在从 Cloud Storage 存储桶添加启动脚本之前,请执行以下操作:
安全注意事项
限制
控制台
将存储在 Cloud Storage 中的启动脚本传递到新虚拟机
将存储在 Cloud Storage 中的启动脚本传递到现有虚拟机
验证启动脚本
在网络浏览器中查看外部 IP 以验证启动脚本是否已创建网站。您可能需要等待大约 1 分钟来完成示例启动脚本。
gcloud
将存储在 Cloud Storage 中的启动脚本传递到新虚拟机
在创建时使用以下
gcloud compute instances create
命令将 Cloud Storage 中存储的启动脚本传递到虚拟机。对于--scope
标志的值,使用storage-ro
,以便虚拟机可以访问 Cloud Storage。gcloud compute instances create VM_NAME \ --image-project=debian-cloud \ --image-family=debian-10 \ --scopes=storage-ro \ --metadata=startup-script-url=CLOUD_STORAGE_URL
请替换以下内容:
将存储在 Cloud Storage 中的启动脚本传递到现有虚拟机
使用以下
gcloud compute instances add-metadata
命令将存储在 Cloud Storage 中的启动脚本传递到现有虚拟机:gcloud compute instances add-metadata VM_NAME \ --zone=ZONE \ --metadata startup-script-url=CLOUD_STORAGE_URL
请替换以下内容:
验证启动脚本
在网络浏览器中查看外部 IP 以验证启动脚本是否已创建网站。您可能需要等待大约 1 分钟来完成示例启动脚本。
REST
将存储在 Cloud Storage 中的启动脚本传递到新虚拟机
在创建时使用以下
instances.insert
方法将 Cloud Storage 中存储的启动脚本传递到虚拟机。在scopes
字段中,添加https://www.googleapis.com/auth/devstorage.read_only
,以便虚拟机可以访问 Cloud Storage。POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances { ... "networkInterfaces": [ { "accessConfigs": [ { "type": "ONE_TO_ONE_NAT" } ] } ], "serviceAccounts": [ { "email": "default", "scopes": [ "https://www.googleapis.com/auth/devstorage.read_only" ] } ], "metadata": { "items": [ { "key": "startup-script-url", "value": "CLOUD_STORAGE_URL" } ] }, ... }
请替换以下内容:
将存储在 Cloud Storage 中的启动脚本传递到现有虚拟机
验证启动脚本
在网络浏览器中查看外部 IP 以验证启动脚本是否已创建网站。您可能需要等待大约 1 分钟来完成示例启动脚本。
从 Linux 启动脚本访问元数据
在启动脚本中,您可以访问元数据值。例如,您可以将同一个脚本用于多个虚拟机,并通过将不同的元数据值传递到每个虚拟机来单独对每个脚本进行参数化。
如需从启动脚本访问自定义元数据值,请执行以下操作:
重新运行 Linux 启动脚本
通过执行以下操作,重新运行启动脚本:
查看 Linux 启动脚本的输出
您可以通过执行以下任一操作来查看 Linux 启动脚本的输出:
后续步骤
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2024-07-05。
[{ "type": "thumb-down", "id": "hardToUnderstand", "label":"Hard to understand" },{ "type": "thumb-down", "id": "incorrectInformationOrSampleCode", "label":"Incorrect information or sample code" },{ "type": "thumb-down", "id": "missingTheInformationSamplesINeed", "label":"Missing the information/samples I need" },{ "type": "thumb-down", "id": "translationIssue", "label":"翻译问题" },{ "type": "thumb-down", "id": "otherDown", "label":"其他" }] [{ "type": "thumb-up", "id": "easyToUnderstand", "label":"易于理解" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"解决了我的问题" },{ "type": "thumb-up", "id": "otherUp", "label":"其他" }] -