虚拟化:LXC, KVM

一,虚拟化:LXC容器,KVM

1,相关概念

Container:容器,基于容器的虚拟化技术起源于所谓的资源容器和安全容器。
(linux:OpenVZ,linux-VServer,FreeVPS.非linux:Solaris Zones,BSD jails,CoreOS,Dejs,Dynos,Docker)
LXC:linux Container.
LXC开源项目(sourceforge):项目本身只是一个为用户提供一个用户空间的工具集,用来使用和管理LXC容器。
LXC真正的实现则是靠Linux内核的相关特性,LXC项目只是对此做了整合。
LXC由下列两个技术组成:
1,资源管理方面依赖于Linux内核的cgroups子系统,cgroups子系统是Linux内核提供的一个基于进程组的资源管理的框架,
可以为特定的进程组限定可以使用的资源。

2,LXC在隔离控制方面依赖于Linux内核的namespace特性,具体而言就是在clone时加入相应的flag(NEWNS NEWPID等等)。

2,LXC管理

用户空间两类管理工具集: liblxc,libvirt
libvirt是Linux上的虚拟化库,是长期稳定的C语言API,支持KVM/QEMU、Xen、LXC等主流虚拟化方案。

2.1,liblxc工具集:

1,liblxc 工具包: yum install lxc (lxc-devel,lxc-libs,lxc-doc,lxc-templates,lxc-extra,python3-lxc,lua-lxc)
2,iproute2 工具包:管理网络接口。yum install iproute (iproute-devel,iproute-doc)
3,如何配置网络: 如:桥接
a.创建一个桥
b.将已有的网络接口添加到桥
4,如何填充一个容器文件系统:除了网络外,容器通常还需要自己的文件系统。(生成chroot环境)
多种填充容器文件系统的方法:
a,构建定制的 Debian 容器;debootstrap sid rootfs http://debian.osuosl.org/debian/
b,运行 ssh 容器
5,如何连接到容器文件系统
a,SSH ;(可以创建一个SSH容器)
b,VNC(GUI);Virtual Network Computing,可以为容器增加一个gui
启动时创建:echo '/usr/bin/vnc4server :0 -geometry 1024x768 -depth 24' >> rootfs/etc/rc.local
连接:vncviewer <ip>:<display>
c,VT: tty(文本);linux virtual terminals;与宿主共享tty.
echo '8:2345:respawn:/sbin/getty 38400 tty8' >> rootfs/etc/inittab
d,VT:X (GUI)
通过 VT: X 连接 让您可以运行一个 GUI。在 VT 9 上运行 GNOME Display Manager(gdm),
然后编辑 rootfs/usr/share/gdm/defaults.conf,将 FirstVT=7 替换为 FirstVT=9,
以及将 VTAllocation=true 替换为 VTAllocation=false。
lxc对象(虚拟机)存放目录:/var/lib/lxc/
lxc缓存目录:/var/cache/lxc/
配置文件样例:/usr/share/lxc/template/

2.2,LXC 工具命令:

1,创建容器:创建容器就是将一个名称与一个配置文件关联起来。该名称将用于管理容器:
lxc-create -n name -f configfile(配置文件样例:/usr/share/lxc/templates/lxc-fedora)
如:运行 lxc-sshd 脚本(该脚本创建一个配置)之后,ssh 容器配置如下所示:
lxc.utsname = my_ssh_container
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 10.0.2.16/24
lxc.network.name = eth0
lxc.mount = ./fstab
lxc.rootfs = ./rootfs
2,获得(或列出)关于已有容器的信息
显示一个容器的状态:lxc-info -n name
显示属于一个容器的进程:lxc-ps
3,启动系统和应用程序容器
LXC容器分两种类型:
1,系统容器,系统容器类似于虚拟机。与真正的虚拟化相比,虽然它们的隔离性要低一些,但是开销也降低了。
直接原因是每个容器使用相同的 Linux 内核。为了类似于虚拟机,系统容器和 Linux发行版一样在同一个地方启动,
即通过运行 init 程序:lxc-start -n name init
2,应用程序容器。应用程序容器只是创建用于隔离一个应用程序的单独的名称空间。
启动一个应用程序容器:lxc-execute -n name cmd
4,向容器中运行的进程发信号:
将一个信号发送到在一个容器中运行的所有进程:lxc-kill -n name -s SIGNAL
5,暂停、恢复、停止和销毁容器
暂停(冻结):lxc-freeze -n name
恢复:lxc-unfreeze -n name
停止:lxc-stop -n name
销毁(删除与名称关联的配置文件和元数据):lxc-destroy -n name
6,杂项:
查看和调整容器的优先级:
lxc-priority -n name
lxc-priority -n name -p priority
持续观察容器的状态和优先级变化:
lxc-monitor -n name
持续观察容器的状态和优先级变化:
lxc-monitor -n name
还可以等待容器进入以一组状态之一:
lxc-wait -n name -s 'STOPPED|STARTING|STOPPING|ABORTING|FREEZING|FROZEN'

