11月29日 KVM虚拟化技术(Virtualization)

1、虚拟化技术简介

libvirt是提供了一个方便的方式来管理虚拟机和其他虚拟化功能的软件的集合,如存储和网络接口管理。这些软件包括一个API库,一个守护进程(Libvirtd),和一个命令行实用程序(virsh)。

  • 主机虚拟化的类型:
    TYPE-I:
    硬件级别直接运行hypervisor;
    xen, vmware ESX/ESXI
    TYPE-II:
    于硬件级别运行一个OS(Host OS),而此OS上运行一个VMM;
    vmware workstation, virtualbox, kvm
    Linux目前流行的开源虚拟化技术解决方案:
    主机虚拟化:xen, kvm, virtualbox
    容器级:lxc, libcontainer, runC, openvz
    模拟器:qemu
  • cpu的环0、环1、环2、环3


    image.png

    cpu从内到外被分成环0-环3使用,环1和环2一般情况下不会使用,环0运行的是一些特权指令,环3运行的是一些普通指令,用户空间运行的一些普通指令,比如1+1等于几,用户空间直接操纵cpu的环3去运行此指令,如果要进行IO操作,比如把1+1的运算结果保存到磁盘,此时用户空间没有权限去执行,就会进行系统调用,进入内核空间,操纵cpu的环0去执行这些特权指令。
    cpu的硬件虚拟化指在环0内部再加一个环-1,环0留给虚拟机的操作系统(GuestOS),环-1留给宿主机的操作系统(HostOS),虚拟机是建立在宿主机之上的。判断一个主机是否支持虚拟化就是看cpu是否有环-1

  • 虚拟化技术的分类:
    (1) 模拟:Emulation:cpu的环0和环3都是虚拟的
    Qemu, PearPC, Bochs, ...
    (2) 完全虚拟化:Full Virtualization,Native Virtualization:cpu的环0是虚拟的,环3是真实的
    BT/hvm
    VMWare Workstation, VirtualBox, VMWare Server, Parallels Desktop, KVM(hvm), XEN(hvm)
    (3) 半虚拟化:Para-Virutalization
    特点:GuestOS(运行在虚拟机上的操作系统)明确知道自己运行在虚拟机之上,并且明确知道要执行某个特权指令时不去找环0,而是找虚拟机管理器去提供一个环0的功能接口
    xen, UML(user-mode linux)
    (4) 容器级虚拟化:
    LXC, OpenVZ, libcontainer, runC, rkt, Linux V Servers, Virtuozzo, ...
    (5) 库级别虚拟化:
    wine
    (6) 程序级虚拟化
    jvm, pvm, ...
  • 虚拟化需要安装的软件包
    先安装kvm模块modprobe kvm
    yum install qemu-kvm libvirt-daemon-kvm virt-manager

2、使用virt-manager管理KVM

使用virt-manager管理KVM就是在图形界面下快速创建虚拟机、安装操作系统。
首先要将虚拟机设置成如下图所示才能支持虚拟化,也就是在虚拟机上安装虚拟机


image.png

