若是CPU支持,還須要在BIOS打開虛擬化支持。一般,主板默認關閉這個選項。html
kvm-ok # 或 grep -E "vmx|svm" /proc/cpuinfo # Intel CPU:vmx # AMD CPU:svm
使用libvirt負責虛擬化的建立及管理。node
# Ubuntu sudo apt-get -y install qemu-kvm qemu-utils libvirt-bin pm-utils virtinst sudo apt-get -y install virt-viewer virt-manager # CentOS yum install -y qemu-kvm qemu-kvm-tools libvirt libvirt-devel libvirt-client pm-utils yum install -y virt-viewer virt-manager
# Ubuntu中解依編譯信賴關係 sudo apt-get build-dep qemu-kvm tar -xzvf qemu-kvm-1.2.0.tar.gz cd qemu-kvm-1.2.0 /configure --prefix=/usr/local/kvm make sudo make install # 安裝後加載KVM模塊 # 注意:系統重啓後要從新加載kvm內核模塊,從源安裝時會有qemu-kvm服務來自動加載該模塊。 sudo modprobe kvm sudo modprobe kvm-intel #INTEL處理器就用這個 sudo modprobe kvm-amd #AMD處理器就用這個
start_libvirtd="yes" libvirtd_opts="-d -l"
listen_tls = 0 # 禁用tls listen_tcp = 1 # 啓用tcp偵聽 tcp_port = "16509" # tcp端口 listen_addr = "0.0.0.0" # tcp偵聽IP auth_unix_ro = "none" auth_unix_rw = "none" auth_tcp = "sasl" # tcp登陸認證方式,"none"爲不使用認證 log_level = 3 log_outputs="3:syslog:libvirtd" max_clients = 1024 # 最大總的鏈接客戶數1024 min_workers = 50 # libvirtd啓動時,初始的工做線程數目 max_workers = 200 # 同上,最大數目 max_requests = 1000 # 最大同時支持的RPC調用,必須大於等於max_workers max_client_requests = 200 # 每一個客戶端支持的最大鏈接數
apt-get install sasl2-bin sed -i 's/\(^START\)=.*$/\1=yes/g' /etc/default/saslauthd
# 添加用戶 saslpasswd2 -a libvirt yuanxing #列出用戶 sasldblistusers2 -f /etc/libvirt/passwd.db # yuanxing@kvmsrv: userPassword,注意:登陸時用戶名要包含@kvmsrv #刪除用戶 saslpasswd2 -a libvirt -d yuanxing
sed -i -e '/^vnc_listen/d' i-e '/^vnc_password/d' /etc/libvirt/qemu.conf echo 'vnc_listen = "0.0.0.0"' >> /etc/libvirt/qemu.conf echo 'vnc_password = "XYZ12345"' >> /etc/libvirt/qemu.conf
service libvirt-bin start|restart|stop|status|reload|force-reload service qemu-kvm start|restart|stop|status|reload|force-reload
sudo apt-get -y install bridge-utils
使用ifplugd方便向桌面發送狀態通知、經過異步處理加快啓動速度(dhcp浪費時間)。python
使用vde2使用多是方便以普通用戶身份來管理(UserModeLinux,涉及到uml工具)?linux
auto lo iface lo inet loopback auto virbr1 iface virbr1 inet static address 172.17.20.20 network 172.17.20.0 netmask 255.255.255.0 broadcast 172.17.20.255 gateway 172.17.20.1 dns-nameservers 8.8.8.8 4.4.4.4 bridge_ports eth0 bridge_stp on bridge_maxwait 0
sudo stop network-manager # Create an override file for the upstart job: echo "manual" | sudo tee /etc/init/network-manager.override
net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0
sysctl -p /etc/sysctl.conf
<network> <name>default</name> <uuid>3be6d4fa-72c4-667b-64ae-85f954f1b2bf</uuid> <forward mode='nat'/> <bridge name='virbr0' stp='on' delay='0' /> <mac address='52:54:00:D6:A2:9B'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.2' end='192.168.122.254' /> </dhcp> </ip> </network>
<network> <name>network-host-bridge</name> <uuid>3b8bf95c-6971-8794-1c63-bc2b8c551979</uuid> <forward mode='bridge'/> <bridge name='virbr1' /> </network>
virsh net-list --all #virsh net-define default.xml virsh net-define network-host-bridge.xml virsh net-start network-host-bridge virsh net-autostart network-host-bridge # virsh net-dumpxml network-host-bridge > /etc/libvirt/qemu/network/network-host-bridge.xml
<interface type='network'> <mac address='52:54:00:6c:07:87'/> <source network='network-host-bridge'/> <target dev='vnet0'/> <model type='virtio'/> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface>
<interface type='bridge'> <mac address='52:54:00:6c:07:87'/> <source bridge='virbr1'/> <target dev='vnet0'/> <model type='virtio'/> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface>
# Generated by iptables-save v1.4.12 on Sat Dec 14 01:24:40 2013 *nat :PREROUTING ACCEPT [310:34187] :INPUT ACCEPT [41:4149] :OUTPUT ACCEPT [471:31957] :POSTROUTING ACCEPT [711:59731] -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535 -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535 -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE COMMIT # Completed on Sat Dec 14 01:24:40 2013 # Generated by iptables-save v1.4.12 on Sat Dec 14 01:24:40 2013 *mangle :PREROUTING ACCEPT [789078:428240757] :INPUT ACCEPT [381196:51105050] :FORWARD ACCEPT [407928:377150708] :OUTPUT ACCEPT [399811:110095092] :POSTROUTING ACCEPT [807739:487245800] -A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill COMMIT # Completed on Sat Dec 14 01:24:40 2013 # Generated by iptables-save v1.4.12 on Sat Dec 14 01:24:40 2013 *filter :INPUT ACCEPT [381157:51098101] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [399811:110095092] -A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT -A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT -A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT -A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT -A INPUT -i virbr1 -p udp -m udp --dport 53 -j ACCEPT -A INPUT -i virbr1 -p tcp -m tcp --dport 53 -j ACCEPT -A INPUT -i virbr1 -p udp -m udp --dport 67 -j ACCEPT -A INPUT -i virbr1 -p tcp -m tcp --dport 67 -j ACCEPT -A FORWARD -d 192.168.122.0/24 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT -A FORWARD -i virbr0 -o virbr0 -j ACCEPT -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr1 -o virbr1 -j ACCEPT -A FORWARD -o virbr1 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr1 -j REJECT --reject-with icmp-port-unreachable COMMIT # Completed on Sat Dec 14 01:24:40 2013
/usr/sbin/dnsmasq \ -u libvirt-dnsmasq \ --strict-order \ --bind-interfaces \ --pid-file=/var/run/libvirt/network/default.pid \ --conf-file= \ --except-interface lo \ --listen-address 192.168.122.1 \ --dhcp-range 192.168.122.2,192.168.122.254 \ --dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \ --dhcp-lease-max=253 \ --dhcp-no-override
virsh virt-install virt-manager virt-clone virt-convert virt-image qeum-img
virsh -c qemu:///system # 本地登陸libvirt控制檯 virsh -c qemu+ssh://root@172.17.20.20/system # ssh遠程登陸libvirt控制檯 virsh -c qemu+tcp://172.17.20.20:16509/system # tcp遠程登陸libvirt控制檯 virt-manager -c qemu+tcp://172.17.20.20:16509/system # 運行libvirt圖形管理界面 virt-manager -c qemu+ssh://root@172.17.20.20/system
<pool type='dir'> <name>data</name> <uuid>117251c7-3444-a5e3-3174-1947c4933321</uuid> <capacity>446342758400</capacity> <allocation>7004667904</allocation> <available>439338090496</available> <source> </source> <target> <path>/data/libvirt/images</path> <permissions> <mode>0700</mode> <owner>-1</owner> <group>-1</group> </permissions> </target> </pool>
<pool type='dir'> <name>ISOs</name> <uuid>e77d9811-5497-521d-0d50-e5104c7e66b1</uuid> <capacity>446342758400</capacity> <allocation>7004667904</allocation> <available>439338090496</available> <source> </source> <target> <path>/data/ISOs</path> <permissions> <mode>0700</mode> <owner>-1</owner> <group>-1</group> </permissions> </target> </pool>
virsh pool-list Name State Autostart ----------------------------------------- data active yes ISOs active yes
使用 virt-manager -c qemu+ssh:///system
遠程鏈接libvirtd後,在圖形界面中建立了第一個虛擬機Ubuntu,並安裝了操做系統。ubuntu
<domain type='kvm' id='2'> <name>Ubuntu</name> <uuid>d2a37ea8-d343-c4bd-c6d0-fb6bd1943f91</uuid> <memory>1048576</memory> <currentMemory>1048576</currentMemory> <vcpu>2</vcpu> <os> <type arch='x86_64' machine='pc-1.0'>hvm</type> <boot dev='cdrom'/> <boot dev='hd'/> </os> <features> <acpi/> <apic/> <pae/> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>destroy</on_reboot> <on_crash>destroy</on_crash> <devices> <emulator>/usr/bin/kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/data/libvirt/images/Ubuntu.img'/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </disk> <disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/data/ISOs/ubuntu-12.04.3-server-amd64.iso'/> <target dev='hdc' bus='ide'/> <readonly/> <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> <controller type='ide' index='0'> <alias name='ide0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <interface type='bridge'> <mac address='52:54:00:6c:07:87'/> <source bridge='virbr1'/> <target dev='vnet0'/> <model type='virtio'/> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <serial type='pty'> <source path='/dev/pts/1'/> <target port='0'/> <alias name='serial0'/> </serial> <console type='pty' tty='/dev/pts/1'> <source path='/dev/pts/1'/> <target type='serial' port='0'/> <alias name='serial0'/> </console> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5900' autoport='yes'/> <video> <model type='cirrus' vram='9216' heads='1'/> <alias name='video0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </video> <memballoon model='virtio'> <alias name='balloon0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </memballoon> </devices> <seclabel type='dynamic' model='apparmor' relabel='yes'> <label>libvirt-d2a37ea8-d343-c4bd-c6d0-fb6bd1943f91</label> <imagelabel>libvirt-d2a37ea8-d343-c4bd-c6d0-fb6bd1943f91</imagelabel> </seclabel> </domain>
# 進程以libvirt-qemu用戶身份運行 /usr/bin/kvm \ -S \ -M pc-1.0 \ -enable-kvm \ -m 1024 \ -smp 2,sockets=2,cores=1,threads=1 \ -name Ubuntu \ -uuid d2a37ea8-d343-c4bd-c6d0-fb6bd1943f91 \ -nodefconfig \ -nodefaults \ -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/Ubuntu.monitor,server,nowait \ -mon chardev=charmonitor,id=monitor,mode=control \ -rtc base=utc \ -no-reboot \ -no-shutdown \ -drive file=/data/libvirt/images/Ubuntu.img,if=none,id=drive-virtio-disk0,format=qcow2 \ -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=2 \ -drive file=/data/ISOs/ubuntu-12.04.3-server-amd64.iso,if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw \ -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0,bootindex=1 \ -netdev tap,fd=19,id=hostnet0,vhost=on,vhostfd=20 \ -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:6c:07:87,bus=pci.0,addr=0x3 \ -chardev pty,id=charserial0 \ -device isa-serial,chardev=charserial0,id=serial0 \ -usb \ -vnc 127.0.0.1:0 \ -vga cirrus \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
sh -c if nc -q 2>&1 | grep "requires an argument" >/dev/null 2>&1; then ARG=-q0;else ARG=;fi;nc $ARG -U /var/run/libvirt/libvirt-sock nc -q0 -U /var/run/libvirt/libvirt-sock nc -q 0 127.0.0.1 5900
使用vmbuilder建立Ubuntu JeOS虛擬服務器,包括虛擬機建立、系統安裝、包安裝,以及系統設置定製都可一步完成。vim
apt-get instal python-vm-builder
vmbuilder --help
vmbuilder kvm ubuntu --help
Vmbuilder缺省對網卡啓用了virtio特性,但虛擬磁盤未啓用virtio特性,可修改其配置檔解決:api
vim /etc/vmbuilder/libvirt/libvirtxml.tmpl <target dev='hd$disk.devletters()' /> # to <target dev='vd$disk.devletters()' bus='virtio' />
Since my virtual machines require a pointopoint entry in /etc/network/interfaces I also edit /etc/vmbuilder/ubuntu/interfaces.tmpl and add an additional line pointopoint underneath gateway. This will set pointopoint to the gateway address that I specify with vmbuilder.安全
pointopoint $gw
As a last ugly rather hack I edit /usr/share/pyshared/VMBuilder/plugins/kvm/vm.py and change the default file image type from qcow2 to raw to improve the disk throughput.bash
filetype = 'raw'
Instead of editing vm.py you could also use the qemu-img command after running vmbuilder to convert the qcow2 image to raw (or just keep qcow2 if you are fine with it).服務器
[DEFAULT] arch=amd64 mem=512 cpus=2 ip=172.17.20.31 gw=172.17.20.1 mask=255.255.255.0 dns=8.8.8.8 user=yuanxing name=YuanXing pass=123456 tmpfs=- firstboot=/data/libvirt/JeOStemplate/firstboot.sh #firstlogin=/data/libvirt/JeOStemplate/firstlogin.sh #bridge=virbr1 network=network-host-bridge [ubuntu] mirror=http://mirrors.163.com/ubuntu iso=/data/ISOs/ubuntu-12.04.3-server-amd64.iso suite=precise flavour=virtual hostname=JeOS addpkg=openssh-server,acpid,vim,at,bc,byobu,tmux,screen,iptables [kvm] libvirt = qemu:///system
# This script will run the first time the virtual machine boots # It is ran as root. echo "Expire the user account" passwd -e user echo "Regenerate ssh keys" rm -f /etc/ssh/ssh_host*key* dpkg-reconfigure -fnoninteractive -pcritical openssh-server
# This script is ran the first time a user logs in echo "Your appliance is about to be finished to be set up." echo "In order to do it, we'll need to ask you a few questions," echo "starting by setting you keyboard and other console informations."
# ubuntu 12.04中vmbuilder的cli.py中對part的處理存在bug,不能正確按man中的格式處理設備名和文件名,由於只能使用以下簡單格式 root 8000 swap 4000 --- /data 20000
vim +391 /usr/lib/python2.7/dist-packages/VMBuilder/contrib/cli.py
sudo vmbuilder kvm ubuntu -c MyJeOS.cfg --part vmbuilder.partition --timezone=CST -d /data/libvirt/images/JeOS # 或者直接在命令行中指定參數 sudo vmbuilder kvm ubuntu --suite precise --flavour virtual --arch amd64 --libvirt qemu:///system \ --hostname gonzo --ip 192.0.32.9 --net 192.0.32.9 --mask 255.255.255.255 --bcast 192.0.32.9 --gw 213.103.105.1 \ --domain example.com --user john --name john --pass 12345 \ --verbose --rootsize=20480 --swapsize=2048 --mem 1024 --cpus 1 \ --addpkg=openssh-server --addpkg=vim --addpkg=acpid \ --dest=/var/lib/libvirt/images/gonzo/
virt-install --name=Ubuntu2 --ram 1024 --vcpus=2 \ --disk pool=data,size=8,bus=virtio,format=qcow2,sparse=false,cache=writeback \ --cdrom /data/ISOs/ubuntu-12.04.3-server-amd64.iso \ --vnc --network bridge=virbr1,model=virtio --noautoconsole \ --connect=qemu:///system # 或用網絡名稱: # --network network=network-host-bridge
說明:在linux系統安裝開始就要注意添加提升性能的一些參數,後面就不須要作一些調整了。
參數說明:
--name 指定虛擬機名稱 --ram 分配內存大小 --vcpus 分配CPU核心數,最大與實體機CPU核心數相同 --disk 指定虛擬機鏡像,size 指定分配大小單位爲G。 --network 網絡類型,此處用的是默認,通常用的應該是 bridge 橋接。 --cdrom 指定安裝鏡像iso --vnc 啓用VNC遠程管理,通常安裝系統都要啓用。 --vncport 指定VNC 監控端口,默認端口爲5900,端口不能重複。 --vnclisten 指定VNC 綁定IP,默認綁定127.0.0.1,這裏改成 0.0.0.0。 --noautoconsole Don't automatically try to connect to the guest console
virsh -c qemu:///system vol-clone --pool data tmpiEMBDQ.qcow2 JeOS_2.qcow2
--connect=CONNECT -o ORIGINAL_GUEST , --original=ORIGINAL_GUEST 被克隆的原始Guest名稱 -m MAC , --mac=MAC MAC地址 --auto-clone, Generate a new guest name, and paths for new storage. -n NAME , --name=NAME 新虛擬機Guest的名稱 -u UUID , --uuid=UUID 指定UUID -f DISKFILE , --file=DISKFILE
# 將JeOS克隆爲指定NAME,按--file指定路徑Clone虛擬磁盤。 NAME=JeOS1; mkdir /data/libvirt/images/$NAME \ && virt-clone \ --connect qemu:///system \ --original JeOS \ --name $NAME \ --file /data/libvirt/images/$NAME/$NAME.qcow2 \ --file /data/libvirt/images/$NAME/${NAME}_data.qcow2