8.3 制作 OpenStack 镜像

image0


这里仅以Ubuntu系统为例,其他系统也是类似,部分不同的地方会给出标注。

8.3.1 准备工作


8.3.1.1 下载iso文件

下载链接

wget http://releases.ubuntu.com/16.04.3/ubuntu-16.04.3-server-amd64.iso

8.3.1.2 安装原始系统

步骤主要有两点: 1. raw系统盘 2. xml文件

raw系统盘 既然是安装系统,那就必须给系统一个地方放置系统,对于虚拟机来说,其系统盘在宿主机上就是一个文件。我们要先创建这个文件,然后在xml里指定,这就是它的系统盘,把系统安装在这里就行了。

qemu-img create -f raw ubuntu-16.04.raw 50G

这里要说明一下,这和 CentOS 不一样, CentOS 可以直接使用 qcow2 文件,而 Ubuntu 则不行。因为qcow2文件大小是根据实际占用的大小决定的,一个空文件 只有 197kb 大小 ,Ubuntu 则会认为给定的磁盘空间过小,无法安装。

关于几种镜像格式 可以参考这里:转换镜像格式

xml文件

安装原始系统的 xml 文件和由镜像创建虚拟机的大不相同。亲测可用如下,只需要修改ubuntu-16.04.rawubuntu-16.04.3-server-amd64.iso 对应路经即可。

题外话,如果嫌弃xml太麻烦,而且看不懂。可以直接用命令启动,不过这个我试过是使用vnc的,可能要手动改下为spice。如果是使用 virt-install 的,后面查看 vnc 端口的可以使用 virsh vncdisplay [domain]

virt-install  --name ubuntu-16.04 \
--ram 4096 \
--vcpus 4 \
--cdrom=ubuntu-16.04.3-server-amd64.iso \
--disk ubuntu-16.04.qcow2,format=qcow2 \
--graphics vnc,listen=0.0.0.0 \
--noautoconsole \
--os-type=linux \
--os-variant=ubuntuquantal \
--check all=off

ubuntu.xml 文件内容如下:

<domain type='kvm'>
   <name>ubuntu-iso</name>
   <memory>4194304</memory>
   <currentMemory>4194304</currentMemory>
   <vcpu>2</vcpu>
   <os>
     <type arch='x86_64' machine='pc'>hvm</type>
     <boot dev='cdrom'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='localtime'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
     <driver name='qemu' type='raw'/>
      <source file='/path/to/ubuntu-16.04.raw'/>
      <target dev='hda' bus='virtio'/>
    </disk>
    <disk type='file' device='cdrom'>
      <source file='/path/to/ubuntu-16.04.3-server-amd64.iso'/>
      <target dev='hdb' bus='ide'/>
    </disk>
    <graphics type='spice' autoport='yes' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
   </graphics>
 </devices>
</domain>

8.3.1.3 启动虚拟机

virsh define ubuntu.xml
virsh start ubuntu-iso

# 查看 vnc spice 端口,比如是5909
virsh dumpxml ubuntu-iso|grep spice

8.3.1.4 安装系统

安装系统需要可视化图形界面,而我们通常都是使用ssh连接到服务器端,这是没有可视化图形界面的。

这时候就要在我们在windows上安装一个 vnc 客户端 这里我使用的是 spice  virt-viewer。 官网下载地址:https://virt-manager.org/download/

下载速度十分缓慢,可能需要半个多小时,我已经下载好,上传到百度云盘,需要自取。

image1

安装好后,可以尝试连接虚拟机。 如果连接失败,可以自己的排查下原因

1. 宿主机的iptables,firewall
2. 端口是否开放,telnet 一下

image2

然后根据提示安装系统(注意要先新建一个用户,设置该用户密码,后续要登陆虚拟机使用)。安装完成后,退出spice。

最后关闭虚拟机。

virsh shutdown/destroy ubuntu-iso

这样我们所安装的系统就已经存放在 ubuntu-16.04.raw 这个文件里。

8.3.2 自定义镜像内容

8.3.2.1 转换镜像格式

还记得我们之前的镜像是 raw 格式的吧? raw 文件,有一特点是你创建多大的盘,这个文件就有多大,而不是按需分配的。我们之前创建的是 50G,这么大的文件,是无法上传到glance的,我需要将其转换成 qcow2 文件,转换之后,原先的 50G 就变成了 1G多,等到OpenStack创建的时候,它自会转成raw的格式。

qemu-img convert -f raw -O qcow2 ubuntu.raw ubuntu-16.04.qcow2

8.3.2.2 启动虚拟机

上面得到的qcow2文件,这时候就要用起来了。用这个镜像文件启动一个虚拟机。

ubuntu-16.04.xml 文件如下:

<domain type='kvm' id='95'>
  <name>ubuntu-16.04</name>
  <memory unit='KiB'>4194304</memory>
  <currentMemory unit='KiB'>4194304</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <cpu mode='custom' match='exact'>
    <model fallback='allow'>SandyBridge</model>
    <feature policy='require' name='vmx'/>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='/path/to/ ubuntu-16.04.qcow2'/>
      <backingStore/>
      <target dev='hda' bus='virtio'/>
    </disk>

    <controller type='pci' index='0' model='pci-root'>
      <alias name='pci.0'/>
    </controller>
    <controller type='ide' index='0'>
      <alias name='ide'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <controller type='virtio-serial' index='0'>
      <alias name='virtio-serial0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </controller>
    <interface type='bridge'>
      <source bridge='br0'/>
      <model type='virtio'/>
    </interface>
    <interface type='bridge'>
      <source bridge='br-test'/>
      <model type='virtio'/>
    </interface>
    <console type='pty' tty='/dev/pts/5'>
      <source path='/dev/pts/5'/>
      <target type='virtio' port='0'/>
      <alias name='console0'/>
    </console>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='spice' port='5900' autoport='yes' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <sound model='ich6'>
      <alias name='sound0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </sound>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
      <alias name='video0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <alias name='balloon0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
    </memballoon>
  </devices>