无标题1.png
[root@node3 network-scripts]#grep -i -E "(vmx|svm|lm)" /proc/cpuinfo #首先查看主机是否支持虚拟化
vmx:是intel的cpu硬件虚拟化标识,也就是有环-1
svm:是amd的cpu硬件虚拟化标识,也有环-1
lm:longmode,确保是x86_64的架构,也就是要确保是64位系统,因为虚拟化功能要在64位系统上
[root@node3 network-scripts]#modprobe kvm #安装kvm模块
[root@node3 ~]# modprobe kvm-intel
[root@node3 ~]# lsmod |grep kvm
kvm_intel              55432  0 
kvm                   346318  1 kvm_intel
[root@node3 network-scripts]#ll /dev/kvm
crw-rw-rw-. 1 root kvm 10, 232 Nov 29 17:33 /dev/kvm #发现生成了此字符文件
[root@node3 network-scripts]#yum install qemu-kvm libvirt-daemon-kvm virt-manager #安装软件包
[root@node3 network-scripts]#systemctl start libvirtd #启动服务
[root@node3 network-scripts]#systemctl status libvirtd
[root@node3 network-scripts]#cdnet
[root@node3 network-scripts]#cp ifcfg-ens33 ifcfg-br0
[root@node3 network-scripts]#vim ifcfg-br0 #创建一个物理网桥,并配置原来物理网卡的ip地址
DEVICE=br0
TYPE=bridge
IPADDR=172.18.21.100
PREFIX=16
GATEWAY=172.18.0.1
DNS1=172.18.0.1
[root@node3 network-scripts]#vim ifcfg-ens33 #将物理网卡中的ip地址去掉,变成物理的交换机
DEVICE=ens33
BRIDGE="br0" #将物理交换机和物理网桥连接
这样相当于物理网桥和物理的网卡交换位置了,物理网卡充当物理交换机,物理网桥充当宿主机的一个虚拟网卡和外部通讯
[root@node3 network-scripts]#systemctl restart network
[root@node3 network-scripts]#ip a 
[root@node3 network-scripts]#brctl show #查看网桥的连接情况,此命令来自于bridge-utils软件包
bridge name bridge id       STP enabled interfaces
br0     8000.0050562375d6   no      ens33

在图形界面下输入如下命令就可以创建虚拟机,并安装操作系统了,这里使用的是PXE安装,需要事先搭建好PXE的环境。将虚拟机的网络和PXE主机的网络放在同一网段,并且不使用vmware workstation的dhc分配ip地址,而使用PXE环境中的dhcp分配ip地址


image.png
brctl用来管理网桥的命令,来自bridge-utils软件包
[root@node3 images]#lsmod |grep bridge #查看桥模块是否加载
bridge                107106  0 
[root@node3 network-scripts]#brctl help #查看帮助
[root@node3 network-scripts]#brctl addbr br1 #添加一个网桥
[root@node3 network-scripts]#brctl show #查看网桥
[root@node3 network-scripts]#ip link set br1 up #开启网桥
[root@node3 ~]#brctl addif br1 ens37 #把网卡添加到网桥上
[root@node3 ~]#ip link set br1 down
[root@node3 ~]#brctl delbr br1 #删除网桥之前要先把网桥设置为down状态
### 3、使用磁盘镜像文件来安装虚拟机
1、查看磁盘镜像文件支持的格式
[root@node3 ~]#qemu-img -h #查看磁盘镜像文件支持的格式及创建的时候的帮助信息,如何创建
一般创建的时候使用qcow2格式,表示写时复制格式,co=copy,
w=write,是一种非常高级的格式,支持镜像文件的压缩、加密、快照
等各种高级功能,并且qemu-img这个工具支持使用http、ftp等协议去
加载另外一个服务器上的文件当做磁盘镜像文件。
如果使用vmware创建虚拟机,还可以使用vmdk格式
[root@node3 app]#mkdir /app/vm/images -pv
[root@node3 app]#qemu-img creat -f qcow2 -o ? /app/vm/images/test.qcow2 #创建磁盘镜像文件时需要带选项如何查帮
助,-o后面加个?,-o指要带的选项,一般带preallocation这个选项,
表示创建的时候给这个磁盘镜像文件预分配哪些空间,怎么分配的,值
有off表示不分配任何内容,用的时候再分配,metadata表示只分配磁盘
镜像文件的元数据,full表示指定多大将分配多大空间,一般情况下使
用metadata
[root@node3 app]#qemu-img create -f qcow2 -o size=120G,preallocation=metadata /app/vm/images/test.qcow2 #开始创建,注意这里创建的只是一个裸的虚拟磁盘,里面并没有操作系统
[root@node3 app]#cd /app/vm/images/
[root@node3 images]#ll -h 
total 23M
-rw-r--r--. 1 root root 121G Nov 30 10:24 test.qcow2 #发现大小为121G,1G是元数据,另外120G是可用的大小
[root@node3 images]#du -sh test.qcow2  #但用此命令发现真正的大小只有23M,ll命令是会欺骗你的,这就是稀疏格式
23M test.qcow2
[root@node3 images]#qemu-img info /app/vm/images/test.qcow2 
image: /app/vm/images/test.qcow2
file format: qcow2
virtual size: 120G (128849018880 bytes)
disk size: 23M
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false

