向虚拟机添加 SSH 密钥

本文档介绍了如何将 SSH 密钥添加到虚拟机 (VM) 实例。

准备工作

将 SSH 密钥添加到使用基于元数据的 SSH 密钥的虚拟机

的虚拟机会将 SSH 密钥存储在 Compute Engine 项目和实例元数据中。如果为虚拟机启用了 OS Login,则虚拟机的客户机代理会忽略存储在元数据中的密钥。

您可以使用存储在项目元数据中的 SSH 密钥来访问项目中的所有虚拟机。您可以使用存储在实例元数据中的 SSH 密钥来访问各个虚拟机。

Compute Engine 不会在 SSH 密钥过期时自动从元数据中移除过期的 SSH 密钥,但过期密钥不能用于建立新的虚拟机连接。如果要从元数据中移除过期密钥,请参阅从使用基于元数据的密钥的虚拟机中移除 SSH 密钥

您可以使用 Trusted Cloud 控制台、gcloud CLI 或 REST 将 SSH 公钥添加到项目或虚拟机实例元数据中。 您无法为 SSH 密钥设置可用区级元数据值。

将 SSH 密钥添加到项目元数据中

您可以向项目元数据添加 SSH 公钥,以访问项目中的所有虚拟机(屏蔽项目范围 SSH 密钥的虚拟机除外)。如需详细了解如何屏蔽项目范围的 SSH 密钥,请参阅在使用基于元数据的 SSH 密钥的虚拟机中屏蔽 SSH 密钥

控制台

如需使用Trusted Cloud 控制台向项目元数据添加 SSH 公钥,请执行以下操作:

  1. 在 Trusted Cloud 控制台中,前往元数据页面。

    转到元数据

  2. 点击 SSH 密钥标签页。

  3. 点击修改

  4. 点击添加项

  5. 在打开的 SSH 密钥字段中,添加您的 SSH 公钥。密钥必须采用以下格式之一:

    • 没有到期时间的密钥格式:

      KEY_VALUE USERNAME
    • 具有到期时间的密钥格式:

      KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

    替换以下内容:

    • KEY_VALUE:SSH 公钥值
    • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

      对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到 Linux 虚拟机

      对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

    • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000
  6. 点击保存

gcloud

In the Trusted Cloud console, activate Cloud Shell.

Activate Cloud Shell

At the bottom of the Trusted Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  1. 如果项目元数据中存在现有 SSH 密钥,则每次使用 gcloud CLI 添加新的 SSH 密钥时,都必须将这些密钥重新添加到项目元数据中。如果您不重新添加现有密钥,则添加新密钥会清空现有密钥。

    如需使用 gcloud CLI 向项目元数据添加 SSH 公钥,请执行以下操作:

    1. 如果您的项目已具有项目范围的 SSH 公钥,请从元数据中获取这些密钥,并将其添加到新文件中:

      1. 运行 gcloud compute project-info describe 命令以获取项目的 SSH 密钥:

        gcloud compute project-info describe \
         --format="value(commonInstanceMetadata[items][ssh-keys])"
        

        输出类似于以下内容:

        username:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... username:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...
        
      2. 复制 ssh-keys 元数据值。

      3. 在工作站上创建并打开一个新的文本文件。

      4. 在该文件中,粘贴您刚刚复制的密钥列表。

      5. 使用以下格式之一在列表末尾添加新密钥:

        • 没有到期时间的密钥格式:

          USERNAME:KEY_VALUE
        • 具有到期时间的密钥格式:

          USERNAME:KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

        替换以下内容:

        • KEY_VALUE:SSH 公钥值
        • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

          对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到实例

          对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

        • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000
      6. 保存并关闭文件。

    2. 运行 gcloud compute project-info add-metadata 命令来设置项目范围的 ssh-keys 值:

      gcloud compute project-info add-metadata --metadata-from-file=ssh-keys=KEY_FILE
      

      KEY_FILE 替换为以下项之一:

      • 您在上一步中创建的文件的路径(如果项目已有 SSH 密钥)
      • 新建 SSH 公钥文件的路径(如果项目还没有 SSH 密钥)

Terraform

如需向项目元数据添加 SSH 公钥,请使用 google_compute_project_metadata 资源。