</domain>

启动虚拟机

virsh define ubuntu-16.04.xml
virsh start ubuntu-16.04
virsh console ubuntu-16.04

8.3.2.3 设置ip地址

由于我们后面安装东西需要联网。所以我们这边先设置下ip地址,保证虚拟机可以上网。

为了方便和不留下历史ip数据,我推荐使用命令来临时配置ip和网关,而不推荐使用配置文件。

# 配置ip
ifconfig ens3 172.20.20.122 up

# 配置网关,这个网关会做snat转发,所以可以上网
route add default gw 172.20.20.200 ens3

检查并设置一下 dns , 不然会装不了包。

ubuntu : /etc/resolvconf/resolv.conf.d/base

centos : cat /etc/resolv.conf

nameserver 8.8.8.8
nameserver 114.114.114.114

8.3.2.4 ssh安装并设置

纯净的系统,是没有 openssh 的,我们需要手动安装

sudo apt-get update
sudo apt-get install openssh-server

查看是否允许密码登陆:
vim /etc/ssh/sshd_config
PermitRootLogin prohibit-password  -> PermitRootLogin yes

查看sshd是否启动
ps -ef|grep sshd  如果没启动:sudo service ssh start

ssh目录

mkdir -p /root/.ssh
chmod 700 /root/.ssh

8.3.2.5 安装cloud-init

安装软件包

sudo apt-get install cloud-init -y
sudo apt-get install  acpid -y

加入开机自启

ubuntu的命令如下

update-rc.d acpid defaults

# 若要关闭开机自启:
sudo update-rc.d -f acpid remove

centos命令如下

chkconfig acpid on

配置cloud-init: /etc/cloud/cloud.cfg

# 允许root登陆
disable_root: false

# 开启ssh
ssh_pwauth:   1

如果有自定义的模块,可以放在 /usr/lib/python2.7/site-packages/cloudinit/config 目录下

然后在cloud-init 的配置文件里相应的配置上这个模块即可。

就比如,我写了一个自定义的模块:cc_ws_virt_network_dep.py

那我就在 /etc/cloud/cloud.cfgcloud_final_modules 阶段配置中写入

- ws_virt_network_dep

8.3.2.6 实现系统盘自动扩容

原文:OpenStack CentOS 镜像根分区自动扩展

  • centos5:太老不支持

  • centos6:CentOS 6 要实现分区自动扩展,要安装以下三个包,通过yum安装可能安装不了,可以通过下载离线rpm包来安装:cloud-utils-growpartdracut-modules-growroot

    yum install cloud-init cloud-utils-growpart dracut-modules-growroot
    

    生新生成 initramfs

    dracut -f
    
  • centos7:CentOS 7 使用的是 3.10 ( > 3.8 ) 的内核,所以并不需要 dracut-modules-growroot 包 ( 源里面也并没有这个包 )。 只安装以下两个包就可以了。

    yum install cloud-init cloud-utils-growpart
    

8.3.2.7 开启console

原文参考:CentOS 配置 console登录

如果确认虚拟机grub已经设置了,就是xml的问题。将virtio 改成 serial

<console type='pty'>
  <target type='serial' port='0'/>
</console>

Ubuntu16.04

vim /etc/default/grub
# >>> GRUB_CMDLINE_LINUX="console=ttyS0"

# 重新生成配置
grub-mkconfig -o /boot/grub/grub.cfg

CentOS 6.X

1. 添加ttyS0的许可,允许root登录
# echo "ttyS0" >> /etc/securetty

2. 修改 /etc/grub.conf 文件
在/etc/grub.conf文件中kernel行末尾追加console=ttyS0

3. 修改/etc/inittab文件(可省略)
在/etc/inittab中加入
S0:12345:respawn:/sbin/agetty ttyS0 115200

4. 重启
# reboot

CentOS 7.X

1. 编辑文件/etc/sysconfig/grub,或者/etc/default/grub 文件
在GRUB_CMD_LINELINUX行末尾添加console=ttyS0,类似以下这样:

GRUB_TIMEOUT=5
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap crashkernel=auto rhgb quiet console=ttyS0"
GRUB_DISABLE_RECOVERY="true"

2. 并以root权限运行以下命令:
stty -F /dev/ttyS0 speed 9600
grub2-mkconfig -o /boot/grub2/grub.cfg 或者 grub-mkconfig -o /boot/grub/grub.cfg
systemctl start getty@ttyS0

完成后验证。

8.3.2.8 其他自定义的选项

CentOS6 创建快照前需要先删除75-persistent-net-generator.rules 文件,不然网卡会往上叠加。

可以使用如下方法解决

ln -s /dev/null /etc/udev/rules.d/70-persistent-net.rules

关闭防火墙

# 先安装工具
sudo apt-get install selinux-utils

# 确认为disabled
getenforce

service firewalld status
service firewalld stop
sudo update-rc.d -f firewalld remove

若有其他要修改的地方,可自行修改。然后关机虚拟机

shutdown -h now

8.3.3 修改镜像的文件

通过 guestfish 工具可以实现不用创建虚拟机就可以修改镜像里的文件内容。

image3

8.3.3 KVM 镜像快照

参考链接:https://www.cnblogs.com/sammyliu/p/4468757.html

$ virsh snapshot-create-as ws_controller01 2.2.7 --disk-only --atomic
$ virsh blockcommit ws_controller01 hda --active --verbose --pivot

image4

image5