当前位置: 首页 > 科技观察

在线升级一目了然的形象技巧

时间:2023-03-14 00:33:59 科技观察

0。背景我们经常需要更新glance镜像,比如上传的镜像可能存在配置问题,或者需要升级现有镜像的软件包或者预装一些新的软件包。当时我们开始这个事情是因为我们对cloud-init做了很多patch,需要同步到glance镜像。如果我们重新创建镜像,然后将其转移到生产环境中,不仅非常繁琐,而且非常耗时。我们希望能够在原有镜像的基础上直接升级cloud-init。1.快照更新镜像最简单的方法是创建云主机,然后更新cloud-init并创建快照形成新镜像(注意删除/var/lib/cloud下的文件,否则cloud-init将在下次启动时不会重新获取元数据)。但是我们遇到的问题是老版本的cloud-init在L版本中注入密码和key失败,而且安装的qemu-guest-agent不支持修改密码,所以无法登录到云主机。因此,必须找到另一种方法。2.glancestorage的后端使用的是本地文件系统,所以我们想到了将镜像挂载到本地文件系统,然后chroot到镜像文件系统环境进行升级配置。如果glance镜像使用本地文件系统作为存储后端,镜像格式为raw,挂载镜像非常简单:losetup/dev/loop0image.imgkpartx-a/dev/loop0mount/dev/mapper/loop0p1/mnt/imageqcow2格式,需要安装qemu-nbd工具包,加载nbd内核模块:modprobenbdmax_part=63qemu-nbd-c/dev/nbd0image.imgmount/dev/nbd0p1/mnt/image如果image中使用了LVM文件系统,可以使用如下方法初始化:vgscanvgchange-aymount/dev/VolGroupName/LogVolName/mnt/imagechroot执行相关操作后,卸载image文件系统:umount/mnt/imagevgchange-anVolGroupNamekillallqemu-nbdkpartx-d/dev/loop0losetup-d/dev/loop0以上方法见Mounting-raw-and-qcow2-vm-disk-images。本文不重点讨论基于本地文件系统作为存储后端的情况,而是重点介绍基于Ceph存储后端的操作方法。下面将详细描述该过程。3、基于Ceph存储后端的更新方式。我们知道,在使用ceph作为存储后端时,镜像会先生成一个名为snap的快照。里面有对应的图片,名字和glance图片id一致。查看它的快照:rbdsnapls--imageopenstack-images/35fcb79c-43a1-4b59-83d7-f4e46a5244192>/dev/null输出:SNAPIDNAMESIZE94604snap20480MB我们不能直接修改快照snap,因为它是受保护的,只能读不能写。如果直接修改镜像,无法同步到快照,出错也不容易回滚。所以我们的做法是先复制一份rbd镜像。首先使用glance命令行工具获取需要更新的镜像的id:IMAGE_ID=$(glanceimage-list--name"CentOS7.164bit2>/dev/null|awk--re-interval'/\w{8}-.*/{print$2}')使用rbd命令复制一个镜像副本,假设POOL变量是glance使用的ceph池:rbdcp$POOL/${IMAGE_ID}$POOL/${IMAGE_ID}_copy挂载镜像到本地文件系统:rbdmap$POOL/${IMAGE_ID}_copy#/dev/rbd0mount/dev/rbd0p1/mnt注意由于镜像是Linux文件系统,通常只有一个根分区,如果是Windows镜像,第一个分区一般是隐藏分区,C盘是第二个分区,所以挂载时注意选择rbd0p2,其中p代表分区。本地挂载后,可以将软件包和配置模板复制到镜像文件系统,如/mnt/root/,然后chroot进入镜像文件系统:cd/mnt#/mnt是我们需要chroot的根目录#mount-tprocprocproc/#mountproc#TouseaninternetconnectioninthechrootenvironmentcopyovertheDNSdetails:cp/etc/resolv.confetc/resolv.conf#Overwrite,生成的云主机会自动覆盖#Tochangerootintoabashshell:chroot/mntbash#chrootto/mnt,如果提示bash命令不能找到了,用绝对路径chroot/mnt/bin/bash试试#初始化环境变量source/etc/profilesource~/.bashrc#如果提示找不到ls等命令,需要手动设置PATH变量:PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/bin#Tip:可选地,创建一个唯一的提示以能够区分你的chroot环境:exportPS1="(chroot)$PS1"然后就可以执行镜像更新的命令,比如更新cloud-init:yumremovecloud-init#Removetheoldversionpackagerpm-icloud-init-0.7.6-bzr1.el7.centos.noarch.rpm#Installthepacakge升级qemu-guest-agent:yuminstall-yqemu-guest-agentrpm-aq|grepqemu-guest-agent#qemu-guest-agent-2.3.0-4.el7.x86_64执行所有更新操作后,完成以下清理工作:yumcleanallrm-rf/root/*#危险!!!删除根目录下复制的临时文件,确认没有有用文件后再执行!exit#退出chroot环境cd#切换到主目录,工作目录不能位于/mnt,否则无法卸载umount--recursive/mnt/#忙了怎么办?查看lsof占用了哪个进程,如果还是不行,试试使用--lazy参数rbdunmap/dev/rbd0#Uninstallfromrbd***需要更新glance,我们的方法是创建一个空的镜像实例先glance,不用指定镜像文件,直接坑一下,获取新的imageid:NEW_IMAGE_ID=`glanceimage-create|grepid|awk'{print$4}'`||{echo'Error:glanceimage-createfailed!';exit1;}接下来更新我们的rbd镜像,将其命名为新创建的镜像实例id并设置快照:rbdmv$POOL/${IMAGE_ID}_copy$POOL/${NEW_IMAGE_ID}rbd--pool=$POOL--image=${NEW_IMAGE_ID}--snap=snapsnapcreaterbd--pool=$POOL--image=${NEW_IMAGE_ID}--snap=snapsnappprotect***更新glance图像元数据:glanceimage-update--name="$DISPLAY_NAME"--disk-format=raw--container-format=bare--is-public=True${NEW_IMAGE_ID}glanceimage-update--propertyimage_meta="$image_meta"${NEW_IMAGE_ID}glanceimage-update--propertyhw_qemu_guest_agent=yes$IMAGE_ID#...#updateimagelocationFSID=`ceph-s|grepcluster|awk'{print$2}'`glanceimage-update--locationrbd://$FSID/$POOL/$IMAGE_ID/snap${NEW_IMAGE_ID}if[[$IMAGE_LABEL=="Windows"||$IMAGE_LABEL=="windows"]];thenglanceimage-update--propertyhw_video_model=qxl--propertyhw_video_ram=64--propertyos_admin_user=Administrator$IMAGE_IDfi***验证新图片的功能,如果没有问题,可以放心删除旧图片【本文为专栏作者】傅广平《原创文章,如需转载请联系]点此查看该作者更多好文