依然选择PXE安装,然后指明磁盘镜像文件的路径就可以在这个磁盘镜像文件上安装操作系统了

image.png

https://launchpad.net/cirros/ 此网站提供了磁盘镜像文件,可以直接从此处下载创建好的磁盘镜像文件,这些磁盘镜像文件中已经安装好了操作系统,导入后不用安装操作系统可以直接使用,可以用于云环境下测试用

[root@node3 images]#ll -h #下载一个磁盘镜像文件并上传
total 9.4M
-rw-r--r--. 1 root root 9.4M Nov 30 10:50 cirros-0.3.0-x86_64-disk.img
[root@node3 images]#cp cirros-0.3.0-x86_64-disk.img c1.img
[root@node3 images]#cp cirros-0.3.0-x86_64-disk.img c2.img
[root@node3 images]#ls #将这个磁盘镜像文件复制两份
c1.img  c2.img  cirros-0.3.0-x86_64-disk.img
[root@node3 images]#qemu-img info c1.img 
image: c1.img
file format: qcow2 #发现格式也是qcow2的
virtual size: 39M (41126400 bytes)
disk size: 9.3M
cluster_size: 65536
Format specific information:
    compat: 0.10
image.png

image.png

image.png

image.png

image.png

QQ截图20171130111127.png

从上图我们发现这已经是一个很小的虚拟机了,并且里面是一个很小的操作系统,可以用c2.img再创建一个虚拟机,让这两个虚拟机可以相互通讯了

4、如何使用qeum-kvm来手动安装虚拟机实例

kvm只能虚拟化cpu和内存,需要qemu来辅助虚拟化IO等其他设备
qemu-kvm可以实现字符界面下手动创建虚拟机实例
Qemu:处理器模拟器
仿真各种IO设备、将仿真设备连接至主机的物理设备、提供用户接口
qemu-kvm命令语法:
qemu-kvm [options] [disk_image]
选项有很多类别:
标准选项、块设备相关选项、显示选项、网络选项、...
标准选项:
-machine [type=]name:-machine help来获取列表,用于指定模拟的主机类型;
-cpu cpu:-cpu help来获取列表;用于指定要模拟的CPU型号;
-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]:指明虚拟机上vcpu的数量及拓扑;sockets表示有个插槽,也就是几颗cpu,cores表示一颗cpu是几核,threads表示以核支持多少个线程,所以最后的虚拟cpu数量相当于这个三个数量相乘
-boot [order=drives][,once=drives][,menu=on|off] [,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_time][,strict=on|off]
order:各设备的引导次序:c表示第一块硬盘,d表示第一个光驱设备;-boot order=dc,once=d表示光盘只在第一次引导,下次就硬盘引导了
-m megs:虚拟机的内存大小;
-name NAME:当前虚拟机的名称,要惟一;
块设备相关的选项:
-hda/-hdb file:指明IDE总线类型的磁盘映射文件路径;第0和第1个;
-hdc/-hdd file:第2和第3个;
-cdrom file:指定要使用光盘映像文件;
-drive [file=file][,if=type][,media=d][,index=i] [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]:
file=/PATH/TO/SOME_IMAGE_FILE:映像文件路径;
if=TYPE:块设备总线类型,ide, scsi, sd, floppy, virtio,...
media=TYPE:介质类型,cdrom和disk;
index=i:设定同一类型设备多个设备的编号; cache=writethrough|writeback|none|directsync|unsafe:缓存方式;
format=f:磁盘映像文件的格式;
显示选项:
-display type:显示的类型,sdl, curses, none和vnc;
-nographic:不使用图形接口;
-vga [std|cirrus|vmware|qxl|xenfb|none]:模拟出的显卡的型号;
-vnc display[,option[,option[,...]]]]:启动一个vnc server来显示虚拟机接口; 让qemu进程监听一个vnc接口;
display:
(1) HOST:N
在HOST主机的第N个桌面号输出vnc;
5900+N
(2) unix:/PATH/TO/SOCK_FILE
(3) none
options:
password:连接此服务所需要的密码;
-monitor stdio:在标准输出上显示monitor界面;
Ctrl-a, c:在console和monitor之间切换;
Ctrl-a, h
网络选项:
-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]
为虚拟机创建一个网络接口,并将其添加至指定的VLAN;
model=type:指明模拟出的网卡的型号,ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio;
-net nic,model=?
macaddr=mac:指明mac地址;52:54:00:
-net tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]:
通过物理的TAP网络接口连接至vlan n;
script=file:启动虚拟机时要执行的脚本,默认为/etc/qemu-ifup
downscript=dfile:关闭虚拟机时要执行的脚本,/etc/qemu-ifdown
ifname=NAME:自定义接口名称;