用于显示系统LXC的版本号:lxc-version
判断linux内核是否支持LXC:lxc-checkconfig
创建一个容器: lxc-create -n name [-f config_file]
在一个容器执行应用程序: lxc-execute -n name [-f config_file] [ -s KEY=VAL ]command
容器中执行给定命令: lxc-start -n name [-f config_file] [-c console_file] [-d] [-s KEY=VAL] [command]
获取一个容器的状态: lxc-info -n name
列出当前系统所有的容器: lxc-ls 
列出特定容器中运行的进程: lxc-ps 
监控一个容器状态的变换: lxc-monitor -n name
获取一个容器的状态: lxc-info -n name
获取或调整与cgroup相关的参数:lxc-cgroup -n name subsystem value 
如: lxc-cgroup -n foo devices.list
lxc-cgroup -n foo cpuset.cpus "0,3"
发送信号给容器中用户进程: lxc-kill -n name SIGNUM
停止容器中所有的进程: lxc-stop -n name
销毁容器: lxc-destroy -n name

2.3,libvirt: 默认为KVM+qemu;(配置文件目录:/etc/libvirt/ ) 

官网:http://libvirt.org/drvlxc.html
安装包:yum install libvirt-client virt-viewer virt-manager
a,图形界面接口的管理工具:virt-manager
b,字符界面接口的管理工具:virsh(命令行工具)
virsh list                                #显示本地活动虚拟机
virsh list –all                           #显示本地所有的虚拟机(活动的+不活动的)
virsh define fedora-configuration.xml     #通过配置文件定义一个虚拟机(这个虚拟机还不是活动的)
virsh start fedora                        #启动名字为fedora的非活动虚拟机
virsh create fedora.xml                   # 创建虚拟机(创建后,虚拟机立即执行,成为活动主机)
virsh suspend fedora                      # 暂停虚拟机
virsh resume fedora                       # 启动暂停的虚拟机
virsh shutdown fedora                     # 正常关闭虚拟机
virsh reboot  fedora # 重启虚拟机
virsh destroy fedora                      # 强制关闭虚拟机
virsh dominfo fedora                      #显示虚拟机的基本信息
virsh domname 2                           # 显示id号为2的虚拟机名
virsh domid fedora                        # 显示虚拟机id号
virsh domuuid fedora                      # 显示虚拟机的uuid
virsh domstate fedora                     # 显示虚拟机的当前状态
virsh dumpxml fedora                      # 显示虚拟机的当前配置文件(可以保存,以便用来创建虚拟机)
(可能和定义虚拟机时的配置不同,因为当虚拟机启动时,需要给虚拟机分配id号、uuid、vnc端口号等等)
virsh setmem fedora 512000           #给不活动虚拟机设置内存大小
virsh setvcpus fedora 4                   # 给不活动虚拟机设置cpu个数
virsh attach-device  name config.xml#给虚拟机添加设备
如:guest_device.xml:
<disk type='block' device='cdrom'>
 <driver name='qemu' type='raw'/>
 <target dev='hdc' bus='ide'/>
 <readonly/>
 <alias name='ide0-1-0'/>
 <address type='drive' controller='0' bus='1' unit='0'/>
