CentOS 6 에서는 Xen 이 없습니다. Xen 의 가장 큰 특징인 반가상화(paravirt)를 지원하는데, 반가상화가 좋은이유는 전가상황에 에서 필요로하는 CPU 가상화를 필요로 하지 않습니다. 회사에 테스트 컴퓨터가 있는데 CentOS 5 에서는 Xen 이 들어있어서 별 무리없이 사용을 하곤했습니다. 물론 반가상화로 사용했었는데, CentOS 6 으로 넘어오면서 사용을 못하고 있었습니다.
이 문서는 CentOS 6 에서 반가상화를 설정하는 방법을 설명한 것입니다.
1.하드웨어
KVM 은 전 가상화입니다. 이를 위해서는 CPU 에서도 하드웨어 적으로 가상화를 지원해줘야 합니다. 최근에 나오는 CPU들은 전부 가상화 기능이 탑재되어 있어서 문제가 없지만 예전에 CPU는 가상화가 거의 없습니다.
processor : 0
vendor_id : AuthenticAMD
cpu family : 15
model : 35
model name : AMD Athlon(tm)64 X2 Dual Core Processor 4400+
stepping : 2
cpu MHz : 2210.066
cache size : 1024 KB
fpu : yes
fpu_exception : yes
cpuid level : 1
wp : yes
flags : fpu de tsc msr pae mce cx8 apic mtrr mca cmov pat clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt
lm 3dnowext 3dnow rep_good extd_apicid pni hypervisor lahf_lm cmp_legacy arat
bogomips : 4420.13
TLB size : 1024 4K pages
clflush size : 64
cache_alignment : 64
address sizes : 40 bits physical, 48 bits virtual
power management: ts fid vid ttp
이럴때 Xen 의 반가상화는 가상화를 가능하게 해줍니다.
2.CentOS 6 설치.
CentOS 6을 설치해줍니다. 설치는 최소 설치로 합니다. 그리고 업데이트로 패키지로 최신으로 만듭니다. 커널이 업데이트 되었다면 재부팅해줍니다. 설치할때 특별한 것은 없고 대신에 컴파일 환경을 만들어 줘야 합니다. Xen, kernel, libvirt 이 3가지의 패키지를 재컴파일 해줘야 하기 때문에 컴파일 환경이 필요합니다.
]# yum update -y
]# reboot
]# yum install gcc.x86_64 gcc-c++.x86_64 wget.x86_64 bzip2-devel.x86_64 pkgconfig.x86_64 openssl-devel.x86_64 make.x86_64 man.x86_64 nasm.x86_64 gmp.x86_64 gdbm-devel.x86_64 readline-devel.x86_64 compat-readline43.x86_64 ncurses-devel.x86_64 db4-devel.x86_64 automake* autoconf* bind-utils vim-enhanced rpm-build -y
3.rpmbuild 환경 변경.
rpmbuild 는 rpm 패키지를 만드는 도구 입니다. 문제는 rpm 패키지를 제작하기위한 뿌리 디렉토리가 /root 라는 것입니다. 커널 패키징을 할때에는 수GB의 용량이 필요한데 보통 / 파티션을 그렇게 크게 잡지는 않습니다. 그래서 rpm 패키지 제작의 뿌리 디렉토리를 다음과 같이 변경해 줍니다.
]# echo '%_topdir /usr/src/rpmbuild' > ~/.rpmmacros
이렇게 하면 rpm 패키지 제작의 뿌리가 /usr/src/rpmbuild 로 변경됩니다.
4.xen 빌드.
먼저 xen 을 빌드 해줍니다. xen 의 srpm 은 다음의 주소에서 다운로드 받습니다.
]# wget http://xenbits.xen.org/people/mayoung/EL6.xen/SRPMS/xen-4.1.1-3.el6.src.rpm
설치해줍니다.
]# rpm -ivvh xen-4.1.1-3.el6.src.rpm
]# rpmbuild -ba /usr/src/rpmbuild/SPECS/xen.spec
이렇게 하면 의존성 오류가 나오는데 다음과 같이 의존성 패키지들을 설치해 줍니다.
]# yum install transfig.x86_64 libidn-devel.x86_64 texi2html SDL-devel.x86_64 curl-devel libX11-devel.x86_64 python-devel.x86_64 ghostscript.x86_64 tetex-latex gtk2-devel.x86_64 libaio-devel.x86_64 texinfo.x86_64 dev86.x86_64 gettext.x86_64 gnutls-devel.x86_64 pciutils-devel.x86_64 libuuid-devel.x86_64 iasl.x86_64 xz-devel.x86_64 e2fsprogs-devel.x86_64 glibc-devel.i686 -y
컴파일이 끝나고 패키지가 정상적으로 생성되었다면 설치해줍니다.
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/xen-licenses-4.1.1-3.el6.x86_64.rpm
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/xen-libs-4.1.1-3.el6.x86_64.rpm
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/xen-hypervisor-4.1.1-3.el6.x86_64.rpm
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/xen-devel-4.1.1-3.el6.x86_64.rpm
]# yum install qemu-img.x86_64 -y
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/xen-runtime-4.1.1-3.el6.x86_64.rpm
]# yum install PyXML.x86_64 bridge-utils.x86_64 kpartx.x86_64 -y
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/xen-4.1.1-3.el6.x86_64.rpm
5.libvirt 패키지 재 빌드.
libvirt 는 가상서버와 클라이언트간에 중계 통신 역활을 합니다. 문제는 CentOS 6 에서는 Xen 통신을 막아놔서 Xen 을 설치하더라도 다음과 같은 오류가 난다는 것입니다.
]# virt-install --paravirt --prompt --nographics
ERROR Host does not support virtualization type 'xen'
이것은 libvirt 에 문제가 있기 때문입니다. 이를 위해서 libvirt 를 재 패키징 해줍니다.
]# wget http://mirror.cdnetworks.com/centos/6/os/SRPMS/Packages/libvirt-0.8.1-27.el6.src.rpm
]# rpm -ivvh libvirt-0.8.1-27.el6.src.rpm
]# vi /usr/src/rpmbuild/SPECS/libvirt.spec
- 107 %define with_xen 0
+ 107 %define with_xen 1
]# rpm -ba libvirt.spec
위와 같이 하면 의존성 오류가 나면서 빌드가 되지 않습니다. 의존성 걸린 것들을 모두 설치해줍니다.
]# yum install libnl-devel.x86_64 libtool.x86_64 nfs-utils.x86_64 libxml2-devel.x86_64 xhtml1-dtds libudev-devel.x86_64 libpciaccess-devel.x86_64 yajl-devel.x86_64 libpcap-devel.x86_64 avahi-devel.x86_64 dnsmasq.x86_64 cyrus-sasl-devel.x86_64 polkit.x86_64 lvm2.x86_64 iscsi-initiator-utils.x86_64 parted-devel.x86_64 device-mapper-devel.x86_64 numactl-devel.x86_64 libcap-ng-devel.x86_64 netcf-devel.x86_64 -y
그리고 다시 리빌드 해줍니다. 정상적으로 패키징이 되었다면 설치해줍니다.
]# yum install cyrus-sasl-md5 nc -y
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/libvirt-client-0.8.1-27.el6.x86_64.rpm
]# yum install ebtables lzop -y
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/libvirt-0.8.1-27.el6.x86_64.rpm
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/libvirt-python-0.8.1-27.el6.x86_64.rpm
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/libvirt-devel-0.8.1-27.el6.x86_64.rpm
6. dom0 커널 빌드.
Xen 을 사용하기 위해서는 dom0 커널이 필요합니다. 다음에 주소에서 다운로드 받습니다.
]# wget http://fedorapeople.org/~myoung/dom0/src/kernel-2.6.32.39-175.xendom0.fc13.src.rpm
이제 설정을 조금 바꿔 줍니다. 먼저 spec 파일을 고칩니다.
]# vim /usr/src/rpmbulid/SPECS/kernel.spec
- 112 %define with_firmware %{?_with_firmware: 1} %{?!_with_firmware: 0}
+ 112 %define with_firmware %{?_without_firmware: 0} %{?!_without_firmware: 1}
- 297 %define with_firmware %{?_without_firmware: 0} %{?!_without_firmware: 1}
+ 297 %define with_firmware 0
이제 커널 설정 값을 변경 합니다.
]# vim /usr/src/rpmbulid/SOURCE/config-generic
CONFIG_VIRTIO=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_RING=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
CONFIG_VIRTIO_NET=y
CONFIG_VMXNET3=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_VIRTIO_CONSOLE=y
]# vim /usr/src/rpmbulid/SOURCE/config-x86_64-generic
CONFIG_XEN=y
CONFIG_XEN_MAX_DOMAIN_MEMORY=32
CONFIG_XEN_BALLOON=y
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_SAVE_RESTORE=y
CONFIG_HVC_XEN=y
CONFIG_XEN_FBDEV_FRONTEND=y
CONFIG_XEN_KBDDEV_FRONTEND=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
CONFIG_XENFS=y
CONFIG_XEN_COMPAT_XENFS=y
CONFIG_XEN_DEV_EVTCHN=y
CONFIG_XEN_SYS_HYPERVISOR=y
]# vim /usr/src/rpmbulid/SOURCE/config-rhel-generic
- 94 # CONFIG_BLK_DEV_NBD is not set
의존성이 패키지를 설치해줍니다.
]# yum install redhat-rpm-config xmlto asciidoc elfutils-libelf-devel binutils-devel -y
리빌드 해줍니다.
]# rpmbuild -ba /usr/src/rpmbuild/SPECS/kernel.spec
정상적으로 빌드가 되었다면 설치해줍니다.
]# rpm -Uvvh /usr/src/rpmbuild/RPMS/x86_64/kernel-firmware-2.6.32.39-175.xendom0.el6.x86_64.rpm
]# rpm -ivvh /usr/src/rpmbuild/RPMS/x86_64/kernel-2.6.32.39-175.xendom0.el6.x86_64.rpm
이제 재부팅을 한번 해줍니다.
7.Network Bridge 설정.
재부팅을 하고나서 ifconfig 를 쳐보면 다음과 같이 나옵니다.
]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:E0:4C:E1:55:46
inet addr:192.168.1.5 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::2e0:4cff:fee1:5546/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:65 errors:0 dropped:0 overruns:0 frame:0
TX packets:79 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:9233 (9.0 KiB) TX bytes:11479 (11.2 KiB)
Interrupt:18 Base address:0xec00lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)virbr0 Link encap:Ethernet HWaddr D6:72:92:9C:78:9F
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:11 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:3052 (2.9 KiB)
가상서버에서는 기본적으로 네트워크를 NAT 방식으로 세팅을 합니다. 이렇게하는 것보다 물리적인 네트워크에 직접 접속하도록 하기위해서 설정을 해주도록 합니다.
]# virsh net-destroy default
]# virsh net-undefine default
]# service libvirtd restart
그리고 eth0 설정을 백업해주고 새로운 브릿지 인터페이스 br0 를 만들어 줍니다.
]# cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth0.bak
]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
NM_CONTROLLED="no"
ONBOOT=yes
HWADDR=00:E0:4C:E1:55:46
BRIDGE="br0"
]# vi /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.1.5
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DELAY=0
]# service network restart
]# cat >> /etc/sysctl.conf <<eof>
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
EOF
]# sysctl -p /etc/sysctl.conf
]# echo "-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT" > /etc/sysconfig/iptables-forward-bridged
]# lokkit --custom-rules=ipv4:filter:/etc/sysconfig/iptables-forward-bridged
]# service libvirtd reload
</eof>
위와 같이 해서 네트워크가 정상 동작한다면 제대로 된 것입니다.
8.Xen grub.conf 설정. 이제 Xen 으로 부팅이 되도록 grub.conf 에 설정을 해줍니다.
]# vim /etc/grub.conf
kernel /boot/xen.gz dom0_mem=512M loglvl=all guest_loglvl=all
module /boot/vmlinuz-2.6.32.39-175.xendom0.el6.x86_64 ro root=UUID=f537d77e-f0df-4326-950c-7d3537e5adc4 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us nomodeset crashkernel=auto
module /boot/initramfs-2.6.32.39-175.xendom0.el6.x86_64.img
]# chkconfig --level 3 iptable off
]# chkconfig --level 3 ip6table off
]# chkconfig --level 3 xenconsoled off
]# chkconfig --level 3 xend off
]# chkconfig --level 3 xendomain off
]# chkconfig --level 3 xenstored off
]# vi /etc/rc.local
service xendomain start
service xenconsoled start
service xenstored start
service xend start
]# reboot
9.확인
부팅후에 가상화가 제대로 되었는지 다음과 같이 확인 합니다.
host : localhost.localdomain
release : 2.6.32.39-175.xendom0.el6.x86_64
version : #1 SMP Sun Oct 9 17:13:19 KST 2011
machine : x86_64
nr_cpus : 2
nr_nodes : 1
cores_per_socket : 2
threads_per_core : 1
cpu_mhz : 2210
hw_caps : 178bf3ff:e3d3fbff:00000000:00000010:00000001:00000000:00000003:00000000
virt_caps :
total_memory : 1919
free_memory : 1383
free_cpus : 0
xen_major : 4
xen_minor : 1
xen_extra : .1
xen_caps : xen-3.0-x86_64 xen-3.0-x86_32p
xen_scheduler : credit
xen_pagesize : 4096
platform_params : virt_start=0xffff800000000000
xen_changeset : unavailable
xen_commandline : dom0_mem=512M loglvl=all guest_loglvl=all
cc_compiler : gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC)
cc_compile_by : root
cc_compile_domain :
cc_compile_date : Sun Oct 9 16:19:45 KST 2011
xend_config_format : 4
vit-manager 와 xinit 를 설치합니다.
]# yum install virt-manager xorg-x11-xinit
이렇게 한 후에 리모트에서 ssh -Y 로 접속을 한후에 virt-manager 를 실행하면 로컬에 화면이 뜹니다.
[출처] Xen 4.1 for CentOS 6|작성자 플그림이