/etc/qemu-ifup
#!/bin/bash
#
bridge=br0
if [ -n "$1" ];then
ip link set $1 up
sleep 1
brctl addif $bridge $1
[ $? -eq 0 ] && exit 0 || exit 1
else
echo "Error: no interface specified."
exit 1
fi

其它选项:
-daemonize:以守护进程运行;

示例
此示例是在上面的基础上完成的,也就是安装好了软件包,创建好了物理网桥等前期的操作
[root@node3 images]#rpm -ql qemu-kvm #发现此命令不在PATH路径下
/usr/libexec/qemu-kvm
[root@node3 images]#ln -s /usr/libexec/qemu-kvm /usr/bin/ #创建一个软链接到PATH路径下就可以使用此命令了
[root@node3 images]#cp cirros-no_cloud-i386.img c1.img
[root@node3 images]#cp cirros-no_cloud-i386.img c2.img
[root@node3 images]#ls /app/vm/images/ #此实验的磁盘镜像文件 
cirros-no_cloud-i386.img是老师经过处理的,去掉了里面的一些脚本,
便于实现时可以快速显示登录信息,不必等到超时
c1.img  c2.img  cirros-no_cloud-i386.img
[root@node3 ~]#qemu-kvm -name c2 -m 64 -smp 4,sockets=2,cores=2 -drive file=/app/vm/images/c2.img,if=virtio,media=disk -nographic #使用此命令创建虚拟机,if=virtio表示块设备总线类型为半虚拟化,一般使用此类型

有的时候要等很长时间才能完成安装,超时连接30次之后才能显示登录信息,此实验使用的磁盘镜像文件是处理过的,很快就会显示登录信息


image.png

要想关闭虚拟机,可以使用poweroff,或者可以先ps aux查看一下进程编号,然后使用kill命令就可以关闭

  • 如何使用vnc来显示虚拟机接口
[root@node3 images]#yum install tigervnc #要安装tigervnc软件包,就可以在vnc上显示虚拟机了
[root@node3 images]#qemu-kvm -name c2 -m 64 -smp 4,sockets=2,cores=2 -drive file=/app/vm/images/c2.img,if=virtio,media=disk -vnc :0 --daemonize #-vnc :0 表示监听在vnc的0号桌面,也就是5900端口,--daemonize表示
后台运行,5900表示vnc的0号桌面,5901表示1号桌面,5902表示2号
桌面,如果不指明默认也是以nvc打开图形界面的
[root@node3 images]#ss -nlt
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      1            *:5900                     *:*                  
[root@node3 images]#ps aux #发现程序在后台运行了
root      11190  6.3  6.2 657656 62076 ?        Sl   14:54   0:05 qemu-kvm -name c2 -m 64 -smp 4,sockets=2,cores=2 -drive file=/app/vm/images/c2.img,if=virti

此时在图形界面下vncviewer :0命令就可以看到vnc打开的图形界面


image.png

5、使用网络选项创建虚拟机

在vmware workstation中网络连接模式有三种


