使用云镜像在KVM上创建一个Linux实验环境

参考自: http://giovannitorres.me/create-a-linux-lab-on-kvm-using-cloud-images.html 真可惜,发现是基于CentOS,可我的开发换是Ubuntu。其中的cloud-localds 命令找不到。

发现一个找命令的工具网站 https://command-not-found.com/cloud-localds ,安装 cloud-image-utils。

找到一个cloud-init,这应该是配套云镜像使用:

Ubuntu找到几个有意思的包:有图形化管理qemu的和使用云镜像的,有空试玩

uvtool/xenial,xenial 0~bzr99-0ubuntu1 all
  Library and tools for using Ubuntu Cloud images

uvtool-libvirt/xenial,xenial 0~bzr99-0ubuntu1 all
  Library and tools for using Ubuntu Cloud Images with libvirt

qtemu/xenial 2.0~alpha1-1ubuntu6 amd64
  graphical user interface for QEMU

ubuntu-virt-mgmt/xenial,xenial 1.4 all
  Common packages useful for managing virtual machines graphically

之前参考的文章,脚本更新了,在 https://github.com/giovtorres/kvm-install-vm。Bash包装了virt-install,仅在 Fedora 最新版上测试过。使用的 ssh-authorized-keys 登陆。这是方式一。


好了,正式开始。有一简短的教程可以参考,使用的指定password登陆。这是方式二,可能更方便些。就从这个入手了。

# Ubuntu 16.04
sudo apt install libvirt-dev libvirt0 libvirt-bin virt-top virt-manager virt-what virt-goodies genisoimage cloud-init cloud-image-utils libguestfs-tools qemu qemu-kvm
# reboot

cat > cloud-config <<EOF
#cloud-config
preserve_hostname: False
hostname: centos
fqdn: centos.example.local
password: 123456
chpasswd: { expire: False }
ssh_pwauth: True
runcmd:
  - [ yum, -y, remove, cloud-init ]
EOF

cloud-localds cloud-config.img cloud-config
mv cloud-config.img /var/lib/libvirt/images

# get the qcow2 images
wget http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2.xz #下载 img 文件
xz -d CentOS-7-x86_64-GenericCloud.qcow2.xz
cp CentOS-7-x86_64-GenericCloud.qcow2 centos.qcow2 #复制一份
# qemu-img resize centos.qcow2 +10G #增加磁盘大小
mv centos.qcow2 /var/lib/libvirt/images

#导入
virt-install --connect=qemu:///system \
 --name centos \
 --ram 2048 \
 --vcpus=2 \
 --os-type=linux \
 --os-variant=centos7.0 \
 --disk /var/lib/libvirt/images/centos.qcow2,device=disk,bus=virtio \
 --disk /var/lib/libvirt/images/cloud-config.img,device=cdrom \
 --graphics none \
 --import

导入后可使用用户名 centos 密码 123456 登陆

virt-install第一次安装时,硬件地址,获取IP是没有问题的。之后通过Libvirt启动该磁盘镜像时,会遇到dhclient没有运行,获取不到IPv4地址的问题,需要修改镜像中网卡的IP地址,使之与Libvirt分配的硬件地址匹配。

# 手动获取IP
/sbin/dhclient -1 -q -lf /var/lib/dhclient/dhclient--eth0.lease -pf /var/run/dhclient-eth0.pid -H centos eth0

(可选)在虚拟机中安装,之后开发要用,通过该软件来获取宿主机的IP。

sudo yum install qemu-guest-agent

qemu-guest-agent是一个助手守护进程,它安装在guest中。它用于在主机和客户端之间交换信息,并在客户端执行命令。 具体特性

基于QMP实现对qemu虚拟机进行交互,qemu命令参数支持2种方法配置qmp,即-qmp和-mon。Libvirt使用的-mon。

$ virsh qemu-monitor-command centos7.0 --pretty '{ "execute": "query-block" }'
{
    "return": [
        {
            "io-status": "ok",
            "device": "drive-virtio-disk0",
            "locked": false,
            "removable": false,
            "inserted": {
                "iops_rd": 0,
                "detect_zeroes": "off",
                "image": {
                    "virtual-size": 8589934592,
                    "filename": "/var/lib/libvirt/images/centos.qcow2",
                    "cluster-size": 65536,
                    "format": "qcow2",
                    "actual-size": 2079526912,
                    "format-specific": {
                        "type": "qcow2",
                        "data": {
                            "compat": "0.10",
                            "refcount-bits": 16
                        }
                    },
                    "dirty-flag": false
                },
                "iops_wr": 0,
                "ro": false,
                "node-name": "#block155",
                "backing_file_depth": 0,
                "drv": "qcow2",
                "iops": 0,
                "bps_wr": 0,
                "write_threshold": 0,
                "encrypted": false,
                "bps": 0,
                "bps_rd": 0,
                "cache": {
                    "no-flush": false,
                    "direct": false,
                    "writeback": true
                },
                "file": "/var/lib/libvirt/images/centos.qcow2",
                "encryption_key_missing": false
            },
            "type": "unknown"
        }
    ],
    "id": "libvirt-6114"
}