</disk>
#virsh update-device guestname guest_device.xml
Device updated successfully
virsh attach-disk  #给虚拟机添加磁盘
如:# virsh attach-disk guestname sample.iso hdc --type cdrom --mode readonly
Disk attached successfully
virsh attach-interface#给虚拟机添加网络接口
virsh edit fedora                         # 编辑配置文件(一般是在刚定义完虚拟机之后)
virsh connect xen+ssh://[email protected]  #连接远程libvirt(默认为本地qumu虚拟机qemu:///system)
virsh –c xen+ssh://[email protected] list --all  #连接并执行远程命令
virsh connect name or url

3,网络虚拟:为容器虚拟一个网络接口;

3.1,使用工具完成(yum install bridge-utils)

brctl addbr br0 ; #创建一个名为br0 的桥
brctl setfd br0 0 ; #设置桥的转发廷迟时间
ifconfig br0 10.0.2.15 promisc up;#用一个已有网络接口中的IP(在本例中是 10.0.2.15)连接到桥接口
brctl addif br0 eth0;#将已有的网络接口(在本例中是 eth0)添加到桥,并取消它与它的 IP 地址的直接关联
ifconfig eth0 0.0.0.0 up;   (任何添加到桥 br0 的接口都将对那个 IP 地址作出响应)
route add -net default gw 10.0.2.2 br0;确保默认的路由
创建完成后可以给容器用(修改容器的配置文件)
lxc.network.type=veth
lxc.network.flags=up
lxc.network.link=br0
lxc.network.ipv4=10.20.153.234/24 #可以不写
lxc.network.hwaddr=4a:49:43:49:79:bd

3.2,直接修改网络配置文件

cat /etc/sysconfig/network-scripts/ifcfg-br0:
DEVICE=br0
TYPE=Bridge
BOOTPROTO=static
BROADCAST=10.1.255.255
IPADDR=10.1.29.4
NETMASK=255.255.0.0
NETWORK=10.1.0.0
GATEWAY=10.1.0.254
ONBOOT=yes


cat /etc/sysconfig/network-scripts/ifcfg-eth1:
# Realtek Semiconductor Co., Ltd. RTL8101E/RTL8102E PCI Express Fast Ethernet controller
DEVICE=eth1
#BOOTPROTO=static
HWADDR=E0:CB:4E:B9:EB:77
#TYPE=Ethernet
#IPADDR=10.1.29.4
#NETMASK=255.255.0.0
#NETWORK=10.1.0.0
#GATEWAY=10.1.0.254
#USERCTL=no
#IPV6INIT=no
#PEERDNS=yes
ONBOOT=yes
BRIDGE=br0

4,LXC使用步骤:

4.1,创建LXC应用程序容器

1,安装用户态工具(从2.6.29开始,内核层已支持),yum install lxc
2,检查内核是否支持;lxc-checkconfig
3, 在主机上创建并挂载cgroup;(fedora已自动挂载)
mkdir /cgroup
mount none -t cgroup /cgroup
echo "none /cgroup cgroup defaults 0 0" >>/etc/fstab

4,配置桥接网络 ;
(使用brctl工具,也可直接修改接口配置文件,)
5,为容器创建配置文件;
如:此例保存为 /var/lib/lxc/lxc_test.conf
lxc.utsname = test
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:bd
lxc.network.ipv4 = 192.168.250.150
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596

6,开启封闭的运行进程(此例为开启一个封闭shell)  
lxc-execute -n test -f /var/lib/lxc/lxc_test.conf /bin/bash  #宿主机test已经存在就不用指定配置文件
(此时即进入一个封闭的shell环境,可以与远程机相互ping通,并与主机共享文件系统,

但是有一个隔离的进程空间,可以ps ax查看与主机的输出不同。在主机上可以查看此容器的状态:lxc-info -n test;lxc-ps)


4.2,创建LXC系统容器;(主机内核启动参数要添加: audit=0)