resource "google_compute_project_metadata" "default" {
  metadata = {
    ssh-keys = <<EOF
      dev:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILg6UtHDNyMNAh0GjaytsJdrUxjtLy3APXqZfNZhvCeT dev
      test:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILg6UtHDNyMNAh0GjaytsJdrUxjtLy3APXqZfNZhvCeT test
    EOF
  }
}

REST

如果项目元数据中存在现有 SSH 密钥,则每次使用 Compute Engine API 添加新的 SSH 密钥时,都必须将这些密钥重新添加到项目元数据中。如果您不重新添加现有密钥,则添加新密钥会清空现有密钥。

如需使用 Compute Engine API 向项目元数据添加 SSH 公钥,请执行以下操作:

  1. 使用 projects.get 方法从元数据获取 fingerprintssh-keys

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID
    

    PROJECT_ID 替换为您的项目 ID。

    响应类似于以下示例:

    ...
    "fingerprint": "utgYE_XWtE8=",
    "items": [
    {
     "key": "ssh-keys",
     "value": "cloudysanfrancisco:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAu5kKQCPF...\nbaklavainthebalkans:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQDx3FNVC8... google-ssh {"userName":"baklavainthebalkans","expireOn":"2021-06-14T16:59:03+0000"}"
    }
    ]
    ...
    
  2. 使用 projects.setCommonInstanceMetadata 方法添加新的 ssh-keys 值。

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/setCommonInstanceMetadata
    
    {
    "items": [
     {
      "key": "ssh-keys",
      "value": "EXISTING_SSH_KEYS\nNEW_SSH_KEY"
     }
    ]
    "fingerprint": "FINGERPRINT"
    }
    

    替换以下内容:

    • PROJECT_ID:您的项目 ID
    • EXISTING_SSH_KEYSprojects.get 请求的响应中的 ssh-keys 键的值
    • FINGERPRINTprojects.get 请求的响应中的 fingerprint 的值
    • NEW_SSH_KEY:新 SSH 密钥,格式如下:

      • 没有到期时间的密钥格式:

        USERNAME:KEY_VALUE
      • 具有到期时间的密钥格式:

        USERNAME:KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

      替换以下内容:

      • KEY_VALUE:SSH 公钥值
      • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

        对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到实例

        对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

      • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000

将 SSH 密钥添加到实例元数据

您可以在创建虚拟机时在创建虚拟机后向实例元数据添加 SSH 公钥。

在创建虚拟机期间向实例元数据添加 SSH 密钥

您可以在创建虚拟机期间使用Trusted Cloud 控制台、gcloud CLI 或 Compute Engine API 将 SSH 密钥添加到实例元数据。

控制台

如需使用 Trusted Cloud 控制台创建实例并同时向实例元数据添加 SSH 公钥,请执行以下操作:

  1. 在 Trusted Cloud 控制台中,前往创建实例页面。

    转到“创建实例”

  2. 如需向实例元数据添加 SSH 公钥,请执行以下操作:

    1. 在导航菜单中,点击安全

    2. 展开管理访问权限部分。

    3. 如需停用 OS Login,请清除通过 IAM 权限控制虚拟机访问权限复选框。

    4. 如果您希望允许项目元数据中的 SSH 公钥访问实例,请取消选中屏蔽项目范围的 SSH 密钥复选框。

    5. 添加手动生成的 SSH 密钥部分中,点击添加项目

    6. 在文本框中添加公钥。秘钥必须采用以下格式之一:

      • 没有到期时间的密钥格式:

        KEY_VALUE USERNAME
      • 具有到期时间的密钥格式:

        KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

      替换以下内容:

      • KEY_VALUE:SSH 公钥值
      • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

        对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到 Linux 虚拟机

        对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

      • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000
  3. 可选:指定其他配置选项。如需了解详情,请参阅实例创建期间的配置选项

  4. 要创建并启动该实例,请点击创建

