从快照创建的 Windows Server 2012 虚拟机无法在 GCE 上启动

Posted

技术标签:

【中文标题】从快照创建的 Windows Server 2012 虚拟机无法在 GCE 上启动【英文标题】:Windows Server 2012 VM created from Snapshot fails to Boot on GCE 【发布时间】:2017-09-26 17:21:49 【问题描述】:

我不是 Windows 专家,在从快照恢复 Windows Server 2012 时遇到了问题。我正在尝试根据几周前从 Windows Server 2012 VM 实例创建的快照在 Google Compute Engine-GCE 上创建一个新的 VM 实例。每当我创建一个新的虚拟机时,我永远无法执行 RDP,然后在阅读 GCE 故障排除指南后,我确定可能是 Windows 无法正常启动。我能够如下查看串行端口输出

SeaBios (version 1.8.2-20161003_105447-google)
Total RAM Size = 0x00000003c0000000 = 15360 MiB
CPUs found: 4     Max CPUs supported: 4
found virtio-scsi at 0:3
virtio-scsi vendor='Google' product='PersistentDisk' rev='1' type=0 removable=0
virtio-scsi blksize=512 sectors=314572800 = 153600 MiB
drive 0x000f3120: PCHS=0/0/0 translation=lba LCHS=1024/255/63 s=314572800
Booting from Hard Disk 0...

卡在 从硬盘 0 启动...

我进一步深入研究并阅读串行端口 2 日志如下

Windows Boot Manager
Windows failed to start. A recent hardware or software change might be the cause. To fix the problem: 

Insert your Windows installation disc and restart your computer.
Choose your language settings, and then click "Next."
Click "Repair your computer.
If you do not have this disc, contact your system administrator or computer manufacturer for assistance. 

Status: 
A required device isn't connected or can't be accessed.  

我将磁盘附加到另一台机器上,我可以看到磁盘上的所有文件。但不能修改任何东西,因为磁盘是写保护的。

我从中创建快照的原始 VM 仍然存在,因此我尝试将快照作为引导磁盘附加到原始 VM 实例,以便具有相同的硬件配置,但我无法分离与该实例关联的磁盘,它给了我以下错误。

Hot-remove of the root disk is not supported.

我尝试使用与拍摄快照之前相同的机器类型创建 VM。但也失败了。

关于如何从快照创建新的虚拟机实例并正确启动 Windows 有什么建议吗?

【问题讨论】:

【参考方案1】:

在浏览了许多文章、论坛和用户指南之后,我终于能够从 Snapshot 成功启动 Windows VM 实例。

问题在于引导加载程序和引导配置数据 (BCD)。理想情况下,您将图像用于 OS 磁盘。在我的情况下,操作系统和数据在同一个磁盘中,我们只有一个快照。 GCE 允许从快照创建新的 VM 实例,但在我的情况下,该实例没有启动。

按照分步指南从快照中恢复您的操作系统/数据。

总结:

从快照创建磁盘并使用新的临时 VM 实例修复磁盘 BCD。

详细步骤

第 1 步:创建恢复 VM 实例并启动它

此实例为临时实例,您可以在恢复操作系统/数据后将其删除。

来自谷歌云控制台

选择Compute Engine > VM Instances并选择CREATE INSTANCE

确保选择与快照相同的操作系统。启动后,请确保您可以执行远程桌面并登录到新的 VM 实例。

记下实例名称和运行该实例的区域。

第 2 步:从快照创建新磁盘

来自谷歌云控制台

选择 Compute Engine > 磁盘 并选择 CREATE DISK

确保在拍摄快照之前/之前选择相同的磁盘大小/磁盘类型,否则 Windows 可能会引发启动错误。还要确保磁盘与您的恢复实例位于同一区域。如果您的磁盘与您的实例不在同一个区域,那么您将无法附加它。

第 3 步:将磁盘附加到恢复实例

在此步骤中,您将磁盘(在步骤 2 中创建)附加到 VM 实例(在步骤 1 中创建)

打开 Google Cloud Shell 并输入以下命令

gcloud compute instances attach-disk [INSTANCE-NAME] --disk [DISK-NAME] --zone [ZONE]

将变量替换为您的实例名称、磁盘名称和运行实例的区域。

第 4 步:在 Windows 中挂载磁盘并分配盘符