1,可以使用已存在的操作系统模板去创建LXC系统容器:(templates privides by the OpenVZ project) (注:为了防止创建的系统容器无法登录,需关闭主机系统的audit,禁止掉容器中xx/pam.d/login中的pam_loginuid.so)
下载相应的模板:http://wiki.openvz.org/Download/template/precreated
使用OpenVZ容器:
1.1,解压模板(根文件系统);
#mkdir -p /srv/lxc/lxctest  #创建容器所在的目录(根目录)
#cd /srv/lxc/lxctest
#tar xvzf fedora-19-x86_64.tar.gz (根文件系统)
1.2,创建配置文件;
#cat /etc/lxc/lxc-fedora.conf
lxc.rootfs = /srv/lxc/lxctest        #指定根文件系统目录
lxc.mount = /etc/lxc/lxc-fedora.fstab    #挂载表
lxc.utsname = fedora     #设置容器名
lxc.network.type=veth     #在此设置网络
lxc.network.flags=up
lxc.network.link=br0
lxc.network.name=eth0
lxc.network.hwaddr=4a:49:43:49:79:bd
lxc.network.ipv4=192.168.1.156  #使用DHCP时为:0.0.0.0
   //以下为可选
lxc.tty = 4
lxc.pts = 1024
lxc.cap.drop = sys_module mac_admin mac_override sys_time
lxc.autodev = 1
# When using LXC with apparmor, uncomment the next line to run unconfined:
#lxc.aa_profile = unconfined
#cgroups
lxc.cgroup.devices.deny = a
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# rtc
lxc.cgroup.devices.allow = c 254:0 rm
1.3,创建挂载表:
#cat/etc/lxc/lxc-fedora.fstab
none /srv/lxc/lxctest/dev/pts devpts defaults 0 0
none /srv/lxc/lxctest/proc    proc   defaults 0 0
none /srv/lxc/lxctest/sys     sysfs  defaults 0 0
1.4,创建初始化容器;
lxc-create -n fedora -f /etc/lxc/lxc-fedora.conf
删除容器对象:lxc-destory -n fedora  (不会删除实际的文件系与配置文件)
1.5,修改容器内网络(因为根文件系统是OpenVZ的)
cat /srv/lxc/lxctest/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0 //跟1.2配置文件中一致
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.1.156
NETMASK=255.255.255.0
BROADCAST=192.168.1.255
1.6,调整设置根文件系统
#chroot /srv/lxc/lxctest #进入容器
#useradd user   #给容器添加用户
#passwd user
#chkconfig --list|grep '3:on'#确定开启哪些服务,关闭哪些服务
#chkconfig httpd off
#chkconfig saslauthd off
#rm /etc/mtab #修复mtab表
#touch /etc/mtab
1.7,设置完成,可以启动
lxc-start -n fedora
lxc-stop -n fedora
2,LXC也提供了几个脚本工具去创建相应的系统空器:
lxc-fedora lxc-debian lxc-busybox lxc-ubuntu lxc-oracle lxc-sshd lxc-alpine
所有这些脚本工具都会下载一个最小的安装和交互设置容器;
2.1:指定install 参数运行,如:
#/usr/share/lxc/templates/lxc-fedora install  #会在/var/lib/lxc/目录下生成config,fstab配置文件,rootfs根目录
2.2,在此配置文件config,fstab,和根文件系统rootfs基础上创建,修改,运行LXC容器(如上)

4.3,使用systemd包中systemd-nspawn工具

1,安装一个系统容器(容器根目录文件系统)
#yum -y --releasever=19 --nogpg --installroot=/home/lxc --disablerepo='*' --enablerepo=fedora install systemd passwd yum fedora-release vim-minimal
2,设置容器root密码
#systemd-nspawn -D /home/lxc  #切换根目录到容器根目录 (把容器中/etc/pam.d/login文件中pam_loginuid注释掉)
#passwd
3,启动容器(主机内核启动参数要添加audit=0)
#systemd-nspawn -bD /home/lxc 3
4,为此容器制作一个服务单元(systemd的unit)
cat /etc/systemd/system/mycontainer.service
[Unit]
Description=My test container
[Service]
ExecStart=/usr/bin/systemd-nspawn -jbD /home/lxc 3
KillMode=process