gcloud

  1. In the Trusted Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Trusted Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 要使用 gcloud CLI 创建虚拟机并同时向实例元数据添加 SSH 公钥,请使用 gcloud compute instances create 命令

    gcloud compute instances create VM_NAME \
       --metadata=ssh-keys=PUBLIC_KEY
    

    替换以下内容:

    • VM_NAME:新虚拟机的名称
    • PUBLIC_KEY:您的 SSH 公钥,格式如下:

      • 没有到期时间的密钥格式:

        USERNAME:KEY_VALUE
      • 具有到期时间的密钥格式:

        USERNAME:KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

      替换以下内容:

      • KEY_VALUE:SSH 公钥值
      • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

        对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到实例

        对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

      • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000

    您可以使用 --metadata-from-file=ssh-keys=FILE_PATH 标志添加多个 SSH 密钥。在该文件中,添加采用上述格式之一的用户名和 SSH 公钥列表。

Terraform

如需向实例元数据添加 SSH 公钥,请使用 google_compute_instance 资源。

resource "google_compute_instance" "default" {
  name         = "my-vm"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "ubuntu-1404-trusty-v20160627"
    }
  }

  # Local SSD disk
  scratch_disk {
    interface = "SCSI"
  }

  network_interface {
    network = "default"
    access_config {}
  }
  metadata = {
    "ssh-keys" = <<EOT
      dev:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILg6UtHDNyMNAh0GjaytsJdrUxjtLy3APXqZfNZhvCeT dev
      test:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILg6UtHDNyMNAh0GjaytsJdrUxjtLy3APXqZfNZhvCeT test
     EOT
  }
}

REST

如需创建虚拟机并且同时使用 Compute Engine 向实例元数据添加 SSH 公钥,请构建一个向 instances.insert 方法发出的 POST 请求:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances

替换以下内容:

  • PROJECT_ID:项目 ID
  • ZONE:虚拟机所在的区域

在请求正文中,在 items 属性中提供用户名和 SSH 公钥:

...
{
 "items": [
    {
     "key": "ssh-keys",
     "value": "PUBLIC_KEY"
    }
   ]
}
...

PUBLIC_KEY 替换为您的公钥,采用以下格式之一:

  • 没有到期时间的密钥格式:

    USERNAME:KEY_VALUE
  • 具有到期时间的密钥格式:

    USERNAME:KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

替换以下内容:

  • KEY_VALUE:SSH 公钥值
  • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

    对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到实例

    对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

  • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000

您可以通过在密钥之间添加 \n 来添加多个 SSH 密钥。

创建虚拟机后,将 SSH 密钥添加到实例元数据

您可以在创建虚拟机后使用Trusted Cloud 控制台、gcloud CLI 或 Compute Engine API 将 SSH 密钥添加到实例元数据。

控制台

如需使用Trusted Cloud 控制台向实例元数据添加 SSH 公钥,请执行以下操作:

  1. 在 Trusted Cloud 控制台中,前往虚拟机实例页面。

    转到“虚拟机实例”

  2. 点击要为其添加 SSH 密钥的虚拟机的名称。

  3. 点击修改

  4. SSH 密钥下,点击添加项目

  5. 将您的公钥添加到文本框中。密钥必须采用以下格式之一:

    • 没有到期时间的密钥格式:

      KEY_VALUE USERNAME
    • 具有到期时间的密钥格式:

      KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

    替换以下内容:

    • KEY_VALUE:SSH 公钥值
    • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

      对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到 Linux 虚拟机

      对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

    • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000
  6. 点击保存

