20分钟

任务 3 制作 Linux 镜像

任务目的

根据已经安装完成的 Linux 系统制作可以被腾讯云服务器导入的镜像文件。腾讯云对被导入的镜像文件有一系列相应的要求,根据已有系统制作镜像需要根据不同的系统有针对性的进行一系列相关的配置,最终制作完成的镜像文件才是能被成功导入的。

任务步骤

1.检查 Linux 系统 OS 分区和启动方式

开启 Linux 虚拟机并以 root 身份登录 Linux 系统,输入以下命令查询 OS 分区格式。

sudo parted -l /dev/sda | grep 'Partition Table'

若返回结果为 msdos,即表示为 MBR 分区,可以继续操作。若返回结果为 gpt,即表示为 GPT 分区,目前服务迁移不支持 GPT 分区。若要继续需要把 GPT 分区变为 MBR 分区。把 GPT 分区变为 MBR 可以使用parted命令,或者使用gdisk命令,在转换磁盘分区格式前需要备份系统文件,可以使用dd命令复制磁盘文件。

执行以下命令,检查操作系统是否以 EFI 方式启动。

sudo ls /sys/firmware/efi

若存在文件,则表示当前操作系统以 EFI 方式启动,不支持进行迁移。若不存在文件,则可以进行下一步。

检查OS分区和启动方式

2.检查系统关键文件

为确保生成的镜像文件可用,需要先确保系统关键文件状态正常。由于这是正常安装的新系统,这一步可以省略。

需检查的系统关键文件包括且不限于以下文件:

/etc/grub2.cfg: kernel 参数里推荐使用 uuid 挂载 root,其它方式(如 root=/dev/sda)可能导致系统无法启动。

/etc/fstab:请勿挂载其它硬盘,迁移后可能会由于磁盘缺失导致系统无法启动。

/etc/shadow:权限正常,可以读写。

执行以下命令查看“grub2.cfg”文件有关“root”的内容。

cat /etc/grub2.cfg | grep root
查看grub2.cfg

执行以下命令查看“fstab”文件。

cat /etc/fstab
查看fstab

执行以下命令检测“shadow”文件是否存在以及读写权限。

#检测文件长度
test -s /etc/shadow && echo "yes"
#检测文件读权限
test -r /etc/shadow && echo "yes"
#检测文件写权限
test -w /etc/shadow && echo "yes"
查看shadow

3.卸载会引起冲突的软件

卸载会产生冲突的驱动和软件(包括 VMware tools,Xen tools,Virtualbox GuestAdditions 以及一些自带底层驱动的软件)。如 VMware tools,如果之前已经安装则需要卸载,卸载 VMWare Tools 的方法如下图。

卸载VMware tools

4.Linux 系统检查 Virtio 驱动

使用以下命令检查内核是否支持 Virtio 驱动。uname -r 为当前系统内核版本。

grep -i virtio /boot/config-$(uname -r)
检查Linux内核

如上图所示:当前内核包含了 virtio_blk 和 virtio_net 驱动,并且是以模块形式编译的(CONFIG_VIRTIO_BLK=m,表示编译成为内核模块,等于 y 表示编译进内核)。

  • 如果返回结果中 CONFIG_VIRTIO_BLK 参数和 CONFIG_VIRTIO_NET 参数取值为 m,表明该操作系统支持但未安装 Virtio 驱动。
  • 如果在返回结果中 CONFIG_VIRTIO_BLK 参数和 CONFIG_VIRTIO_NET 参数取值为 y,表示该操作系统包含了 Virtio 驱动。
  • 如果在返回结果中没有 CONFIG_VIRTIO_BLK 参数和 CONFIG_VIRTIO_NET 参数的信息,表示该操作系统不支持导入腾讯云。

上图的返回结果中 CONFIG_VIRTIO_BLK 参数和 CONFIG_VIRTIO_NET 参数取值为 m,需要手动安装 Virtio 驱动。

使用以下命令检查临时文件系统是否包含 Virtio 驱动。

lsinitrd /boot/initramfs-$(uname -r).img | grep virtio
检查Virtio驱动(失败)

命令无返回结果表明临时文件系统中不含 Virtio 驱动,需要重新配置临时文件系统。先执行以下命令备份关键文件。

cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak

使用以下命令重新配置临时文件系统。

mkinitrd -f --with=virtio_blk --with=virtio_pci /boot/initramfs-$(uname -r).img $(uname -r)

