最近负责的一个组件需要针对 Ubuntu 系统做兼容性适配,由于组件运行时会修改系统配置并写入大量文件,有必要使用虚拟机来开发测试。但通常开发使用的 Linux 发行版都是 RedHat 系的,找遍公司也没有能直接用的 Ubuntu 虚拟机镜像,最后自己手搓了一个,过程记录如下。
下载所需版本的 cloud image
首先需要确定所使用的 Ubuntu 版本,然后从官方镜像列表中下载相应的云主机镜像,云主机镜像预装了 cloud-init,可以更方便地运行在 openstack 等云平台中。
在镜像列表页面,需要根据发布频率(如 Release、Daily builds)、镜像大小(完整包和 Minimal)以及 Ubuntu 版本选择合适的镜像,在镜像下载页面有许多不同类型的文件,如校验和文件、manifest 以及不同架构的镜像,我们只需要文件后缀为 .img
的 QEMU qcow2 镜像。``
本示例将选择 X86 架构的 20.04-lts
版本,最终所下载的镜像为 ubuntu-20.04-server-cloudimg-amd64.img。
使用 wget
命令将其下载到本地:
|
|
cloud-init
cloud-init 是用于跨平台初始化云主机实例的行业标准方法。它支持所有的主要公有云供应商、私有云配置系统和裸机安装。
有了 cloud-init,只需要提供系统镜像和规定的元数据(以及可选的用户数据和供应商数据)即可初始化一个云主机实例,在启动过程中,cloud-init 将读取所提供的元数据,识别它所运行的平台并完成相应的系统初始化步骤。初始化过程涉及设置网络和存储设备,配置 SSH 访问密钥及其他系统配置,还可将可选的用户或供应商数据传递给实例。
cloud-init 大幅简化了云主机的复杂配置过程,只需要编写一个统一的配置文件,就可以在不同的云平台创建出相同规格的主机实例。
配置模板镜像
下载的初始镜像并不能直接上传到云主机平台使用,否则创建的虚拟机无法通过 SSH 登录,会提示如下类似错误(SSH 用户只能使用镜像默认的 ubuntu
):
|
|
下面需要使用一些虚拟机管理工具,基于模板镜像运行一个虚拟机,在虚拟机中完成所需配置,最终将模板镜像修改至可直接使用的镜像。
安装虚拟机管理工具
以下安装命令基于 CentOS
,其他发行版本也可通过对应的包管理系统下载所需工具:
|
|
创建模板镜像并配置磁盘大小
基于初始镜像创建模板镜像,并命名为 root-disk.qcow2
:
|
|
根据需要,设置基于该模板镜像所创建的虚拟机磁盘大小,示例设置为 50G:
|
|
准备 cloud-init 配置
假设将使用的默认主机名和密码如下:
|
|
用于测试开发的虚拟机,可配置为直接使用 root
用户并以密码登录,但切勿用于生产用途。生产环境镜像需使用普通用户加 sudo
权限以及 public key
等更安全的登录途径。
接下来创建一个 cloud-init 的配置文件,并在其中定义主机名和密码等:
|
|
如果还需要对主机做更多配置,可参考 cloud-init
的文档示例:
Cloud config examples - cloud-init 21.4 documentation
然后使用 cloud-localds
基于配置文件创建 ISO 镜像:
|
|
基于模板镜像以及配置镜像安装虚拟机:
|
|
命令运行成功后会进入一个新的终端会话,在自动执行一系列的初始化操作之后,将可以用上文设置的 default_user
的用户名和密码登录所创建的虚拟机。
初始化虚拟机
进入运行中的虚拟机后,我们希望进行一些与登录相关的初始化配置。以下操作以 Ubuntu 20.04 为例,其他版本可能有所区别。
允许以 root
用户登录
Ubuntu 20.04 默认的 SSH 配置不允许以 root 用户登录,我们需要修改 /etc/ssh/sshd_config
文件将 PermitRootLogin prohibit-password
配置更改为 PermitRootLogin yes
:
|
|
重启 SSH 服务:
|
|
设置 root
用户密码
默认情况下 Ubuntu 20.04 未设置 root 用户密码,因此无法使用 root 用户登录系统,需要通过 passwd
命令初始化 root 用户的密码:
|
|
密码设置完毕后,我们可以输入 ctrl
+ ]
退出虚拟机会话,并通过 virsh
命令获取运行中虚拟机的 IP 地址,测试是否能通过 root
用户 SSH 登录虚拟机:
|
|
登陆成功后,可以在虚拟机中执行其他初始化操作,如安装基础依赖、配置镜像源等。
最后在虚拟机中执行关闭命令退出会话:
|
|
清理与压缩镜像
在 virt-install
执行过程中,虚拟机会将虚拟网卡的 Mac 地址记录到文件系统中,但每一次基于镜像启动虚拟机都会生成一个新的 Mac 地址,因此需要将镜像中已经写入配置文件的 Mac 地址清除掉。
除了进入虚拟机手动清除,还可以使用上文已安装的专门工具来清理:
|
|
该命令还将执行清除操作历史等一系列操作。
接着在 libvirt 中注销已创建的虚拟机实例:
|
|
此时对虚拟机所做的更改都已写入到 root-disk.qcow2
模板镜像中,将其上传到云主机平台的镜像服务器,就可以基于已写入的配置重复创建新的虚拟机实例。
如果此时镜像体积较大,可执行以下命令可对镜像体积进行压缩,并使用压缩得到的 ubuntu-20.04.qcow2
镜像:
|
|
在本示例中,镜像大小从 7 个多 G 压缩到了 500M 左右,效果显著。