gcloud

  1. In the Trusted Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Trusted Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. 如果实例元数据中存在现有 SSH 密钥,则每次使用 gcloud CLI 添加新的 SSH 密钥时,都必须将这些密钥重新添加到实例元数据中。如果您不重新添加现有密钥,则添加新密钥会清空现有密钥。

    如需使用 gcloud CLI 向实例元数据添加 SSH 公钥,请执行以下操作:

    1. 如果您的虚拟机已具有实例级 SSH 公钥,请从元数据中获取它们,并将其添加到新文件中:

      1. 运行 gcloud compute instances describe 命令以获取虚拟机的元数据:

        gcloud compute instances describe VM_NAME
        

        VM_NAME 替换为需要添加或移除 SSH 公钥的虚拟机的名称。

        输出类似于以下内容:

        ...
        metadata:
        ...
        - key: ssh-keys
         value: |-
           cloudysanfrancisco:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAu5kKQCPF...
           baklavainthebalkans:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQDx3FNVC8... google-ssh {"userName":"baklavainthebalkans","expireOn":"2021-06-14T16:59:03+0000"}
        ...
        
      2. 复制 ssh-keys 元数据值。

      3. 在工作站上创建并打开一个新的文本文件。

      4. 在该文件中,粘贴您刚刚复制的密钥列表。

      5. 使用以下格式之一在列表末尾添加新密钥:

      • 没有到期时间的密钥格式:

        USERNAME:KEY_VALUE
      • 具有到期时间的密钥格式:

        USERNAME:KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

      替换以下内容:

      • KEY_VALUE:SSH 公钥值
      • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

        对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到实例

        对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

      • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000
      1. 保存并关闭文件。
    2. 运行 gcloud compute instances add-metadata 命令以设置 ssh-keys 值:

      gcloud compute instances add-metadata VM_NAME --metadata-from-file ssh-keys=KEY_FILE
      

      替换以下内容:

      • VM_NAME:您要为其添加 SSH 密钥的虚拟机
      • KEY_FILE 替换为以下项之一:
      • 您在上一步中创建的文件的路径(如果虚拟机已有 SSH 密钥)
      • 新建 SSH 公钥文件的路径(如果虚拟机还没有 SSH 密钥)

REST

如果实例元数据中存在现有 SSH 密钥,则每次使用 Compute Engine API 工具添加新的 SSH 密钥时,都必须将这些密钥重新添加到实例元数据中。如果您不重新添加现有密钥,则添加新密钥会清空现有密钥。

如需使用 Compute Engine API 向实例元数据添加 SSH 公钥,请执行以下操作:

  1. 使用 instances.get 方法从元数据获取 fingerprintssh-keys 值。

    GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME
    

    替换以下内容:

    • PROJECT_ID:您的项目 ID
    • ZONE:要添加 SSH 密钥的虚拟机所在的可用区
    • VM_NAME:您要为其添加 SSH 密钥的虚拟机

    响应类似于以下示例:

    ...
    "fingerprint": "utgYE_XWtE8=",
    "items": [
    {
     "key": "ssh-keys",
      "value": "cloudysanfrancisco:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAu5kKQCPF...\nbaklavainthebalkans:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQDx3FNVC8... google-ssh {"userName":"baklavainthebalkans","expireOn":"2021-06-14T16:59:03+0000"}"
    }
    ]
    ...
    
  2. 使用 instances.setMetadata 方法添加新的 ssh-keys 值。

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setMetadata
    
    {
    "items": [
     {
      "key": "ssh-keys",
      "value": "EXISTING_SSH_KEYS\nNEW_SSH_KEY"
     }
    ]
    "fingerprint": "FINGERPRINT"
    }
    

    替换以下内容:

    • PROJECT_ID:您的项目 ID
    • EXISTING_SSH_KEYSinstances.get 请求的响应中的 ssh-keys 键的值
    • FINGERPRINTprojects.get 请求的响应中的 fingerprint
    • NEW_SSH_KEY:新 SSH 密钥,格式如下:

      • 没有到期时间的密钥格式:

        USERNAME:KEY_VALUE
      • 具有到期时间的密钥格式:

        USERNAME:KEY_VALUE google-ssh {"userName":"USERNAME","expireOn":"EXPIRE_TIME"}

      替换以下内容:

      • KEY_VALUE:SSH 公钥值
      • USERNAME:您的用户名。例如 cloudysanfranciscocloudysanfrancisco_gmail_com

        对于 Linux 虚拟机,除非您将虚拟机配置为允许 root 登录,否则 USERNAME 不能为 root。如需了解详情,请参阅以根用户身份连接到实例

        对于使用 Active Directory (AD) 的 Windows 虚拟机,必须在用户名前面加上格式为 DOMAIN\ 的 AD 域。例如,ad.example.com AD 中的用户 cloudysanfranciscoUSERNAMEexample\cloudysanfrancisco

      • EXPIRE_TIME:密钥的到期时间,采用 ISO 8601 格式。例如:2021-12-04T20:12:00+0000

后续步骤