排查虚拟机启动问题

本文档包含有关配额错误启动磁盘启动脚本所导致的虚拟机启动问题的问题排查信息。

配额错误

如果您在尝试启动实例时收到配额错误,则必须申请额外的 CPU 配额。如需了解详情,请参阅资源配额文档的虚拟机实例部分。

启动磁盘

如果您的实例无法启动,并且您无法连接到该实例或通过交互式串行控制台进行登录,请确定启动磁盘未能完成引导和启动过程的原因。

确定启动磁盘未启动的原因

  • 验证启动磁盘是否未满

    如果您的启动磁盘已满,并且您的操作系统不支持自动调整大小,您将无法连接到您的实例。您必须创建新实例并重新创建启动磁盘。请参阅恢复无法访问的实例或存储空间已满的启动磁盘

  • 检查虚拟机实例的串行端口输出。

    实例的 BIOS、引导加载程序和内核会将其调试消息输出到实例的串行端口输出,从而提供有关实例遇到的任何错误或问题的宝贵信息。如果您启用将串行端口输出记录到 Cloud Logging 的功能,则即使实例未运行,您也可以访问此信息。

  • 启用对串行控制台的交互式访问。

    您可以启用对实例串行控制台的交互式访问,以便从实例内部登录并调试启动问题,而无需完全启动实例。如需了解详情,请参阅与串行控制台进行交互

  • 验证您的磁盘是否具有有效的文件系统。

    如果您的文件系统已损坏或者无效,您将无法启动您的实例。要验证您的磁盘的文件系统,请执行以下步骤:

    1. 如果适用,请将相关磁盘从其挂接的任何实例中分离:

      gcloud compute instances delete old-instance --keep-disks boot

    2. 使用 Google 提供的最新映像启动新实例:

      gcloud compute instances create debug-instance

    3. 将您的磁盘作为非启动磁盘来挂接,但不装载该磁盘。将 DISK 替换为将不启动的磁盘的名称。请记下用于标识实例上磁盘的设备名称:

      gcloud compute instances attach-disk debug-instance 
      --disk DISK
      --device-name debug-disk

    4. 连接实例:

      gcloud compute ssh debug-instance

    5. 查找磁盘的根分区,此分区以 part1 表示法标识。在本示例中,磁盘的根分区位于 /dev/sdb1

      ls -l /dev/disk/by-id
      total 0
      lrwxrwxrwx 1 root root  9 Jan 22 17:09 google-debug-disk -> ../../sdb
      lrwxrwxrwx 1 root root 10 Jan 22 17:09 google-debug-disk-part1 -> ../../sdb1
      lrwxrwxrwx 1 root root  9 Jan 22 17:02 google-persistent-disk-0 -> ../../sda
      lrwxrwxrwx 1 root root 10 Jan 22 17:02 google-persistent-disk-0-part1 -> ../../sda1
      lrwxrwxrwx 1 root root  9 Jan 22 17:09 scsi-0Google_PersistentDisk_debug-disk -> ../../sdb
      lrwxrwxrwx 1 root root 10 Jan 22 17:09 scsi-0Google_PersistentDisk_debug-disk-part1 -> ../../sdb1
      lrwxrwxrwx 1 root root  9 Jan 22 17:02 scsi-0Google_PersistentDisk_persistent-disk-0 -> ../../sda
      lrwxrwxrwx 1 root root 10 Jan 22 17:02 scsi-0Google_PersistentDisk_persistent-disk-0-part1 -> ../../sda1
      
    6. 在根分区上运行文件系统检查:

      sudo fsck /dev/sdb1
      fsck from util-linux 2.20.1
      e2fsck 1.42.5 (29-Jul-2012)
      /dev/sdb1: clean, 19829/655360 files, 208111/2621184 blocks
      

    7. 装载文件系统:

       sudo mkdir /mydisk
      
       sudo mount /dev/sdb1 /mydisk
      
    8. 检查磁盘是否具有内核文件:

       ls /mydisk/boot/vmlinuz-*
      /mydisk/boot/vmlinuz-3.2.0-4-amd64
      
  • 验证磁盘是否具有有效的主启动记录 (MBR)

    在挂接了永久性启动磁盘(例如 /dev/sdb)的调试实例上运行以下命令:

     sudo parted /dev/sdb print
    

    如果您的 MBR 有效,则该命令会列出有关文件系统的信息:

     Disk /dev/sdb: 10.7GB
     Sector size (logical/physical): 512B/4096B
     Partition Table: msdos
     Disk Flags:
     Number  Start   End     Size    Type     File system  Flags
      1      2097kB  10.7GB  10.7GB  primary  ext4         boot
     

解决启动问题

在确定引导和启动过程失败的位置后,您可以通过完成以下操作之一来解决问题:

创建独立的启动磁盘

将导入的映像装载到已挂接到临时虚拟机实例的辅助磁盘上。使用 Cloud Console 或 gcloud 工具从您上传的映像创建一个独立磁盘,并创建一个挂接该独立磁盘的临时虚拟机。您可以使用此实例修改独立磁盘上的文件,并解决导致该映像无法启动的问题。

控制台

您可以从导入的启动磁盘映像创建独立磁盘,也可以将启动磁盘与实例分离,并使用分离后的启动磁盘创建实例。

  1. 在 Cloud Console 中,转到磁盘页面。

    转到“磁盘”

  2. 点击创建磁盘
  3. 创建磁盘页面上,指定以下特性:
    • 区域Select a zone near you. You must use this same zone when you create your temporary instance.
    • 磁盘来源类型映像
    • 来源映像: Specify the name of the boot disk image that you imported.
  4. 如需创建磁盘,请点击创建