转到开始 > 搜索并键入 diskmgmt.msc 以打开磁盘管理工具。如果您刚刚附加的磁盘显示为 Offline,请右键单击它并选择 Online

确保磁盘处于联机状态后,验证磁盘上的每个卷都分配了驱动器号。分配的特定驱动器号并不重要。如果任何卷没有分配驱动器号,请右键单击该卷并选择更改驱动器号和路径,然后选择添加。选择分配以下驱动器号,让它选择下一个可用的驱动器号,然后单击确定。同样,实际使用的驱动器号并不重要。

记下驱动器号。对我来说,它的 D:驱动器。

第 6 步:从磁盘中删除写保护

尝试在您连接的驱动器中创建一个新文件夹。如果您的磁盘被写保护并且您无法在驱动器中创建任何文件或文件夹,那么您需要关闭写保护,否则您可以跳过此步骤。

打开提升的命令提示符(以管理员身份运行)并输入

diskpart 

你会得到DISKPART>提示

类型:

list volume 

系统将显示所有带有编号的卷。接下来,您需要通过键入来选择卷:

select volume # 

其中 # 是卷号。对我来说是1。

然后键入以下命令删除写保护

attr disk clear readonly 
attr volume clear readonly
attr volume clear hidden
attr volume clear shadowcopy

通过键入 exit 或关闭命令提示符窗口退出 diskpart。在 Windows 资源管理器中打开驱动器。您应该能够看到所有数据和 Windows 系统文件。在驱动器中创建一个新文件夹以确保磁盘没有写保护。

第 7 步:修复引导配置数据 (BCD)

如果您熟悉 Windows bcedit 命令,那么请务必使用 bcedit,但我使用 EasyBCD 来修复启动配置数据。

从https://neosmart.net/EasyBCD 下载 EasyBCD 并将其安装到您的恢复虚拟机实例上

安装后打开 EasyBCD 并点击

文件 > 选择 BCD 存储

在文件名下的文件选择对话框中输入 D:\Boot\BCD 或您在步骤 5 中分配的任何驱动器号。系统将显示您驱动器的引导配置数据。

点击编辑启动菜单按钮并选择跳过启动菜单并点击保存设置

点击高级设置按钮并在基本标签下点击驱动器:菜单并选择磁盘的驱动器号。

请注意:驱动器号应与Step-5相同

点击BCD Backup/Repair按钮并在BCD管理选项下选择重新创建/修复启动文件并点击执行操作按钮。

再次打开磁盘管理使磁盘脱机,然后右键单击磁盘并选择脱机

现在最小化您的 RDP 窗口并在 Google Cloud Shell 中键入以下命令以从恢复实例中分离磁盘

gcloud compute instances detach-disk [INSTANCE-NAME] --disk [DISK-NAME] --zone [ZONE]

现在您已经修复了从快照创建的磁盘的引导配置数据。

我们现在已准备好旋转 VM 实例并使用此磁盘启动它。让我们从磁盘创建实例

第 8 步:创建新的虚拟机实例

从 Google Cloud Console 中选择 Compute Engine > VM Instances 并选择 CREATE INSTANCE

为避免在首次运行时出现任何问题,请确保选择与创建快照时/之前相同的机器类型

此时,您应该能够拥有正常工作的 VM 实例,并且您应该能够进行 RDP 登录。

如果您仍然遇到任何问题,请通过单击 Google Cloud Console 中的 VM 实例查看您的串行端口日志,然后向下滚动到页面底部,或者您可以在 Google Cloud Shell 中键入以下命令.

gcloud compute instances get-serial-port-output [INSTANCE-NAME] --zone [ZONE]

经验教训

对于有/无数据的操作系统磁盘,使用图像而不是快照。 不要将数据保存在与操作系统相同的磁盘中,即使它是一台测试机器并且您正在做一些临时工作。

【讨论】:

【参考方案2】:

感谢您提供详细的答案。这里的关键问题是,当您拍摄 VSS 启动的快照时,Windows 会将卷标记为只读/快照。 GCE Persistent Disk Snapshot 将保留该标志。所有数据都是正确和一致的。您需要做的就是按照 step1-step6 的概述删除这些标志。

第 7 步的一个小建议。您可以简单地使用内置工具 bcdboot.exe 来修复它。

bcdboot.exe D:\Windows /s D:

(BCD Hive其实是可以的,但是MBR中的磁盘签名是在手动联机磁盘时被Windows修改的,所以我们需要在这里运行命令使其恢复到与启动数据库一致)。

【讨论】:

感谢冯敏提供的信息。非常感谢您的反馈。 我只想补充一点,这里提到了这一点。我也刚刚注意到cloud.google.com/compute/docs/instances/windows/…【参考方案3】:

@Shaheryar 的回答太棒了!!如果您需要自动化/编写某些步骤的脚本,您可以使用以下内容:

第 4 步和第 6 步

通过将以下内容放入mount.txt 文件中,可以使磁盘联机并清除读取标志:

rem This script is mean to be run with diskpart /s mount.txt
rem It mounts the snapshot volume to D:/ and makes it writeable

list disk

rem The snapshot disk should be on disk #1
rem Use `list disk` to find it if it changed - also update unmount.txt

select disk 1
online disk

rem The partition should be on volume #2
rem Use `list volume` to find it if it changed - also update unmount.txt

select volume 2
assign letter=D

attr disk clear readonly
attr volume clear readonly
attr volume clear hidden
attr volume clear shadowcopy

exit

从管理控制台/shell,使用

运行此文件
diskpart /s mount.txt

第 7 步

修复 BCD 的 GUI 步骤可以在管理员 Powershell 会话中替换为以下命令:

attrib -h -s D:\Boot\BCD
Remove-Item -Path D:\Boot\BCD

# Recreate BCD
bcdedit.exe /createstore D:\Boot\BCD
bcdedit.exe /store D:\Boot\BCD /create "bootmgr" /d "Windows Boot Manager"
bcdedit.exe /store D:\Boot\BCD /set "bootmgr" device partition=D:
bcdedit.exe /store D:\Boot\BCD /set "bootmgr" displaybootmenu No
bcdedit.exe /store D:\Boot\BCD /timeout 0

$out = bcdedit.exe /store D:\Boot\BCD /create /d "Microsoft Server" /application osloader
$id = Select-String -Input $out -Pattern '.+'  -AllMatches | %  $_.Matches  | %  $_.Value 

# Output from above
bcdedit.exe /store D:\Boot\BCD /set "$id" device partition=D:
bcdedit.exe /store D:\Boot\BCD /set "$id" osdevice partition=D:
bcdedit.exe /store D:\Boot\BCD /set "$id" path \Windows\system32\winload.exe
bcdedit.exe /store D:\Boot\BCD /set "$id" systemroot \Windows
bcdedit.exe /store D:\Boot\BCD /set "$id" nx OptOut
bcdedit.exe /store D:\Boot\BCD /set "$id" allowedinmemorysettings 0x15000075
bcdedit.exe /store D:\Boot\BCD /set "$id" inherit "6efb52bf-1766-41db-a6b3-0ee5eff72bd7"
bcdedit.exe /store D:\Boot\BCD /set "$id" resumeobject "45e743a4-934e-11e9-a872-8c17a054efa7"

bcdedit.exe /store D:\Boot\BCD /displayorder "$id"

# Print result
bcdedit.exe /store D:\Boot\BCD /enum /v

这些steps are adopted 来自 EasyBCD 的创建者。通过反复试验发现缺少的步骤与 EasyBCD GUI 将创建的结果文件相匹配。

缺少卸载步骤

您可能还想在分离之前卸载该卷。这可以通过将以下内容放入 unmount.txt 文件中来完成:

rem This script unmounts the snapshot after its bootloader has been fixed

rem See mount.txt for why volume 2
select volume 2
remove

rem See mount.txt for why disk 1
select disk 1
offline disk

exit

最后,使用管理控制台/shell 运行它

diskpart /s mount.txt

【讨论】:

以上是关于从快照创建的 Windows Server 2012 虚拟机无法在 GCE 上启动的主要内容,如果未能解决你的问题,请参考以下文章

Windows Server 2012 Hyper-V 快照

SQL Server 2012 创建数据库快照

网络存储技术Windows server 2012 (项目五 存储服务器的数据快照计划与故障还原)

网络存储技术Windows server 2012 (项目五 存储服务器的数据快照计划与故障还原)

linux-创建/使用快照/克隆(类似windows中备份还原)

成功创建 Always On SQL Server 快照后,Debezium 未跟踪 CDC