image.png

这三种分别是什么含义呢


image.png

示例1:特定虚拟网络模式,也就是不能和物理机通讯,只能两台虚拟机相互通讯
[root@centos7 ~]#grep -i -E "(vmx|svm|lm)" /proc/cpuinfo
[root@centos7 app]#modprobe kvm
[root@centos7 app]#lsmod |grep kvm
[root@centos7 app]#yum install qemu-kvm tigervnc -y
[root@centos7 ~]#brctl addbr vnet0 #创建一个私有网桥,也就是虚拟的交换机
[root@centos7 ~]#brctl show
bridge name bridge id       STP enabled interfaces
virbr0      8000.525400c04670   yes     virbr0-nic
vnet0       8000.000000000000   no      
[root@centos7 ~]#ip link set vnet0 up #激活此交换机
[root@centos7 app]#ln -s /usr/libexec/qemu-kvm /usr/bin
[root@centos7 app]#vim /etc/qemu-ifup #创建一个添加虚拟机网卡到网桥的启动脚本
#!/bin/bash
#
bridge=vnet0
if [ -n "$1" ];then #如果虚拟网卡存在
      ip link set $1 up  #就激活此虚拟网卡
      sleep 1
       brctl addif $bridge $1 #将虚拟网卡连接到网桥上,也就是连接到虚拟交换机上
       [ $? -eq 0 ] && exit 0 || exit 1
else
       echo "no interface specified" 
           exit 2
fi
[root@centos7 app]#chmod a+x /etc/qemu-ifup
[root@centos7 app]#bash -n /etc/qemu-ifup
[root@centos7 app]#vim /etc/qemu-ifdown #创建一个摘除虚拟机网卡到网桥的脚本
#!/bin/bash
#
bridge=vnet0
if [ -n "$1" ];then
       brctl delif $bridge $1
       [ $? -eq 0 ] && exit 0 || exit 1
else
       echo "no interface specified"
            exit 2
fi
[root@centos7 app]#chmod a+x /etc/qemu-ifdown
[root@centos7 app]#bash -n /etc/qemu-ifdown
[root@centos7 app]#qemu-kvm -name c1 -m 64m -smp 2 -drive file=/app/c1.img,if=virtio,media=disk -vnc :0 -daemonize -net nic,model=e1000,macaddr=52:54:00:00:00:01 -net tap,script=/etc/qemu-ifup,ifname=eth0 #macaddr=52:54:00:00:00:01,前三个是固定的,后面三个自己设置,ifname指明虚拟机网卡的名字
[root@centos7 app]#qemu-kvm -name c2 -m 64m -smp 2 -drive file=/app/c2.img,if=virtio,media=disk -vnc :1 -daemonize -net nic,model=e1000,macaddr=52:54:00:00:00:02 -net tap,script=/etc/qemu-ifup,ifname=eth1
[root@centos7 app]#ps aux
[root@centos7 app]#ss -nlt #可以发现5900和5901端口已经打开
[root@centos7 app]#ip a #可以发现虚拟机的网卡有一半也在宿主机上显示
[root@centos7 app]#brctl show #发现两个虚拟机的网卡都连接到虚拟交换机上了
bridge name bridge id       STP enabled interfaces
virbr0      8000.525400c04670   yes     virbr0-nic
vnet0       8000.062ae11d546e   no      eth0
                                        eth1

测试:在两台虚拟主机上配置好ip地址,发现可以相互ping通了,注意配置ip地址时要sudo su root才有权限修改


image.png

示例2:仅主机模式

[root@centos7 app]#ifconfig vnet0 10.0.0.254/24 #将虚拟交换机添加一个ip地址,相当于在宿主机上添加了一个虚拟网卡,这样虚拟机就可以和宿主机通讯了

测试:发现可以ping通了


image.png

在虚拟机上将网关指向宿主机的虚拟网卡地址,就可以和宿主机的真实网卡通讯了,但ping不通外网


image.png