5,重启systemd
#systemctl daemon-reload       #重启systemd
#systemctl start mycontainer    #启动容器  (在后台运行容器)
#systemctl stop mycontainer    #停止容器

4.4,使用libvirt 管理LXC:   

(默认uri为qumu:///system,KVM虚拟机,export LIBVIRT_DEFAULT_URI=lxc:///)

例:# cat helloworld.xml (配置文件)
<domain type='lxc'>
 <name>helloworld</name>
 <memory>102400</memory>
 <os>
<type>exe</type>
<init>/bin/sh</init>
 </os>
 <devices>                  #指定容器中的设备
<console type='pty'/>  
<filesystem type='mount'>       #可以指定需要挂载的文件系统和目录(此处是挂了一个根目录)
 <source dir='/export/helloword/root'/>
 <target dir='/'/>
</filesystem>
<interface type='network'>
 <mac address='52:54:00:4d:2b:cd'/>
 <source network='default'/>
</interface/>
 </devices>
</domain>

1,定义或创建domain:
# virsh --connect lxc:/// define helloword.xml
Domain helloword defined from helloword.xml
创建虚拟机:virsh create helloword.xml
2,启动:# virsh --connect lxc:/// start helloword   
Domain helloword started
3,连到虚拟机中:
# virsh --connect lxc:/// console helloword
Connected to domain helloword
4,取消定义:virsh -c lxc:/// undefine helloword
5,销毁:virsh -c lxc:/// destroy helloword


kvm:  

内核 kvm.ko  +用户态管理工具: yum install libvirt-client virt-viewer virt-manager

pci 设备passthrough
1,BIOS下使能intel VT-d 或AMD IOMMU
2,在内核中使能 激活 intel VT-d
grub.cfg  中kernel行后添加启动参数:intel_iommu=on
3,重启系统
3.1,列出当前机上所有设备:
# virsh nodedev-list --tree
3.2,查看设备的域,总线,插槽,功能号等信息:
# virsh nodedev-dumpxml pci_0000_00_0f_0
<device>
 <name>pci_0000_00_0f_0</name>
 <parent>computer</parent>
 <driver>
<name>vmwgfx</name>
 </driver>
 <capability type='pci'>
<domain>0</domain>
<bus>0</bus>
<slot>15</slot>
<function>0</function>
<product id='0x0405'>SVGA II Adapter</product>
<vendor id='0x15ad'>VMware</vendor>
 </capability>
</device>
3.3,与主机断开连接(detach from the system)
# virsh nodedev-dettach pci_0000_00_0f_0
3.4,给客户机添加一个设备(3.2中查询的设备域,总线,插槽,功能号信息);不支持热插拨
# virsh edit win2k3   (domain,客户机名;在<devices>段添加一个设备项)
<hostdev mode='subsystem' type='pci' managed='yes'>
 <source>
 <address domain='0x0000' bus='0x00' slot='0x1a' function='0x7'/>
 </source>
</hostdev>
3.5,当客户机启来后,要通知主机不能使用它;
$ readlink /sys/bus/pci/devices/0000\:00\:1d.7/driver
../../../bus/pci/drivers/drivername
3.6,与设备断开连接
$ virsh nodedev-dettach pci_8086_3a6c
3.7,验证现在在pci_stub的控制下:
$ readlink /sys/bus/pci/devices/0000\:00\:1d.7/driver
../../../bus/pci/drivers/pci-stub
3.8,设置sebool来让客户机管理pci设备
$ setsebool -P virt_manage_sysfs 1
3.9,启动客户机
# virsh start win2k3
连接虚拟机:
connect qemu+ssh://virtuser@host2/    #用SSH连接,
connect qemu://host2/                       #用TLS连接

你可能感兴趣的:(虚拟化:LXC, KVM)