本页面介绍何时及为何创建确定性实例模板。确定性实例模板可让您明确了解在部署实例模板时,应在实例上安装的第三方服务或应用类型。创建确定性实例模板后,您可以将实例模板发生不确定性和意外行为的可能性降至最低。
为何要创建确定性实例模板
一般来说,我们建议实例模板的属性要尽可能明确且具确定性。如果您在安装或使用第三方服务的实例模板中采用启动脚本,请确保这些脚本提供明确的信息(例如要安装的应用版本)。Compute Engine 只能依赖于模板中定义的信息,而无权控制所引用的第三方服务。如果您的模板中的信息过于模糊,则该实例模板可能会出现预料之外的行为。
例如,假设通过以下命令来创建一个包含启动脚本的实例模板,该脚本将会安装 apache2 并使用外部服务器上托管的某个文件:
gcloud compute instance-templates create example-template-with-startup \
--image-family debian-9 \
--image-project debian-cloud \
--metadata startup-script='#! /bin/bash
sudo apt install -y apache2
scp myuser@108.59.87.185:index.php /var/www/'
这个启动脚本有两个潜在问题:
- 此脚本没有明确定义要安装哪个版本的 apache2,并且依赖于
apt
软件库中提供的当前版本。 - 此脚本依赖于某个由第三方托管的文件,而该文件未纳入版本控制,并且自上次使用实例模板后可能已经发生了更改。
如果您使用了自动扩缩程序,则非确定性实例模板可能会导致该自动扩缩程序将新的实例添加到使用不同配置(例如不同版本的 apache2)的托管实例组中。
同样,如果您对某个托管式实例组应用了此模板,并将该实例组更新为其他模板服务,然后决定回滚到先前的模板,那么实例最终可能使用的是与更新前的版本不同的 apache2 或 index.php 文件,因为您的实例在启动时始终会获取最新版本。
避免模糊或意外的实例模板行为
为了避免出现意外的模板行为,请从以下方法中任选其一:
使用容器优化型映像或 Docker(带有Docker 标记)。例如,我们建议您为 Docker 映像的每个新版本分配新的标记,并在实例模板中使用这些标记,而不要使用默认的最新标记。对于容器优化型映像,您可以在清单文件中明确引用映像的特定版本。下面的示例使用标记为“version_2_1_3”的版本的 Docker 映像“myimage”:
version: v1beta2 containers: - name: simple-echo image: myimage:version_2_1_3 [ rest of your manifest file ]
创建自定义映像以用作模板的映像。这种方式比使用启动脚本更可取,因为它可以保证每个实例都是相同的,而启动脚本在分发软件包更新后可能会产生不同的结果。在进行原型设计和快速开发时,建议在实例模板中使用启动脚本;在准备部署生产级质量的服务时,建议使用自定义映像。
如果您确实要使用启动脚本,请考虑将脚本更新为确定性脚本。例如,您可以基于之前的模板创建新版本,并指定一个确定性启动脚本,具体如下所示:
gcloud compute instance-templates create example-template-with-startup-2-1-3 \ --image-family debian-9 \ --image-project debian-cloud \ --metadata startup-script='#! /bin/bash sudo apt install -y apache2=2.2.20-1ubuntu1 scp myuser@108.59.87.185:version_2_1_3/index.php /var/www/'
其中,“version_2_1_3”是一个子目录,其中包含 2.1.3 版服务的 PHP 脚本。