示例3 NAT模式
[root@centos7 app]#cat /proc/sys/net/ipv4/ip_forward #查看是否开启路由功能,如果没有要开启路由功能
1
在宿主机上添加iptables的SNAT规则
[root@centos7 app]#iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j SNAT --to-source 172.18.21.107

此时可以ping通外网了


image.png

总结:半虚拟化:virtio建议:Network IO, Disk IO使用virtio,性能会有显著提升。

6、如何实现给虚拟机自动分配地址

上面测试的时候都是给虚拟主机手动配置的地址,如何能实现自动给它们分配地址呢,需要进行如下操作

[root@centos7 ~]#yum install dnsmasq
[root@centos7 ~]#dnsmasq --listen-address=10.0.0.254,127.0.0.1 --dhcp-range=10.0.0.1,10.0.0.50,48h --dhcp-option=3,10.0.0.254 #48小时指的是地址有效期,--dhcp-option=中的3表示此选项是网关
[root@centos7 ~]#ss -unlp #发现udp的67端口已经监听
[root@centos7 ~]#ps aux #发现dnsmasq进程已经运行

发现可以自动获取ip地址了


image.png

7、将虚拟机的网卡和物理桥桥接,直接就可以和外部通讯

1、创建一个物理桥
[root@centos7 network-scripts]#cp ifcfg-ens37 ifcfg-br0
[root@centos7 network-scripts]#vim ifcfg-br0
DEVICE=br0
DEVICE=br0
TYPE=bridge
IPADDR=172.18.21.107
REFIX=16
GATEWAY=172.18.0.1
DNS1=172.18.0.1
[root@centos7 network-scripts]#vim ifcfg-ens37
DEVICE=ens37
BRIDGE=br0
[root@centos7 network-scripts]#systemctl restart network
[root@centos7 network-scripts]#ip a
[root@centos7 network-scripts]#brctl show
2、修改启动脚本,将虚拟机的网卡和物理桥连接
[root@centos7 network-scripts]#vim /etc/qemu-ifup 
#!/bin/bash
#
bridge=br0
if [ -n "$1" ];then
      ip link set $1 up
      sleep 1
       brctl addif $bridge $1
       [ $? -eq 0 ] && exit 0 || exit 1
else
       echo "no interface specified"
           exit 2
fi
3、启动一个虚拟机实例
[root@centos7 network-scripts]#qemu-kvm -name c2 -m 64m -smp 2 -drive file=/app/c2.img,if=virtio,media=disk -vnc :1 -daemonize -net nic,model=e1000,macaddr=52:54:00:00:00:02 -net tap,script=/etc/qemu-ifup,ifname=eth1
[root@centos7 network-scripts]#ss -nlt
[root@centos7 network-scripts]#ps aux

4、测试
发现直接分配的就是外网的地址,说明将虚拟机的网卡和物理桥连接后直接可以访问外网,不需要设置SNAT地址转换也可以实现,就是将虚拟机的网卡和物理网卡桥接,而物理网卡和物理桥是连接的,vmware workstation中的桥接就是这种模式的


image.png

8、网络名称空间

[root@node3 images]#ip netns add router0 #添加一个网络名称空间
[root@node3 images]#ip netns list
router0
[root@node3 images]#ip link add myeth1 type veth peer name myeth2 #添加一对虚拟网卡,veth代表网卡类型为以太网网卡, peer name表示对端的名字是什么,这一对网卡相当于一根网线的两头
[root@node3 images]#ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:23:75:d6 brd ff:ff:ff:ff:ff:ff
    inet 172.18.21.100/16 brd 172.18.255.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe23:75d6/64 scope link 
       valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:33:fb:70 brd ff:ff:ff:ff:ff:ff
    inet 192.168.25.30/24 brd 192.168.25.255 scope global dynamic ens37
       valid_lft 38162sec preferred_lft 38162sec
    inet6 fe80::250:56ff:fe33:fb70/64 scope link 
       valid_lft forever preferred_lft forever
