要了解Google Compute Engine如何管理ssh密钥,您必须了解GCE如何管理元数据(因为它们存储在元数据存储中,正如您所写的那样)。
更具体地说,项目和实例元数据之间的区别至关重要。引用文档(请参见上面的链接):
元数据可以在项目和实例级别分配。项目级元数据会传播到项目内所有虚拟机实例,而实例级元数据只影响该实例。您可以设置项目和实例级别的元数据,但如果您为项目和实例元数据设置相同的键,则Compute Engine将使用实例元数据。
虽然这似乎相当逻辑和简单,但必须非常注意使用的术语:
项目级元数据“传播”到项目内所有虚拟机实例[...]
和
如果您为“项目和实例元数据”设置相同的键,则Compute Engine将使用实例元数据。
如果您考虑这两个断言,它意味着两件事情:
1. 如果您仅在项目级别设置元数据,则会在您的实例中传播。
2. 如果您在实例级别设置元数据,则它将优先于项目级别,并且不会传播。
因此,GCE平台负责在实例中放置/删除您的ssh密钥(并在放置密钥时创建相关用户,而只是从
~user/.ssh/authorized_keys
文件中删除密钥,以便您不会失去任何
~user
的数据),仅当您没有指定自己的密钥(在实例创建或之后)时才进行。如果您这样做了,GCE平台将认为ssh密钥管理是手动的,而与元数据存储不会保持同步。
幸运的是,GCE平台做得很好,因此您不需要重新创建实例来让GCE平台管理您的密钥:您只需要删除与
sshKeys
相关的实例级别元数据即可。
同样地,如果您使用关键字
sshKeys
添加一些实例级别的元数据,它将禁用GCE平台管理的SSH密钥;除非您删除该实例级别的元数据。
关于延迟问题:到目前为止,除了网络延迟之外,我没有遇到任何延迟(因此没有注意到平台执行延迟)。我不认为平台偶尔有延迟是不可能的,但这似乎不太可能是您问题的原因。
额外说明:
一些发行版(如ubuntu)包括一个特定的用户(在ubuntu的情况下为:~ ubuntu),可以使用该用户登录到项目级别的ssh密钥中存在的每个用户。但是,在实例创建时生成了该用户的authorized_keys,并且似乎从未被GCE平台再次更改。在我看来,应优先选择自动ssh密钥管理。
来源:个人使用GCE、terraform和Google开发者控制台的经验。
sshKeys
元数据值已经被弃用;请改用ssh-keys
元数据值。更多信息请参见此处。 - Mike