连接到在 GDC 上使用虚拟机运行时的虚拟机

本文档适用于运行 GKE on Bare Metal 的应用所有者。本文档介绍了如何连接到在 GDC 上使用虚拟机运行时的虚拟机 (VM)。您可以使用 IP 地址直接连接到虚拟机,也可以使用内置的工具进行 SSH 或控制台访问。

准备工作

要完成本文档,您需要拥有以下资源的访问权限:

配置对虚拟机的无密码 SSH 访问

通过 GDC 上的 VM Runtime 安装的访客代理,可以实现对虚拟机的无密码直接 SSH 访问。除此之外,客机代理还会安装 SSH 密钥并使其过期。此功能使 SSH 隧道可以从集群网络外部的客户端访问您的虚拟机。

启用客机代理

如需启用客机代理,请执行以下操作:

  1. 检查您的 VirtualMachine 自定义资源,以确认其已配置为启用客机代理:

    kubectl get gvm VM_NAME -o yaml --kubeconfig KUBECONFIG
    

    spec.osType 字段应设置为虚拟机的操作系统:LinuxWindowsspec.guestEnvironment 部分不应明确配置为空。如果该部分配置为空 (guestEnvironment: {}),则可以完全移除该部分以启用客机代理。

    您要访问的虚拟机的 VirtualMachine 自定义资源应如下所示:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      name: sample-vm
    spec:
      compute:
        cpu:
          vcpus: 2
        memory:
          capacity: 4Gi
    ...
      osType: Linux
    ...
    
  2. 如有必要,请使用 kubectl edit 更新 VirtualMachine 自定义资源。

  3. 如需验证客机代理是否正常运行,请检查虚拟机自定义资源中的 status

    kubectl get gvm VM_NAME --kubeconfig KUBECONFIG
    

    当客机代理正常运行时,您会看到 GuestEnvironmentEnabledGuestEnvironmentDataSynced 条件为 status: "True"

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      ...
      name: vm-sample-01
      ...
    status:
      conditions:
      - lastTransitionTime: "2022-10-05T22:40:26Z"
        message: ""
        observedGeneration: 1
        reason: UserConfiguration
        status: "True"
        type: GuestEnvironmentEnabled
      - lastTransitionTime: "2022-10-06T21:55:57Z"
        message: ""
        observedGeneration: 1
        reason: GuestEnvironmentDataSynced
        status: "True"
        type: GuestEnvironmentSynced
      ...
    

启用无密码 SSH 访问