18: myeth2@myeth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 6e:bb:a2:10:76:6a brd ff:ff:ff:ff:ff:ff
19: myeth1@myeth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether c6:ea:cf:41:60:f6 brd ff:ff:ff:ff:ff:ff
[root@node3 images]#ip link set dev myeth2 netns router0 #将其中一个虚拟网卡加入到新建的名称空间内
[root@node3 images]#ip a
[root@node3 images]#ip a #发现看不到myeth2网卡了,在另外一个空间里了
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:23:75:d6 brd ff:ff:ff:ff:ff:ff
    inet 172.18.21.100/16 brd 172.18.255.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe23:75d6/64 scope link 
       valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:33:fb:70 brd ff:ff:ff:ff:ff:ff
    inet 192.168.25.30/24 brd 192.168.25.255 scope global dynamic ens37
       valid_lft 37776sec preferred_lft 37776sec
    inet6 fe80::250:56ff:fe33:fb70/64 scope link 
       valid_lft forever preferred_lft forever
19: myeth1@if18: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether c6:ea:cf:41:60:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@node3 images]#ip netns exec router0 ip a #只有在此名称空间内才能看到myeth2网卡
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
18: myeth2@if19: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 6e:bb:a2:10:76:6a brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@node3 images]#ip netns exec router0 ip link set dev myeth2 name eth0 #可以修改网卡的名字
[root@node3 images]#ip netns exec router0 ip a 
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
18: eth0@if19: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 6e:bb:a2:10:76:6a brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@node3 images]#ip netns exec router0 ifconfig eth0 10.0.0.200/24 #配置一个ip地址
[root@node3 images]#ip netns exec router0 ip a 
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
18: eth0@if19: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN qlen 1000
    link/ether 6e:bb:a2:10:76:6a brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.0.200/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@node3 images]#ifconfig myeth1 10.0.0.100/24 #给myeth1也配置一个ip地址
[root@node3 images]#ping 10.0.0.200 #发现两者可以互相通讯了
PING 10.0.0.200 (10.0.0.200) 56(84) bytes of data.
64 bytes from 10.0.0.200: icmp_seq=1 ttl=64 time=0.218 ms
64 bytes from 10.0.0.200: icmp_seq=2 ttl=64 time=0.098 ms
64 bytes from 10.0.0.200: icmp_seq=3 ttl=64 time=0.035 ms
^C
--- 10.0.0.200 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.035/0.117/0.218/0.075 ms

总结:在linux系统上构建一个虚拟的网络名称空间后可以当做一个虚拟机来用,并且这个虚拟机和宿主机还可以相互通讯,这个功能属于容器型虚拟化。

9、使用virsh命令管理虚拟机

虚拟机的生成需要依赖于预定义的xml格式的配置文件,其生成工具有两个:virt-manager, virt-install。前面已经展示了如何使用virt-manager图形工具创建虚拟机。

示例:1
[root@centos7 ~]#yum install libvirt-daemon-kvm virt-install qemu-kvm
[root@centos7 app]#systemctl start libvirtd
[root@centos7 app]#systemctl status libvirtd
vim /etc/libvirt/qemu.conf
user = "root"
group = "root"
dynamic_ownership = 0
systemctl restart libvirtd
[root@centos7 app]#virt-install -h
[root@centos7 app]#virt-install -n c1 --vcpus 2 --memory 64 -w bridge=br0 --import --disk /app/c1.img,format=qcow2 --dry-run #创建虚拟机,先干跑一下
[root@centos7 app]#virt-install -n c1 --vcpus 2 --memory 64 -w bridge=br0 --import --disk /app/c1.img,format=qcow2 #正式安装、创建虚拟机,发现是前台运行的
[root@centos7 ~]#ps aux #在打开的一个窗口,查看进程是否已经运行
[root@centos7 ~]#virsh list 
 Id    Name                           State
----------------------------------------------------
 1     c1                             running
