用 Ubuntu Cloud Images 制作自己的云镜像(配置 cloud-init 的 NoCloud 数据源)
条评论还是之前写过的,云厂商提供的系统镜像不好使的问题。之前写过《使用 iPXE 和 netboot.xyz 重装 VPS 系统》,但是,由于各种原因(如系统内存不足、国内网络不稳定等),其适用性受到了限制。这次改用了 Ubuntu Cloud Images,可以直接用 dd 命令覆盖系统盘,然后重装系统。
介绍 cloud-init 和 Ubuntu Cloud Images
cloud-init 是一个初始化云镜像的工具,同时也是一个自动化的配置工具。
Ubuntu Cloud Images 是由 Ubuntu 官方提供的用于在公有云上运行的系统镜像。它在首次启动时会运行 cloud-init 初始化系统。
如何制作自己的云镜像
系统准备
要制作自己的云镜像,需要准备相应的环境。本文假设你使用最新的 Ubuntu 20.04 LTS 系统,已包含“kpartx”和“losetup”工具。
此外,你还需要“qemu-img”,可以通过 sudo apt install qemu-utils
安装需要的软件包。
为了将镜像传输到要安装的云服务器,你还需要配置 web 服务器。配置方法不再赘述。
要安装的机器需要可以启动救援模式,并且救援模式需要可以联网(至少需要可以连接到镜像所在机器)。
下载 Ubuntu Cloud Images
打开 https://cloud-images.ubuntu.com/,选择要安装的 Ubuntu 版本(如“focal”),点击“current”选择最新构建,然后根据架构选择要下载的文件。例如,最常见的 amd64 架构请下载“focal-server-cloudimg-amd64.img”。
转换为 raw 文件
下载到的镜像是 qcow2 格式的,需要转换为 raw 格式,才能被挂载、修改和使用。运行下面的命令转换为 raw 格式。
1 | qemu-img convert -f qcow2 -O raw focal-server-cloudimg-amd64.img focal-server-cloudimg-amd64.raw |
挂载 raw 文件
需要把 raw 文件映射为 loop 设备,然后挂载到系统上。
请参阅《如何挂载.img格式的镜像》,完成挂载。
需要注意的是,文中的“.img格式的镜像”,是指我们转换出来的 raw 文件,而不是下载到的后缀为“.img”的 qcow2 文件。
另外,Ubuntu Cloud Images 的系统分区是分区 1,其他系统可能略有不同。
举例来说,如果 sudo losetup -f
查到的空闲 loop 设备为 /dev/loop9,那么就执行以下命令:
1 | sudo losetup /dev/loop9 focal-server-cloudimg-amd64.raw |
如果你想安装其他系统镜像,可以用 sudo fdisk -l /dev/loop9
查看分区信息。
修改 cloud-init 配置
用 cd /mnt/etc/cloud/cloud.cfg.d
切换到 cloud.cfg.d 目录,sudo nano 99-fake_cloud.cfg
创建文件 99-fake_cloud.cfg,内容如下:
1 | # CLOUD_IMG: This file was created/modified by the Cloud Image build process |
修改完成后保存,用以下命令取消挂载:
1 | sudo umount /mnt |
其中把“/mnt”修改为你的实际挂载目录,把“/dev/loop9”修改为你的实际 loop 设备。
安装 Ubuntu
首先假定你已经把修改过的系统镜像放到 web 服务器上,镜像 url 为“http://web/image.raw”。在要安装的机器上进入救援模式,找到系统启动盘(如 /dev/sda,也可能为 /dev/vda、/dev/nvme0n1 等),然后执行以下命令:
1 | wget http://web/image.raw | sudo dd of=/dev/sda |
请注意硬盘需要有足够空间。Ubuntu Cloud Images 所需空间大约是 2.2G。完成后重启机器,等待初始化完成即可。
示例配置默认禁用密码登录,需要使用 ssh 密钥。首次登录会要求修改密码。
完成后,你就可以享受未经云厂商加料的原汁原味的系统了。
定制镜像
如果你想定制镜像(如安装某些软件、配置网络等),可以参考 cloud-init 的文档,包括配置示例、模块等,修改配置文件。这样,系统初始化时会进行对应配置,减少重复配置环境的工作量。