再次检查临时文件系统是否包含 Virtio 驱动,出现下图结果则 Virtio 驱动配置成功。

检查Virtio驱动(成功)

5.安装 cloud-init

安装 cloud-init 首先要确保虚拟机网络连接畅通。执行以下命令查看网络连接状态。

ip addr
查看网络连接

执行以下命令修改网卡配置。

vi /etc/sysconfig/network-scripts/ifcfg-ens33

在 vi 编辑界面按i进入插入模式,将 ONBOOT 后面的 no 改成 yes,设置网卡自动启动,按Esc键退出插入模式,再输入“:wq”保存并退出。

修改网卡配置

执行以下命令重启网卡。

service network restart
重启网卡

网络连接畅通,开始配置 yum 源,这里使用腾讯软件源。

curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo

yum 源安装完成后,安装 wget。

yum install wget -y

接下来开始安装 cloud-init,有两种安装方式。

方式一:使用软件源上的 cloud-init 包方式。

  • 执行以下命令安装 cloud-init 包。yum install cloud-init -y
  • 执行以下命令修改 cloud-init 配置文件。
wget -O /etc/cloud/cloud.cfg http://cloudinit-1251740579.cosgz.myqcloud.com/centos-cloud.cfg?_ga=1.215849695.911154906.1570865323