[root@centos7 ~]#virsh #发现virsh是一个交互式的命令
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit
virsh # help #查看帮助
virsh # help console #查看各子命令的帮助,注意帮助里面所说的domain指的就是一个虚拟机
virsh # console c1 #连接至虚拟机c1的控制台,要按一下enter键才能进入登录
cirros login: cirros #登录
Password: 
$ sudo su root
$ ip a #可以查看ip
用ctrl+右中括号可以切换回宿主机
virsh # destroy c1 #强行关机,拔电源的方式
virsh # list --all #查看所有的连接和关闭状态的虚拟机
 Id    Name                           State
----------------------------------------------------
 -     c1                             shut off
virsh # start c1 #启动虚拟机
virsh # shutdown c1 #正常关机
[root@centos7 ~]#virsh dumpxml c1 > /app/c2.xml #可以把此虚拟机的
xml文件保存到一个文件中,就可以利用此xml格式的配置文件创建一个
虚拟机了,这样就不用手写xml文件了
[root@centos7 ~]#vim /app/c2.xml 更改配置文件
<domain type='kvm' id='3'> #id
 <name>c2</name>#名字
  <uuid>b5dbf131-790e-4ec4-bd4d-79e875264ca9</uuid> #uuid
 <disk type='file' device='disk'>
 <source file='/app/c2.img'/> #换一个磁盘镜像文件
<mac address='52:54:00:10:b9:e7'/>#mac地址不同冲突
[root@centos7 ~]#virsh create /app/c2.xml --console #利用xml格式的配置文件创建虚拟机,--console指创建后直接连接到控制台,就可以登录了
[root@centos7 ~]#ls /etc/libvirt/qemu #发现前面创建的c1虚拟机的xml格式的配置文件放在此目录下,因此刚才创建的c2虚拟机最好也把c2.xml文件也放到此目录下
c1.xml  networks
virsh # undefine c1 #删除虚拟机
virsh # suspend c1 #将虚拟机暂停于内存中
virsh # resume c1 #从内存中恢复
virsh # save c1 /app/c1.bin #保存虚拟机的当前状态至文件中,相当于vmware workstation中的挂起
virsh # list --all
 Id    Name                           State
----------------------------------------------------
 3     c2                             running
 -     c1                             shut off
virsh # restore /app/c1.bin --running #从文件中恢复
Domain restored from /app/c1.bin
virsh # list
 Id    Name                           State
----------------------------------------------------
 3     c2                             running
 4     c1                             running
[root@centos7 app]#qemu-img create -f qcow2 -o preallocation=metadata,size=10G /app/c4.img #创建一个磁盘镜像文件
[root@centos7 app]#qemu-img info /app/c4.img 
image: /app/c4.img
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 2.2M
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
[root@centos7 app]#virsh help attach-disk 
[root@centos7 app]#virsh attach-disk c1 /app/c4.img vda #给虚拟机插入一块硬盘,支持热插拔
Disk attached successfully
[root@centos7 app]#virsh domblklist c1
Target     Source
------------------------------------------------
hda        /app/c1.img #hda时IDE硬盘,在这里不支持热插拔
vda        /app/c4.img #注意vda格式的是半虚拟化的支持热插拔
[root@centos7 app]#virsh detach-disk c1 /app/c4.img  #拆除硬盘
Disk detached successfully

[root@centos7 app]#virsh domblklist c1
Target     Source
------------------------------------------------
hda        /app/c1.img
[root@centos7 app]#virsh domiflist c1
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet0      bridge     br0        rtl8139     52:54:00:11:b9:e5

[root@centos7 app]#virsh attach-interface c1 bridge br0  #也支持网络即接口的热插拔, 注意 :无须事先创建网络接口设备,会自动创建
Interface attached successfully

[root@centos7 app]#virsh domiflist c1
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet0      bridge     br0        rtl8139     52:54:00:11:b9:e5
vnet2      bridge     br0        rtl8139     52:54:00:e1:8c:dc
[root@centos7 app]#virsh detach-interface c1 bridge --mac 52:54:00:e1:8c:dc #热拆除网络接口
Interface detached successfully

图形管理工具:
kimchi:基于H5研发web GUI; virt-king;
OpenStack: IaaS
oVirt:

推荐阅读更多精彩内容