OpenStack镜像制作教程

说明:本文档以CentOS6.5为例,讲解如何制作openstack镜像。不同的linux发行版的具体操作不一样,但制作镜像的过程是一样的。

一、准备环境

建议使用一台物理机来配置kvm环境,需要cpu支持intel VT等硬件虚拟化功能。也可以用虚拟机来制作镜像,同样需要开启硬件虚拟化功能。

建议确保网络及软件源配置正确。

判断是否支持虚拟化功能命令:(确认有结果输出。则表示该机器支持或已配置intel VT vmx(intel)或svm(AMD) 支持虚拟技术)

# cat /proc/cpuinfo | grep vmx

1.1安装软件包

# yum install libvirt qemu-kvm virt-install bridge-utils qemu-img virt-manager libguestfs

1.2启动服务

# systemctl start libvirtd

二、制作linux镜像

2.1启动虚机

2.1.1.准备iso镜像文件

/tmp/CentOS-6.5-x86_64-minimal.iso

2.1.2.创建一块虚拟磁盘

# qemu-img create -f raw /tmp/centos-6.5.raw 20G

2.1.3.启动镜像

# virt-install --virt-type kvm --name centos-6.5 --ram 1024 \

--disk /tmp/centos-6.5.raw,format=raw \

扫描二维码关注公众号,回复: 9003304 查看本文章

--network network=default \

--graphics vnc,listen=0.0.0.0 --noautoconsole \

--os-type=linux --os-variant=rhel6 \

--cdrom=/tmp/CentOS-6.5-x86_64-minimal.iso

2.1.4.安装系统

使用vnc登入机器,按照正常的步骤安装系统。分区设置为单个/分区,不设置swap分区。vnc的ip为镜像宿主机的ip,端口可以ps找到,默认是5900。也可以使用virsh从命令行进行安装。部分操作命令如下:

2.1.4.1 查看当前虚机

# virsh list [--all]

2.1.4.2 使用virsh从console登入机器

# virsh console centos-6.5

2.1.4.3 启动虚拟机

# virsh start centos-6.5

2.1.4.4 查看vnc端口

# virsh vncdisplay centos-6.5

系统安装完成之后,重启虚拟机。

2.2安装软件包

如果虚拟机可以联网,则可以不用配置软件源,直接使用默认的即可。

2.2.1.安装基本软件包

安装NetworkManager,用于网卡的自动发现及管理;安装acpid,用于虚拟机的电源管理;安装epel-release,添加epel源

# yum install NetworkManager acpid epel-release

2.2.1 开机启动服务

chkconfig acpid on

chkconfig NetworkManager on

2.2.2.安装cloud-init相关软件包

安装cloud-init,用于注入密码/密钥和主机名;安装qemu-guest-agent,用于在面板更新密码/密钥;安装cloud-utils,用于更改虚拟机根分区大小(可选安装,需要启用epel源)

# yum install cloud-init qemu-guest-agent cloud-utils

开机启动服务(有的linux发行版默认不开机自启这些服务,需要手动设置开机自启)

# chkconfig cloud-init on

# chkconfig cloud-init-local on

# chkconfig cloud-config on

# chkconfig cloud-final on

# chkconfig qemu-ga on

2.2.3.修改代码

UOS3.0默认没有向虚拟机提供userdata,所以在UOS3.0下支持密码注入,需要修改cloud-init的代码实现

代码1:

/usr/lib/python2.7/site-packages/cloudinit/cloud.py

在合适的位置加入如下代码:

    def get_admin_pass(self):
        return self.datasource.get_admin_pass()

代码2:

/usr/lib/python2.7/site-packages/cloudinit/config/cc_set_admin_pass.py (新建文件)

写入如下代码:

from cloudinit import util
from string import letters, digits
# We are removing certain 'painful' letters/numbers
PW_SET = (letters.translate(None, 'loLOI') +
          digits.translate(None, '01'))

def handle(_name, cfg, cloud, log, args):
    errors = []
    try:
        log.debug("Getting admin password from cloud")
        admin_pass = cloud.get_admin_pass()
        log.debug("Changing password for root")
        if admin_pass is None:
            admin_pass = rand_user_password()
        util.subp(['chpasswd'], 'root:%s' % admin_pass)
    except Exception as e:
        errors.append(e)
        util.logexc(log, "Failed to set passwords for root")
    if len(errors):
        log.debug("%s errors occured, re-raising the last one", len(errors))
        raise errors[-1]

def rand_user_password(pwlen=9):
    return util.rand_str(pwlen, select_from=PW_SET)

如果虚拟机默认使用的是Python3,则将上面的代码替换为:

from cloudinit import util
from string import ascii_letters, digits
# We are removing certain 'painful' letters/numbers
PW_SET = (ascii_letters.translate('loLOI') +
          digits.translate('01'))


def handle(_name, cfg, cloud, log, args):
    errors = []
    try:
        log.debug("Getting admin password from cloud")
        admin_pass = cloud.get_admin_pass()
        log.debug("Changing password for root")
        if admin_pass is None:
            admin_pass = rand_user_password()
        util.subp(['chpasswd'], 'root:%s' % admin_pass)
    except Exception as e:
        errors.append(e)
        util.logexc(log, "Failed to set passwords for root")
    if len(errors):
        log.debug("%s errors occured, re-raising the last one", len(errors))
        raise errors[-1]

def rand_user_password(pwlen=9):
    return util.rand_str(pwlen, select_from=PW_SET)

代码3:

/usr/lib/python2.7/site-packages/cloudinit/sources/__init__.py

