将 Ubuntu 16 PV 转换为 Ubuntu 16 HVM 后无法连接到 EC2 实例

Ale*_*lex 4 hard-drive amazon-ec2 paravirtualization nvme hvm

所以已经几天了,我仍然无法连接到运行 Ubuntu 16 的 EC2 的新 HVM 实例。作为参考,我正在尝试将我们的服务器从运行 Ubuntu 16 的 m3 实例升级到运行 Ubuntu 16 的 C5 实例。对于几乎我尝试过的所有方法,我都可以停止我的新 C5 实例,分离所有卷,并将新更新的源卷附加为/dev/sda1,但是当我去连接到实例时,我总是最终超时。亚马逊的状态检查也失败了,因为它说实例无法访问。但是,系统日志在启动时没有显示任何问题。

我已经尝试在这篇文章中做所有事情。我也试过这个帖子。我看过其他网站,并尝试过这个这个。我什至尝试过 ec2 命令行工具方法和从 ec2 控制台(在线)转换 AMI,但是我要么无法使用转换后的 AMI 启动 C5 实例,要么实例将停止并失败(在通过命令行转换)。

我真正能想到的唯一原因可能是 C5 实例上的分区的命名约定。我见过的每一个指南都使用xvda/xvdf/xvdg. 我可能是错的,但我没有这些分区或磁盘,而是有nvme0n1nvme0n1p1、(新的 HVM 根)nvme1n1、 和nvme1n1p1。当我尝试 HVM / 源 / 目标磁盘方法时,我有nvme0n1/nvme0n1p1nvme1n1(目标 - 一切都应该结束的地方)和nvme2n1/nvme2n1p1(源 - 一切来自哪里,在 m3 上)。我发现了这篇关于 nvme 的亚马逊帖子,所以我不认为这应该是一个问题,因为我只是在使用时使用了正确的磁盘/分区/mnt/,即。我打电话mkdir -p /mnt/target && mount /dev/nvme1n1 /mnt/target而不是mkdir -p /mnt/target && mount /dev/xvdf /mnt/target,但到目前为止没有任何效果。当我附加targetas 时,我的实例变得无法访问/dev/sda1

那么,在使用名为 的磁盘执行这些操作时,我是否遗漏了什么nvme*?我可以提供任何其他信息或调试内容来帮助理解问题吗?

Ale*_*lex 5

我意识到这个问题并没有被很多人看到,但以防万一,我希望我的结果可以在将来对某人有所帮助(甚至可能是我下次尝试这样做时)。我要感谢来自 Amazon 支持的 Steve E. 帮助我迁移了我的实例 <3

无论如何,将我的 Ubuntu 16.04 M3 (PV) 实例迁移到 Ubuntu 16.04 C5 (HVM) 实例时存在 2 个问题。第一个问题是新的 C5 实例确实使用了新的命名约定,因此其他有关将 PV 迁移到 HVM 的教程的工作方式并不完全相同。另一个问题是我的 M3 (PV) 实例已经升级到 Ubuntu。在过去一年左右的时间里,我实际上已经从 Ubuntu 12 -> Ubuntu 14 -> Ubuntu 16 开始。这导致了未生成云网络文件的问题,因此无法访问我的实例。

无论如何,要使用新的 nvme 命名约定将 Ubuntu 16.04 PV 实例迁移到 HVM 实例,请执行以下操作:

先决条件摘要:

  1. 在开始之前,请确保在您的 PV 实例上安装以下内容:

    $ sudo apt-get install grub-pc grub-pc-bin grub-legacy-ec2 grub-gfxpayload-lists
    $ sudo apt-get install linux-aws
    
    Run Code Online (Sandbox Code Playgroud)
  2. 停止 PV 实例并创建其根卷的快照将此快照恢复为源相同可用区上的新 EBS 卷(在创建快照后立即启动 PV 实例)
  3. 启动一个新的 C5 HVM 实例(目标),在源实例的同一可用区上选择 Ubuntu Server 16.04 LTS (HVM)(保持这个新实例 EBS 根卷大小为 8GB,因为这个根卷只会被临时使用)
  4. 实例启动后,您在步骤 1 中恢复的卷(即 PV 实例的根卷)附加/dev/sdf(在 Ubuntu 系统上,名称将为nvme1n1)。
  5. 创建一个新的(空白)EBS 卷(与您的“源”PV 根卷大小相同)并附加到 HVM 实例/dev/sdg(在 Ubuntu 系统上,名称将为nvme2n1

移民:

登录到您的实例后,用于sudo su以 root 用户身份执行所有命令。

  1. 显示您的音量

    # lsblk 
    NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    nvme0n1     259:0    0    8G  0 disk 
    ??nvme0n1p1 259:1    0    8G  0 part /
    nvme1n1     259:2    0  100G  0 disk 
    nvme2n1     259:3    0  100G  0 disk 
    
    Run Code Online (Sandbox Code Playgroud)

    nvme0n1是您刚刚创建的 HVM 根(这次只是为了引导) nvme1n1是恢复的 PV 根(将被转换为 HVM) nvme2n1是空白卷(将从 PV 根接收转换为nvme1n1

  2. nvme2n1nvme2n1p1将被创建)上创建一个新分区

    # parted /dev/nvme2n1 --script 'mklabel msdos mkpart primary 1M -1s print quit'
    # partprobe /dev/nvme2n1
    # udevadm settle
    
    Run Code Online (Sandbox Code Playgroud)
  3. 检查“源”卷并最小化原始文件系统的大小以加快进程。我们不想在下一步中复制可用磁盘空间。

    # e2fsck -f /dev/nvme1n1 ; resize2fs -M /dev/nvme1n1
    
    Run Code Online (Sandbox Code Playgroud)
  4. 将“源”复制到“目标”卷

    # dd if=/dev/nvme1n1 of=/dev/nvme2n1p1 bs=$(blockdev --getbsz /dev/nvme1n1) conv=sparse count=$(dumpe2fs /dev/nvme1n1 | grep "Block count:" | cut -d : -f2 | tr -d "\\ ")
    
    Run Code Online (Sandbox Code Playgroud)
  5. 将“目标”音量调整为最大:

    # e2fsck -f /dev/nvme2n1p1 && resize2fs /dev/nvme2n1p1
    
    Run Code Online (Sandbox Code Playgroud)
  6. 准备目标卷:

    # mount /dev/nvme2n1p1 /mnt/ && mount -o bind /dev/ /mnt/dev && mount -o bind /sys /mnt/sys && mount -o bind /proc /mnt/proc
    
    Run Code Online (Sandbox Code Playgroud)
  7. chroot 到新卷

    # chroot /mnt/
    
    Run Code Online (Sandbox Code Playgroud)
  8. 在 chroot 卷上重新安装 grub

    # grub-install --recheck /dev/nvme2n1
    # update-grub
    
    Run Code Online (Sandbox Code Playgroud)

    退出 chroot

    # exit
    
    Run Code Online (Sandbox Code Playgroud)

    关闭实例

    # shutdown -h now
    
    Run Code Online (Sandbox Code Playgroud)
  9. 转换后,您现在需要执行以下操作:

    分离您之前在 HVM 实例上的 3 个卷。将您在/dev/sda1控制台上创建(空白)的最后一个卷(它之前附加为/dev/nvme2n1)附加到 HVM 实例上。启动 HVM 实例。

新的 HVM 实例现在应该成功启动,并且将是旧源 PV 实例的精确副本(如果您使用了正确的源卷)。一旦确认一切正常,就可以终止源实例。


更新网络配置(可选)

现在,上述步骤适用于这里的大多数人。但是,我的实例状态仍未达到。原因是因为我在我的实例上升级了 Ubuntu,而不是从一个新的镜像开始。这使得eth0配置被激活,一个没有50-cloud-init.cfg配置文件。

如果您已经有了该文件/etc/network/interfaces.d/50-cloud-init.cfg,那么您可以继续更新该文件,而不是创建一个新文件。还假设所有命令都通过sudo su.

  1. 关闭实例,分离卷,然后输入与之前相同的配置。将 8GB 卷附加为/dev/sda1/,并将最终目标卷附加为/dev/sdf/. 启动实例并登录。

  2. Mount /dev/sdf,现在应该nvme1n1p1通过执行以下操作:

    # mount /dev/nvme1n1p1 /mnt/ && mount -o bind /dev/ /mnt/dev && mount -o bind /sys /mnt/sys && mount -o bind /proc /mnt/proc
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建或更新文件:

    /etc/network/interfaces.d/50-cloud-init.cfg
    
    Run Code Online (Sandbox Code Playgroud)

    具有以下内容:

    # This file is generated from information provided by
    # the datasource.  Changes to it will not persist across an instance.
    # To disable cloud-init's network configuration capabilities, write a file
    # /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
    # network: {config: disabled}
    auto lo
    iface lo inet loopback
    
    auto ens5
    iface ens5 inet dhcp
    
    Run Code Online (Sandbox Code Playgroud)
  4. 退出chrootexit),关闭实例(shutdown -h now)。

  5. 按照之前的第 9 步操作!

你应该完成!