如需为您的虚拟机启用无密码 SSH 访问,请执行以下操作:

  1. 在您选择的编辑器中创建 VirtualMachineAccessRequest 清单文件,例如 vm-access-request.yaml

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineAccessRequest
    metadata:
      name: VMAR_NAME
      namespace: VM_NAMESPACE
    spec:
      vm: VM_NAME
      user: USERNAME
      ssh:
        key: PUBLIC_SSH_KEY
        ttl: EXPIRATION_TIME
    

    替换以下内容:

    • VMAR_NAME:访问请求资源的名称。
    • VM_NAMESPACE:您要访问的虚拟机的命名空间。
    • VM_NAME:您要访问的虚拟机的名称。
    • USERNAME:正在访问虚拟机的用户的用户名。
    • PUBLIC_SSH_KEY:用于 SSH 访问的公钥。通常,这是 id_rsa.pub 文件的内容。
    • EXPIRATION_TIMEttl(存留时间)字段指定 SSH 密钥的有效期。

      例如,如果您指定 30m,则 SSH 密钥会在 30 分钟后到期。

      此标志使用下列单位:

      • s 表示秒数
      • m 表示分钟数
      • h 表示小时数
      • d 表示天数
  2. 使用 kubectl apply 根据清单文件创建 VirtualMachineAccessRequest。例如,如果您将清单文件命名为 vm-access-request.yaml

    kubectl apply -f MANIFEST --kubeconfig KUBECONFIG
    

    替换以下内容:

    • MANIFEST:访问请求清单文件的名称。例如 vm-access-request.yaml
    • KUBECONFIG:托管您要访问的虚拟机的集群 kubeconfig 文件的路径。
  3. 如需验证您的访问请求配置是否成功,请检查 VirtualMachineAccessRequest 的状态:

    kubectl get vmar VMAR_NAME -o yaml --kubeconfig KUBECONFIG
    

    配置成功后,status 部分将包含 state: configured

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachineAccessRequest
    metadata:
      ...
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"vm.cluster.gke.io/v1","kind":"VirtualMachineAccessRequest",
          "metadata":{"annotations":{},"name":"vmar-sample","namespace":"default"},
          "spec":{"ssh":{"key":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ...jMLHFc=
              sample-user@sample-host","ttl":"5h"},"user":"sample-user","vm":"vm-sample-01"}}
      creationTimestamp: "2022-10-06T21:55:57Z"
      finalizers:
      - vm.cluster.gke.io/vmar-finalizer
      generation: 2
      name: vmar-sample
      namespace: default
      resourceVersion: "13033921"
      uid: 282d72ad-f48d-4e89-af22-336940ac9f58
    spec:
      ssh:
        key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ...jMLHFc= sample-user@sample-host
        ttl: 5m0s
      user: sample-user
      vm: vm-sample-01
    status:
      processedAt: "2022-10-06T21:55:57Z"
      state: configured
    

停用客机代理

当您创建新虚拟机并设置 osType 字段时,系统将启用客机代理。此功能目前为预览版,您可以通过修改 VirtualMachine 自定义资源来停用它。停用客机代理会停用对虚拟机的无密码 SSH 访问。

如需停用客机代理,请执行以下操作:

  1. 在更改配置之前,请使用 kubectl 停止您的虚拟机:

    kubectl virt stop VM_NAME --kubeconfig KUBECONFIG
    
  1. 修改虚拟机资源:

    kubectl edit gvm VM_NAME --kubeconfig KUBECONFIG
    
  2. 更新 VirtualMachine 配置以明确添加空的 spec.guestEnvironment

    apiVersion: vm.cluster.gke.io/v1alpha1
    kind: VirtualMachine
    metadata:
      name: vm-example
      namespace: default
    spec:
      compute:
      ...
      osType: Linux
      guestEnvironment: {}
    
  3. 在编辑器中保存并关闭更新后的虚拟机清单。

  4. 使用 kubectl 启动虚拟机:

    kubectl virt start VM_NAME --kubeconfig KUBECONFIG
    

使用 IP 地址连接

如果您的虚拟机具有可访问的 IP 地址,并且您已经拥有访问虚拟机的凭据,则可以使用 SSH、VNC 或 RDP 等协议进行连接。

通过 IP 地址连接

如果您可以直接连接到虚拟机的 IP 地址,请使用以下任一方法:

SSH

  1. 获取虚拟机的详细信息以查看其 IP 地址:

    kubectl get gvm VM_NAME --namespace VM_NAMESPACE --kubeconfig KUBECONFIG
    

    替换以下值:

    • VM_NAME:虚拟机的名称。
    • VM_NAMESPACE:虚拟机的命名空间。

    以下示例输出显示了虚拟机信息和 IP 地址:

    NAME   STATUS    AGE   IP
    vm1    Running   7m    10.200.0.21
    
  2. 使用 SSH 客户端连接到您的虚拟机:

    ssh USERNAME@IP_ADDRESS -i PATH_TO_KEY
    

    替换以下值:

    • USERNAME:虚拟机上账号的用户名。
    • IP_ADDRESS:您在上一步获得的虚拟机的 IP 地址。
    • PATH_TO_KEY:SSH 私钥的路径。

VNC 或 RDP

虚拟网络计算 (VNC)远程桌面协议 (RDP) 可让您使用图形控制台访问虚拟机。使用 IP 地址时,您必须在客机操作系统中启用 VNC 或 RDP,然后才能使用 VNC 或 RDP 连接到虚拟机。如需了解如何启用和使用 VNC 或 RDP,请参阅您的客机操作系统的文档。

您还需要使用现有凭据登录虚拟机,例如您在创建虚拟机时为创建初始用户凭据而定义的凭据。

  1. 获取虚拟机的详细信息以查看其 IP 地址:

    kubectl get gvm VM_NAME --namespace VM_NAMESPACE --kubeconfig KUBECONFIG
    

    替换以下值:

    • VM_NAME:虚拟机的名称。
    • VM_NAMESPACE:虚拟机的命名空间。

    以下示例输出显示了虚拟机信息和 IP 地址:

    NAME   STATUS    AGE   IP
    vm1    Running   7m    10.200.0.21
    
  2. 使用客户端工具和相应端口(例如 VNC 端口 5900 或 RDP 端口 3389)连接到上一步获得的虚拟机的 IP 地址。

通过 Service 连接

如果您的虚拟机连接至默认的 pod-network,并且您无法直接与虚拟机的 IP 地址通信,请在负载均衡器 Service 后面公开虚拟机。

  1. 在您选择的编辑器中创建 Service 清单,例如 my-service-load-balancer.yaml

    nano my-service-load-balancer.yaml
    
  2. 复制并粘贴以下 YAML 清单:

    apiVersion: v1
    kind: Service
    metadata:
      name: VM_NAME-service
    spec:
      selector:
        kubevirt/vm: VM_NAME
      ports:
      - name: PORT_NAME
        protocol: PROTOCOL_TYPE
        port: EXTERNAL_PORT
        targetPort: TARGET_PORT
      type: LoadBalancer
    

    在此 Service 清单类型中,替换以下值:

    • VM_NAME:要公开进行远程访问的虚拟机的名称。
    • PORT_NAME:您的协议的名称,例如 sshvncrdp
    • PROTOCOL_TYPE:协议类型,例如 tcp(SSH 和 RDP)或 udp (VNC)。
    • EXTERNAL_PORT:要公开且用于连接的外部端口号。
    • TARGET_PORT:目标端口,例如 22 (SSH)。
  3. 在编辑器中保存并关闭 Service 清单。

  4. 使用 kubectl 创建 Service

    kubectl apply -f my-service-load-balancer.yaml  --kubeconfig KUBECONFIG
    
  5. 获取负载均衡器服务的 EXTERNAL-IP 地址:

    kubectl get service VM_NAME-service --kubeconfig KUBECONFIG
    

    此时将显示负载均衡器的 IP 地址,如以下示例输出中所示:

    NAME          TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
    vm1-service   LoadBalancer   172.26.232.167   10.200.0.51   22:31141/TCP   6d20h
    
  6. 使用标准协议连接到负载均衡器的 EXTERNAL-IP 地址,例如使用 SSH 客户端:

    ssh USERNAME@LOAD_BALANCER_IP_ADDRESS  -i PATH_TO_KEY
    

    替换以下值:

    • USERNAME:虚拟机上账号的用户名。
    • LOAD_BALANCER_IP_ADDRESS:负载均衡器的 IP 地址。
    • PATH_TO_KEY:SSH 私钥的路径。

使用 SSH 直接连接

如果客户端连接到 Anthos clusters on Bare Metal 节点所在的物理网络,并且您不需要使用 SSH 隧道连接到集群,则可以使用 kubectl virt ssh 进行连接。

  1. 如需从控制台使用 SSH 通过 virtctl 插件连接 Linux 虚拟机,请执行以下操作:

    kubectl virt ssh USERNAME@VM_NAME --namespace VM_NAMESPACE --kubeconfig KUBECONFIG
    

    替换以下值:

    • USERNAME:用于访问虚拟机的用户名。如果虚拟机上不存在此账号,则会创建此账号。
    • VM_NAME:您的虚拟机的名称。
  2. 使用 SSH 成功连接后,不再需要连接,请退出 SSH 会话:

    exit
    

使用控制台直接连接

如果您没有与 Linux 虚拟机的直接网络连接来进行 SSH 访问,请使用 GDC 控制台上的 VM Runtime 连接到虚拟机的控制台。此方法会打开串行控制台。连接后,您会看到一个命令提示符,而不是图形控制台。

  1. 如需从控制台访问 Linux 虚拟机,请使用 virtctl 插件:

    kubectl virt console VM_NAME --kubeconfig KUBECONFIG
    

    VM_NAME 替换为虚拟机名称。

    出现提示时,请输入您的虚拟机的用户凭据。这些凭据必须存在于虚拟机上,或者在创建虚拟机时应用。如果需要,请参阅以下部分以了解在创建虚拟机时创建初始用户凭据

  2. 成功连接到虚拟机的控制台后,如果不再需要连接,请退出虚拟机会话和控制台:

    Ctrl + ]
    

使用 VNC 直接连接

您可以使用 kubectl virt vnc 命令打开虚拟网络计算 (VNC) 图形控制台以访问虚拟机。此方法适用于运行 Windows 或 Linux 客机操作系统的虚拟机。当您使用 kubectl virt vnc 命令时,GDC 上的虚拟机运行时会为您打开 VNC,因此您无需在客机操作系统中启用 VNC。

您需要使用现有凭据登录虚拟机,例如您在创建虚拟机时为创建初始用户凭据而定义的凭据。

  1. 如需使用 VNC 访问虚拟机,请使用 virtctl 插件:

    kubectl virt vnc VM_NAME --kubeconfig KUBECONFIG
    

    VM_NAME 替换为虚拟机名称。

    出现提示时,请输入您的虚拟机的用户凭据。

  2. 成功连接虚拟机的 VNC 会话且不再需要连接后,从虚拟机退出登录以关闭 VNC 连接。

创建初始用户凭据

使用控制台连接到虚拟机时,您必须指定用户凭据。对于 Linux 和 Windows 客机操作系统,创建初始用户凭据的过程有所不同。

Linux 客机操作系统

对于 Linux 虚拟机,用户凭据可以内置到自定义映像中,也可以在创建虚拟机时指定。

  • --configure-initial-password 参数用于 kubectl virt create 命令:

    kubectl virt create vm VM_NAME \
        --image ubuntu20.04 \
        --os-type Linux \
        --configure-initial-password USERNAME:PASSWORD \
        --kubeconfig KUBECONFIG
    

    替换以下值:

    • VM_NAME:虚拟机的名称。
    • USERNAME:要在虚拟机中创建的账号的用户名。
    • PASSWORD:用户账号的密码。

    此示例命令会创建一个 Linux 虚拟机来运行 Ubuntu 20.04。建议您在首次登录虚拟机后更改初始凭据。

Windows 客机操作系统

请按照以下步骤操作,重置现有用户的密码或为新用户创建初始密码:

  1. 在 Windows 虚拟机中启用客机代理:

    1. 配置虚拟机以启用客机代理

    2. 使用 VNC 或 RDP 连接到虚拟机。

    3. 在虚拟机中,转到 guest agent 驱动器。在大多数情况下,这是驱动器 E:

    4. 使用 PowerShell 运行 install.ps1

      这将安装并启动客机代理。客机代理会在后续虚拟机重新启动时自动启动。

    5. 关闭远程会话。

  2. 在管理员工作站上,使用以下命令重置(如果使用新的用户名,则为设置)Windows 虚拟机密码:

    kubectl virt reset-windows-password VM_NAME \
        --user=USERNAME \
        --namespace=VM_NAMESPACE
    

    替换以下内容:

    • VM_NAME:虚拟机的名称。
    • USERNAME:您要重置(或设置)密码的用户名。如果用户名是新的,该命令会创建一个新的 Windows 账号并设置初始密码。
    • VM_NAMESPACE:(可选)虚拟机的命名空间。此标志是可选标志。如果未指定,则使用默认命名空间 default

    如需重置(或设置)密码而不显示确认提示,请使用可选的 --force 标志。如果使用 --force 标志,命令会显示提示,警告您重置现有账号的密码的后果。如果不使用 --force 标志,则命令会显示以下文本,提示您确认密码重置:

    This command creates an account and sets an initial password for the
    user USERNAME if the account does not already exist.
    If the account already exists, resetting the password can cause the
    LOSS OF ENCRYPTED DATA secured with the current password, including
    files and stored passwords.
    
    Would you like to set or reset the password for USERNAME (Y/n)?
    

    确认(或强制)密码重置后,该命令将返回指定虚拟机和用户名的新密码:

    Resetting and retrieving password for USERNAME on VM_NAME
    
    vm_name:    VM_NAME
    username:   USERNAME
    password:   PASSWORD
    

后续步骤