在合适的位置加入如下代码:

    def get_admin_pass(self):
        if not self.metadata or 'admin_pass' not in self.metadata:
            return None
        return str(self.metadata['admin_pass'])

2.2.4.修改配置文件

cloud-init的配置文件:

/etc/cloud/cloud.cfg 
users:
 - default
disable_root: 0                                       #默认此处为1,需要更改
ssh_pwauth:   0
locale_configfile: /etc/sysconfig/i18n
mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2']
resize_rootfs_tmp: /dev
ssh_deletekeys:   0
ssh_genkeytypes:  ~
syslog_fix_perms: ~
cloud_init_modules:
 - migrator
 - bootcmd
 - write-files
 - growpart
 - resizefs
 - set_hostname
 - set_admin_pass                                     #加入此行,即调用上面加入的代码                         
 - update_hostname
 - update_etc_hosts
 - rsyslog
 - users-groups
 - ssh
cloud_config_modules:
 - mounts
 - locale
 - set-passwords
 - yum-add-repo
 - package-update-upgrade-install
 - timezone
 - puppet
 - chef
 - salt-minion
 - mcollective
 - disable-ec2-metadata
 - runcmd
cloud_final_modules:
 - rightscale_userdata
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - scripts-user
 - ssh-authkey-fingerprints
 - keys-to-console
 - phone-home
 - final-message
system_info:
  default_user:
    name: centos
    lock_passwd: true
    gecos: Cloud User
    groups: [wheel, adm]
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    shell: /bin/bash
  distro: rhel
  paths:
    cloud_dir: /var/lib/cloud
    templates_dir: /etc/cloud/templates
  ssh_svcname: sshd
# vim:syntax=yaml

qemu-guest-agent的配置文件:

/etc/sysconfig/qemu-ga 
TRANSPORT_METHOD="virtio-serial"
DEVPATH="/dev/virtio-ports/org.qemu.guest_agent.0"
LOGFILE="/var/log/qemu-ga/qemu-ga.log"
PIDFILE="/var/run/qemu-ga.pid"
BLACKLIST_RPC=""                                 #默认配置需要修改此行,清除引号中内容
FSFREEZE_HOOK_ENABLE=0

三、其他系统配置

3.1禁用默认的zeroconf route

# echo "NOZEROCONF=yes" >> /etc/sysconfig/network

3.2修改kernel启动参数,编辑/boot/grub/grub.conf,在kernel所在行添加console字段

kernel ... console=ttyS0,115200n8 console=tty0

3.3关闭开机启动服务

# chkconfig iptables off

# chkconfig iptables6 off

# chkconfig postfix off

3.4关闭selinux

# vim /etc/selinux/config

...

SELINUX=disabled 设置为关闭,重启后生效。

...

# setenforce 0 可临时设置为0,重启后配置文件生效。

四、定制化配置

对系统进行定制化配置,配置完后关闭虚拟机。

# poweroff

五、处理镜像

5.1初始化镜像文件,删除网卡MAC等信息

# virt-sysprep -d centos-6.5

5.2 Undefine虚拟机

# virsh undefine centos-6.5

5.3转换和压缩镜像文件

# virt-sparsify --convert qcow2 --compress /tmp/centos-6.5.raw /tmp/centos-6.5.qcow2

六、测试镜像

cloudmetadata.iso作为虚拟机唯一的光驱连接到关闭状态的虚拟机,启动虚拟机后,检查虚拟机是否可以被注入hostname和密码,hostname应该被注入为linux-host,密码为Ustack2016

七、发布镜像

7.1发布准备

登录云平台物理机,将制作好的镜像上传到glance服务所在主机文件系统中的目录/var/image/extra/,并对镜像进行重命名操作,重命名示例如下:

发行版---详细版本号---制作日期(日期+字母).qcow2

CentOS---6.5-64bit---2019-12-20-a.qcow2

说明:

发行版 和 详细版本号 用于镜像分类

制作日期用来标志唯一镜像

格式必须满足上述示例要求

对/var/image/extra/uiu/meta-info/目录内文件的说明,我们通过该目录预定义一些镜像的属性,meta-info内含各个镜像的基本属性,当新添加发行版或新的大版本时,需要创建关联的文件

# ls meta-info/CentOS/6.5-64bit
主要看EXPECTED_SIZE,这个要和raw格式镜像的大小匹配,并需要注意的是image_meta里的pass不一定是初始密码(安装了cloudinit的镜像,初始密码由cloudinit读取metadata获得),display_name是面板上所展示的名字,image_name_order和image_label_order分别用于定义面板上镜像的显示顺序的。

7.2生成镜像校验文件

# md5sum CentOS---6.5-64bit---2019-12-20-a.qcow2 > CentOS---6.5-64bit---2019-12-20-a.qcow2.md5sum

7.3发布镜像

进入目录/var/image/extra/uiu/,执行publish_extra_img上传镜像

# source /root/adminrc

# ./publish_extra_img /var/image/extra/CentOS---6.5-64bit---2019-12-20-a.qcow2

7.4验证

glance命令:

# 查看镜像列表

glance image-list

# 查看具体镜像

glance image-show [IMAGE_ID]

# 修改如何镜像属性

glance help image-update

# 删除镜像

glance image-delete [IMAGE_ID]

在web界面使用上传的镜像新建虚机,测试是否可以正常使用

发布了638 篇原创文章 · 获赞 1184 · 访问量 159万+

猜你喜欢

转载自blog.csdn.net/itcast_cn/article/details/103733186