方式二:手工下载 cloud-init 源码包方式。(方式一使用软件源安装不可用时选择这种方式,如果 yum 安装成功,可以直接跳至下一步(本任务第6步)

在正常安装的情况下,cloud-init-17.1 版本与腾讯云的兼容性最佳,可以保证使用该镜像创建的云服务器的所有配置项都可以正常初始化。

  • 执行以下命令,下载 cloud-init 源码包。
wget https://launchpad.net/cloud-init/trunk/17.1/+download/cloud-init-17.1.tar.gz
安装cloud-init
  • 执行以下命令,解压并进入文件目录。
tar -zxvf cloud-init-17.1.tar.gz
cd cloud-init-17.1
  • 接下来需要安装 Python-pip,使用 yum 方式安装。如果没有配置 epel 镜像源,则需要配置 epel 镜像源。前往腾讯软件源,找到 epel,点击查看进入epel 帮助文档
epel镜像源
  • 根据文档执行命令安装 epel。
epel安装方法
  • 执行下列命令安装 Python-pip
yum install python-pip -y
  • 执行以下命令,安装依赖包。
pip install -r requirements.txt

结果如下图显示。

安装依赖结果
  • 执行以下命令安装 cloud-utils 组件。
yum install cloud-utils-growpart -y
  • 执行以下命令,安装 cloud-init。
python setup.py build
python setup.py install --init-system system

结果如下图,则安装成功。

安装cloud-init结果
  • 执行以下命令修改 cloud-init 配置文件。
wget -O /etc/cloud/cloud.cfg http://cloudinit-1251783334.cosgz.myqcloud.com/centos-cloud.cfg?_ga=1.212713436.911154906.1570865323
修改 cloud-init 配置文件
  • 执行以下命令添加 syslog 用户
useradd syslog
  • 设置 cloud-init 服务开机自启动
systemctl enable cloud-init-local.service
systemctl start cloud-init-local.service
systemctl enable cloud-init.service
systemctl start cloud-init.service
systemctl enable cloud-config.service
systemctl start cloud-config.service
systemctl enable cloud-final.service
systemctl start cloud-final.service
systemctl status cloud-init-local.service
systemctl status cloud-init.service
systemctl status cloud-config.service
systemctl status cloud-final.service
  • 将 /lib/systemd/system/cloud-init-local.service 文件替换为如下内容:
[Unit]
Description=Initial cloud-init job (pre-networking)
Wants=network-pre.target
After=systemd-remount-fs.service
Before=NetworkManager.service
Before=network-pre.target
Before=shutdown.target
Conflicts=shutdown.target
RequiresMountsFor=/var/lib/cloud
[Service]
Type=oneshot
ExecStart=/usr/bin/cloud-init init --local
ExecStart=/bin/touch /run/cloud-init/network-config-ready
RemainAfterExit=yes
TimeoutSec=0
# Output needs to appear in instance console output
StandardOutput=journal+console
[Install]
WantedBy=cloud-init.target
  • 将 /lib/systemd/system/cloud-init.service 文件替换为以下内容:
[Unit]
Description=Initial cloud-init job (metadata service crawler)
Wants=cloud-init-local.service
Wants=sshd-keygen.service
Wants=sshd.service
After=cloud-init-local.service
After=systemd-networkd-wait-online.service
After=networking.service
After=systemd-hostnamed.service
Before=network-online.target
Before=sshd-keygen.service
Before=sshd.service
Before=systemd-user-sessions.service
Conflicts=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/bin/cloud-init init
RemainAfterExit=yes
TimeoutSec=0
# Output needs to appear in instance console output
StandardOutput=journal+console
[Install]
WantedBy=cloud-init.target

6.检查 cloud-init 相关配置是否成功

执行以下命令,检查 cloud-init 相关配置是否成功。

以下操作执行完成后,请勿重启服务器,否则需重新执行下以下操作。

#启动cloud-init
cloud-init init --local
#删除程序执行时产生的文件
rm -rf /var/lib/cloud

7.导出镜像

导出的镜像中至少需要包含根分区以及 mbr。如果导出的镜像缺少 mbr,将无法启动。

在当前操作系统中,如果/boot/home为独立分区,导出的镜像还需要包含这两个独立分区。

执行lsblk命令查看分区,/boot为独立分区需要导出,此外还需要存在于磁盘/dev/sdambr,选择导出/dev/sda

系统分区

方式一:使用 vmdk 文件。

使用该方式导出镜像的前提是在安装 Linux 系统时选择了【将虚拟磁盘存储为单个文件】,若是选择了【将虚拟磁盘拆分为多个文件】请使用方式二导出镜像。

输入命令poweroff关闭虚拟机。打开虚拟机所在文件夹,找到 后缀为“.vmdk” 文件,此即为需要导出的镜像文件。

CentOS vmdk格式镜像文件

方式二:使用命令导出。

使用命令导出需要挂载另一虚拟磁盘。

关闭虚拟机,来到 VMware player 软件主界面。选中 Linux 虚拟机,点击右下角的【编辑虚拟机设置】。

VMware虚拟机列表

点击下方的【添加】按钮,在弹出框选择【硬盘】。选择磁盘界面选择【创建新虚拟磁盘】,指定磁盘容量为 10GB,选择【将虚拟磁盘存储为单个文件】。其它设置默认。

添加硬盘

添加磁盘后开启虚拟机,以 root 用户登录,执行以下命令。

fdisk -l
磁盘分区

找到添加的磁盘/dev/sdb,执行下列命令对磁盘分区。

fdisk /dev/sdb

首先输入“n”添加分区,然后输入“p”主分区,其它按回车健选择默认值。

添加分区

分区完成后输入“w”保存设置。

保存分区设置

执行以下命令将分区格式化为 ext4。

mkfs.ext4 /dev/sdb1

执行以下命令将磁盘挂载到/mydata文件夹。

#创建文件夹
mkdir /mydata
#将磁盘挂载到文件夹
mount /dev/sdb1 /mydata

由于虚拟机重启,故需要执行下列命令。

cloud-init init --local
rm -rf /var/lib/cloud

执行以下命令,将/dev/sda导出。/mydata/test.qcow2是存放镜像文件的地址。

#安装qemu-img
yum install qemu-img -y
qemu-img convert -f raw -O qcow2 /dev/sda /mydata/centos7.qcow2

要将制作完成的镜像移动至本机,需要使用 FTP 工具。此处选择使用FileZilla

下载软件安装包,找到安装包并双击安装软件。选择默认配置,安装完成后双击图标打开软件。

FileZilla

使用 FTP 需要填入主机地址,回到 Linux 虚拟机,执行以下命令。

ifconfig

“192.168.19.130”即为主机地址。不同虚拟机的主机地址可能不相同。

主机地址

回到 FileZilla 软件主界面,最小化安装 CentOS 时 vsftpd 没有安装,可以采用 SFTP 的方式连接主机。点击左上角的图标添加站点。

添加站点按钮

【协议】选择【SFTP - SSH File Transfer Protocol】,【主机】填入查询到的主机地址,【用户】和【密码】填入 Linux 系统的用户名和密码。点击【连接】按钮。

添加站点

连接到虚拟机后,软件右侧显示 Linux 虚拟机的文件系统,找到位于/mydata 文件夹的镜像文件,选中镜像文件后右键点击【下载】,将镜像文件下载到本机。

下载镜像文件

至此,Linux 镜像制作完成。