创建您可以在其中挂接独立磁盘的临时实例,并将引导加载程序配置为在 Cloud Console 环境中运行。

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。

    转到实例

  2. 点击创建实例按钮。

  3. 创建实例页面,指定实例名称以及该实例所在的地区。此可用区必须与您之前创建独立磁盘的可用区相同。

  4. 展开管理、安全、磁盘、网络、单独租用部分。

  5. 磁盘标签页下的额外磁盘部分,点击挂接现有磁盘。系统随即会显示一个新的部分。

  6. 磁盘部分下,从下拉列表中选择您创建的独立磁盘。 此操作会将独立磁盘连接到实例,以便您稍后可以装载该磁盘并修改其内容。

  7. 点击完成以完成挂接磁盘操作。

  8. 点击创建按钮创建实例。

gcloud

您可以从导入的启动磁盘映像创建独立磁盘,也可以将启动磁盘与实例分离,并使用分离后的启动磁盘创建实例。

 gcloud compute disks create DISK_NAME 
--zone ZONE
--image IMAGE_NAME

替换以下内容:

  • DISK_NAME:新独立磁盘的名称。
  • ZONE:离您比较近的可用区。在创建临时实例时,您必须使用该可用区。
  • IMAGE_NAME:您导入的启动磁盘映像的名称。

创建您可以在其中挂接独立磁盘的临时实例,并将引导加载程序配置为在 Cloud Console 环境中运行。

gcloud compute instances create INSTANCE_NAME --zone ZONE --disk name=DISK_NAME

替换以下内容:

  • INSTANCE_NAME:您的实例的唯一名称
  • ZONE:您创建独立磁盘的可用区
  • DISK_NAME:您从导入的启动磁盘映像创建的独立磁盘的名称

在使用挂接的独立磁盘创建实例后,您将拥有一个虚拟环境,并可以在其中从原始启动磁盘映像修改引导加载程序。

配置启动磁盘

连接到实例,装载独立磁盘并配置引导加载程序,以便该实例能够在 Compute Engine 上正常启动。

  1. 通过浏览器使用 SSH 连接到临时实例,或使用 gcloud compute ssh 命令实现此连接。
  2. 使用 blkid 命令确定您要修改的磁盘以及需要装载的分区。在此示例中,/dev/sdb 是您之前导入的磁盘。

    lsblk
    
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda      8:0    0   10G  0 disk
    └─sda1   8:1    0   10G  0 part /
    sdb      8:16   0  100G  0 disk
    ├─sdb1   8:17   0   96G  0 part
    ├─sdb2   8:18   0    1K  0 part
    └─sdb5   8:21   0    4G  0 part
    
  3. 将独立磁盘的根分区装载到 /tmp 目录。在此示例中,/dev/sdb1 是根分区,而其他分区不需要任何修改。您的分区方案可能要求您必须装载多个分区才能访问所有需要更改的文件。

    sudo mount /dev/sdb1 /tmp
    
  4. 修改可能导致磁盘启动过程失败的文件。如需了解详情,请参阅引导加载程序配置说明

  5. 从临时实例中卸载启动磁盘。

    sudo umount /tmp
    

使用启动磁盘

完成此磁盘的配置后,请将其分离出来并用作新实例的启动磁盘。

控制台

从临时实例中分离独立磁盘。

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。

    转到实例

  2. 在实例列表中,点击您修改了其独立启动磁盘的临时实例的名称。实例详情页面会打开。

  3. 在实例详情页面顶部,点击修改

  4. 额外磁盘下,点击独立磁盘旁边的 X,以指示您想要将该磁盘从临时实例中分离出来。

  5. 点击保存以保存更改。

使用已分离的独立磁盘来创建实例。

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。

    转到实例

  2. 点击创建实例按钮。

  3. 创建实例页面,指定实例名称以及该实例所在的地区。此可用区必须与您之前创建独立磁盘的可用区相同。

  4. 启动磁盘下,点击更改以开始配置您的启动磁盘。

  5. 现有磁盘标签页中,选择要用作此新实例启动磁盘的独立启动磁盘。

  6. 点击创建按钮创建实例。

gcloud

从临时实例中分离独立磁盘。

gcloud compute instances detach-disk INSTANCE_NAME --disk DISK_NAME

替换以下内容:

  • INSTANCE_NAME:您的实例的唯一名称。
  • DISK_NAME:新独立磁盘的名称。

使用已分离的独立磁盘来创建实例。

gcloud compute instances create INSTANCE_NAME --zone ZONE --disk name=DISK_NAME,boot=yes

替换以下内容:

  • INSTANCE_NAME:您的实例的唯一名称
  • ZONE:独立磁盘所在的可用区
  • DISK_NAME:您从导入的启动磁盘映像创建的独立磁盘的名称

测试您使用修改后的启动磁盘创建的实例。如果您仍然无法连接到实例,请再次读取串行控制台输出以确定启动过程失败的位置。重复此问题排查过程,直到您纠正了启动磁盘映像的各种问题为止。

启动脚本

启动脚本问题可能与元数据服务器的网络连接有关:

  • 对于 Linux 虚拟机,Compute Engine 在尝试从元数据服务器获取信息(例如自定义启动或关停脚本)之前,将等待连接到元数据服务器。如果元数据服务器无响应,或您尚未配置网络,则虚拟机将无法完成启动。

  • 对于映像早于 v20160606 的 Linux 虚拟机,串行端口输出会显示 "Waiting for metadata server, attempt N",其中 N 是已尝试的次数。

    由于一个暂时性的网络问题,此问题可能持续长达七分钟,但会自行解决。如果问题在七分钟后无法自行解决,请重新创建虚拟机实例。