$ virsh qemu-monitor-command centos7.0 --hmp 'info block'
drive-virtio-disk0 (#block155): /var/lib/libvirt/images/centos.qcow2 (qcow2)
    Cache mode:       writeback

学习qmp的简单使用

以及, 使用QEMU客户代理查找客户IP地址

# 查看支持的操作
$ virsh qemu-agent-command centos7.0 --pretty '{ "execute": "guest-info" }'
{
    "return": {
        "version": "2.12.0",
        "supported_commands": [
            {
                "enabled": true,
                "name": "guest-get-osinfo",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-timezone",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-users",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-host-name",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-exec",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-exec-status",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-memory-block-info",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-set-memory-blocks",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-memory-blocks",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-set-user-password",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-fsinfo",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-set-vcpus",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-vcpus",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-network-get-interfaces",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-suspend-hybrid",
                "success-response": false
            },
            {
                "enabled": true,
                "name": "guest-suspend-ram",
                "success-response": false
            },
            {
                "enabled": true,
                "name": "guest-suspend-disk",
                "success-response": false
            },
            {
                "enabled": true,
                "name": "guest-fstrim",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-fsfreeze-thaw",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-fsfreeze-freeze-list",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-fsfreeze-freeze",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-fsfreeze-status",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-file-flush",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-file-seek",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-file-write",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-file-read",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-file-close",
                "success-response": true
            },
            {
                "enabled": false,
                "name": "guest-file-open",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-shutdown",
                "success-response": false
            },
            {
                "enabled": true,
                "name": "guest-info",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-set-time",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-get-time",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-ping",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-sync",
                "success-response": true
            },
            {
                "enabled": true,
                "name": "guest-sync-delimited",
                "success-response": true
            }
        ]
    }
}

$ virsh qemu-agent-command centos7.0 --pretty '{ "execute": "guest-network-get-interfaces" }'
{
    "return": [
        {
            "name": "lo",
            "ip-addresses": [
                {
                    "ip-address-type": "ipv4",
                    "ip-address": "127.0.0.1",
                    "prefix": 8
                },
                {
                    "ip-address-type": "ipv6",
                    "ip-address": "::1",
                    "prefix": 128
                }
            ],
            "statistics": {
                "tx-packets": 6,
                "tx-errs": 0,
                "rx-bytes": 416,
                "rx-dropped": 0,
                "rx-packets": 6,
                "rx-errs": 0,
                "tx-bytes": 416,
                "tx-dropped": 0
            },
            "hardware-address": "00:00:00:00:00:00"
        },
        {
            "name": "eth0",
            "ip-addresses": [
                {
                    "ip-address-type": "ipv4",
                    "ip-address": "192.168.122.58",
                    "prefix": 24
                },
                {
                    "ip-address-type": "ipv6",
                    "ip-address": "fe80::5054:ff:fe28:c078",
                    "prefix": 64
                }
            ],
            "statistics": {
                "tx-packets": 247,
                "tx-errs": 0,
                "rx-bytes": 100007,
                "rx-dropped": 12,
                "rx-packets": 1531,
                "rx-errs": 0,
                "tx-bytes": 19704,
                "tx-dropped": 0
            },
            "hardware-address": "52:54:00:28:c0:78"
        }
    ]
}

新建一个会话,弹出 cloud init 初始化镜像

$ virsh list
 Id    Name                           State
----------------------------------------------------
 4     centos                         running

$ virsh change-media centos hda --eject --config
Successfully ejected media.

退出时使用 Ctrl 键+ ] (左方括号)键退出

再次命令行界面登陆 virsh console

virsh start centos
virsh list #确保running
virsh console centos

关闭virsh shutdown

$ virsh list --all
 Id    Name                           State
----------------------------------------------------
 -     centos                         shut off

之后立即禁止开机启动cloud-init,或者卸载。导致虚拟机开机启动贼慢。

$ ls /lib/systemd/system/cloud-*.service
/lib/systemd/system/cloud-config.service  /lib/systemd/system/cloud-init-local.service
/lib/systemd/system/cloud-final.service   /lib/systemd/system/cloud-init.service

$ systemctl disable cloud-config cloud-init-local cloud-final cloud-init
Removed symlink /etc/systemd/system/cloud-init.target.wants/cloud-config.service.
Removed symlink /etc/systemd/system/cloud-init.target.wants/cloud-init.service.
Removed symlink /etc/systemd/system/cloud-init.target.wants/cloud-init-local.service.
Removed symlink /etc/systemd/system/cloud-init.target.wants/cloud-final.service.

提供上述制作的镜像centos7.qcow2下载。

链接:https://pan.baidu.com/s/16PT60usy_HhxmtXD-FO-3A 
提取码:j8v1 
复制这段内容后打开百度网盘手机App,操作更方便哦

用virt-manager来启动,手动qemu启动,可能启动之后就找不到了

qemu-system-x86_64 -hda /var/lib/libvirt/images/centos7.qcow2 -enable-kvm  -vnc 0.0.0.0:0

推荐一本KVM入门书:《KVM Virtualization Cookbook》,网上有电子版


那如何在Windows上Libvirt呢? https://libvirt.org/windows.html

https://blog.csdn.net/weiyuanke/article/details/8020657


如何在Windows上使用qemu启动qcow2系统镜像?

https://www.xiexianbin.cn/windows/2017-02-16-use-qemu-start-qcow2-image-in-window/index.html

qemu-system-x86_64 -m 1024 -smp 1 -drive file="G:\VM\qemu\centos7.qcow2" -boot c -net nic -net tap,ifname=my-tap
Windows下启动的qemu虚拟机

一次永久解决cmd窗口汉字显示乱码:

  1. win+R 输入regedit 进入注册表
  2. 找到 HKEY_CURRENT_USER\Console\%SystemRoot%_system32_cmd.exe 如果 该项下已存在CodePage项,则把值改为十进制”65001”;如果不存在,在该项下新建一个 DWORD(32位值),命名为“CodePage”,值设为“65001”
  3. 重启cmd后生效
  4. 对于Power shell修改同样,只需在第2步修改
    %SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe 下的项。