Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355709
  • 博文数量: 306
  • 博客积分: 3975
  • 博客等级: 中校
  • 技术积分: 3265
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-27 13:14
文章分类

全部博文(306)

文章存档

2017年(1)

2016年(3)

2015年(11)

2014年(15)

2013年(178)

2012年(41)

2011年(38)

2010年(9)

2009年(9)

2008年(1)

分类: LINUX

2009-09-13 11:07:33

 虚拟化是目前一门炙手可热的技术,它给我们带来的好处在各个层次都有体现,作为一个网络管理者来说,搭建和维护服务器更是我们职责所在!目前的服务器配置可以说是相当高了,单核cpu的时代也已经渐渐离我们远去,在我们使用多核cpu以及大内存服务器的的同时,我们是否想过这些服务器的性能是否完全都使用上了?举个例子来说,假设公司有一台IBM System x3650,它配备Xeon 5450cpu(四核心),二级缓存高达12M,最大支持48gb内存,在这样一台如此强劲的服务器上如果只跑一两个应用的话是否浪费了很多的性能呢?
当然,你完全可以把企业中很多的应用都跑在这一台服务器上,这样做虽然是可以的,但是大家都知道,在单个OS上跑的应用越多,出问题的系数也就越高,往往会因为其中某一个应用的问题而导致整个OS崩溃,再或者某个应用支持的系统平台不同,我们需要多个OS来支持,如此以来是否又要购买服务器来达到我们的需求?如果在虚拟化技术没出现之前,我们只能购买更多的服务器来支持更多的应用,无论在维护还是资金上都是一笔不小的投入,不过此刻的我们非常幸运,在这个虚拟化技术流行的时代,那些曾经不可能实现的问题已经不再是问题了,在此我也非常感谢那些在虚拟化技术上投入心血的人们.我们现在完全可以实现在一台物理机上同时跑多个OS!
    很多管理员都用过VMware Workstation或者vpc,我们把它们称作虚拟机软件,我们可以在其上安装和物理机不同的OS,在我们需要测试某些程序或者搭建一些环境的时候经常使用到他们,在虚拟机上跑的OS即便是崩溃了也不会影响我们物理机上的任何应用,那我们是否把他们应用在服务器虚拟化层面呢?在这里我不建议这么去做,因为以上提到的两款虚拟机软件只不过是在物理机OS上运行的一个软件而已,此软件运行后会模拟一台真实计算机的环境,只不过是模拟罢了,模拟出来的东西要和物理机上的内核打交道是要经过很多道关卡的,在通过一层一层二进制转换后才能把I/O操作传送到内核中,从而我们会感觉到它们性能是不怎么强的,而服务器在性能上的要求是非常高.
    简单介绍一下,在目前的服务器虚拟化方面使用较多的有Xen,hyper-v,VMware esX server等,hyper-v集成在windows server 2k8 64位版中,必须购买windows 2k8以后才可以使用.VMware esX server是一款相当成熟的虚拟机管理器,也是需要购买后才可使用,而Xen则是开源软件,可以直接下载后在linux上编译即可使用,并且最新的Xen3已经支持硬件虚拟化,可以在不修改内核源码的情况下虚拟OS,当然还有其他更多的可以在google上找到.关于Xen的原理可以在学习到,在这里提一下什么是hypervisor,简单的说hypervisor其实就是由一些微代码构成,其最先被载入内存,用来隔离每一个OS.在有官方的ppt,可以更加详细的了解Xen的原理.
   经常看到一些喜爱Linux的用户和喜爱使用Windows的用户针锋相对,甚至破口大骂的时候我非常不理解,我对Linux和windows都非常喜爱,在搭建服务器的时候总是喜欢把两者结合起来使用,评价谁好谁坏毫无意义,应该尽量结合两者的优势来管理好服务器才是正道.平时用Linux的时候很多,我比较爱用centos和suse,这里就拿Centos5来说说Xen在网络上的配置,让我们把Xen更好的应用于生产环境中.
   首先在centos上安装xen内核,这个很简单,在centos中有rpm包,直接使用dvd挂载上去后安装即可,具体安装哪些包在这里就不多废话了,网络上有很多教程,在这个地方浪费篇幅就跑题了,现在假设已经安装好了Xen内核,并且在Xen内核中已经安装成功一台guestOS,(半虚拟化环境)那么在多网卡的环境下如何去配置?这里只是讲解多网卡桥接环境.
   先来分析几个脚本,更加深刻的理解xen的网络配置情况.
   如果你是用rpm包安装的话,那么可以看到如下的结构..
引用
[root@target xen]# auto  xend-config.sxp   xmexample2
qemu-ifup  xend-pci permissive.sxp  xmexample.hvm
scripts    xend-pci-quirks.sxp      xmexample.vti
test1      xmexample1
blktap                   vif-common.sh
block                    vif-nat
block-common.sh          vif-route
block-enbd               vtpm
block-nbd                vtpm-common.sh
external-device-migrate  vtpm-delete
locking.sh               vtpm-hotplug-common.sh
logging.sh               vtpm-impl
network-bridge           vtpm-migration.sh
network-custom           xen-hotplug-cleanup
network-nat              xen-hotplug-common.sh
network-route            xen-network-common.sh
vif-bridge               xen-script-common.sh

    其中用显示为红色的几个文件和xen的网络配置关系密切.那么xend进程启动以后是如何调用这几个文件的?这几个文件又做了些什么动作?
在官方说明中有这样一段话:
When xend starts up, it runs the network-bridge script, which:
1。creates a new bridge named xenbr0 (建立一个网桥名称为xenbr0)
2。real ethernet interface eth0 is brought down (关闭真实的以太网接口eth0)
3。the IP and MAC addresses of eth0 are copied to virtual network interface veth0  (将eth0的IP和MAC地址拷贝给虚拟以太网接口veth0)
4。real interface eth0 is renamed peth0 (将真实的接口eth0重命名为peth0)
5。virtual interface veth0 is renamed eth0 (将虚拟以太网接口veth0重命名为eth0)
6。peth0 and vif0.0 are attached to bridge xenbr0. Please notice that in xen 3.3, the default bridge name is the same than the interface it is attached to. Eg: bridge name eth0, eth1 or ethX.VlanID (将peth0和vif0.0连接到网桥xenbr0)
7。the bridge, peth0, eth0 and vif0.0 are brought up (激活peth0 eth0 vif0.0)

xenbr0是什么?
我们知道,在xen环境里domU要和网络中的计算机通信是要通过xen总线来调用后端驱动来实现的.在xend脚本启动时,我们用ifconfig命令会发现多了一个xenbr0,xenbr0是一个网桥,众所周知,网桥是工作在链路层,在网桥中的设备都在一个广播域中,使用以下命令可以查看xenbr0的信息。
引用
[root@target ~]# brctl show | grep xenbr0 ; ip link show | grep xenbr0
xenbr0          8000.feffffffffff       no              peth0
                                                       vif0.0
xenbr0: BROADCAST,NOARP,UP,LOWER_UP mtu 1500 qdisc noqueue

    可以看出在网桥已经桥接了两块网卡,并且关闭了arp,在xend进程未启动之前,我们是看不到vethX接口的,因为此时netbk和netloop没有被载入,当进程启动后会通过xend脚本载入,此时虚拟接口以及被创建,但是down掉的,然后通过上面几个步骤后veth0会重命名为eth0,并且peth0,eth0以及vif0.0会被激活,此过程是通过network-bridge脚本实现的,为什么看不到veth0,因为此时已经被重命名为eth0.打开脚本会看到。
先看看创建网桥的代码,在network-bridge第198行定义了一个op_start函数
引用
198  op_start () {
   199      if [ "${bridge}" = "null" ] ; then
   200          return
   201      fi
   202
   203      if is_network_root ; then
   204          [ -x /usr/bin/logger ] && /usr/bin/logger "network-bridge: bridging not supported on network
root; not starting"
   205          return
   206      fi
   207
   208      if ! link_exists "$vdev"; then
   209          if link_exists "$pdev"; then
   210              # The device is already up.
   211              return
   212          else
   213              echo "
   214  Link $vdev is missing.
   215  This may be because you have reached the limit of the number of interfaces
   216  that the loopback driver supports.  If the loopback driver is a module, you
   217  may raise this limit by passing it as a parameter (nloopbacks=); if the
   218  driver is compiled statically into the kernel, then you may set the parameter
   219  using loopback.nloopbacks= on the domain 0 kernel command line.
   220  " >&2
   221              exit 1
   222          fi
   223      fi
   224
   225      create_bridge ${bridge}

    这一段前面是一些判断语句,比如bridge变量没设置或者vdev不存在的时候将给出提示信息并且退出,而最后create_bridge ${bridge}则是调用了create_bridge函数来创建一个网桥,create_bridge函数在xen-network-common.sh中有如下定义:
使用brctl命令创建网桥,关闭了生成树协议,转发延迟设置为0,并且关闭了arp和multicast
引用
109  create_bridge () {
   110      local bridge=$1
   111
   112      # Don't create the bridge if it already exists.
   113      if [ ! -e "/sys/class/net/${bridge}/bridge" ]; then
   114          brctl addbr ${bridge}
   115          brctl stp ${bridge} off
   116          brctl setfd ${bridge} 0
   117          sysctl -w "net.bridge.bridge-nf-call-arptables=0"
   118          sysctl -w "net.bridge.bridge-nf-call-ip6tables=0"
   119          sysctl -w "net.bridge.bridge-nf-call-iptables=0"
   120          ip link set ${bridge} arp off
   121          ip link set ${bridge} multicast off
   122      fi
   123
   124      # A small MTU disables IPv6 (and therefore IPv6 addrconf).
   125      mtu=$(ip link show ${bridge} | sed -n 's/.* mtu \([0-9]\+\).*/\1/p')
   126      ip link set ${bridge} mtu 68
   127      ip link set ${bridge} up
   128      ip link set ${bridge} mtu ${mtu:-1500}
   129  }

    替换ip和mac,并且重命名网卡等后续工作
引用
if link_exists "$vdev"; then
        mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
        preiftransfer ${netdev}
        transfer_addrs ${netdev} ${vdev}
        if is_bonding ${netdev} || ! ifdown ${netdev}; then
            # Remember the IP details if necessary.
            get_ip_info ${netdev}
            ip link set ${netdev} down
            ip addr flush ${netdev}
        fi
        ip link set ${netdev} name ${pdev}
        ip link set ${vdev} name ${netdev}

        setup_bridge_port ${pdev}
        setup_bridge_port ${vif0}
        ip link set ${netdev} addr ${mac} arp on

        ip link set ${bridge} up
        add_to_bridge  ${bridge} ${vif0}
        add_to_bridge2 ${bridge} ${pdev}
        do_ifup ${netdev}
    else
        # old style without ${vdev}
        transfer_addrs  ${netdev} ${bridge}
        transfer_routes ${netdev} ${bridge}
    fi

    if [ ${antispoof} = 'yes' ] ; then
        antispoofing
    fi
}

     明白了这些就好办了,这些动作都可以手工完成。
   先看看默认情况下,xend启动时网络情况是怎样的。默认启动时会根据network-bridge中的几个变量自动添加网桥并把网卡加入网桥中。在这里我HostOS中有两块物理网卡,此时服务启动后会自动建立xenbr0,并且把peth0 vif0.0加入。如果设置了默认路由,那么网卡号就是默认路由出口网卡号,如果没有设置默认路由,并且没有手动给vifnum赋值的话,默认为0,此时netdev为eth0,网桥名称为xenbr0,并且不使用iptable防止欺骗。
引用
vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 's/^[^0-9]*//')} (使用正规表达式找出默认网关出口网卡)
vifnum=${vifnum:-0})(如果vifnum变量没设置,则设置为0)
bridge=${bridge:-xenbr${vifnum}}(如果网桥名未设置则设置为xenbr${vifnum})
netdev=${netdev:-eth${vifnum}} (虚拟以太网接口,如果没设置则为eth${vifnum})
antispoof=${antispoof:-no}(默认不启用)
下列几项不要更改,看了前面的原理应该不难理解!
pdev="p${netdev}"
vdev="veth${vifnum}"
vif0="vif0.${vifnum}"

假如默认值不符合我们要求,我们可以手动添加。假设想建立一个名为test的网桥,桥接pth1和vif0.1(模块加载时自动生成的,直接和veth1相连,vif0.2则连接veth2,官网有图解)
引用
[root@target scripts]# pwd ; brctl show
/etc/xen/scripts
bridge name     bridge id               STP enabled     interfaces
[root@target scripts]# ./network-bridge bridge=test vifnum=1 start > /dev/null 2>&1 ; brctl show
bridge name     bridge id               STP enabled     interfaces
test            8000.feffffffffff       no              peth1
                                                        vif0.1

删除
引用
./network-bridge bridge=test vifnum=1 start > /dev/null 2>&1 ; brctl show
bridge name     bridge id               STP enabled     interfaces

设置domU配置文件,修改xen目录下与domU同名文件。红色标记的地方即为配置网卡的地方,mac地址如果为空则会在启动时自动分配,可以手动指定,建议制定为Xen保留地址00:16:3e:xx:xx:xx,bridge是要桥接到的网桥,要和已经存在的网桥名称一致,在这里为test。
引用
name = "test"
uuid = "14d7fb2c-3ef7-ce3e-7e73-bd6e4e082887"
maxmem = 256
memory = 128
vcpus = 1
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [  ]
disk = [ "tap:aio:/vmdisk/centos.img,xvda,w" ]
vif = [ "mac=00:16:3e:10:e4:53,bridge=test" ]

    使用xm create test命令启动后,会自动调用vif-bridge脚本,此时使用brctl show可以看到vif3.0(前面的3是domU的id号,0代表第一块网卡)已经桥接到test.此时在domU上设置好ip地址(或者从dhcp获取)后就可以和主机eth1相同网段的主机通信了。此时vif3.0对应在domU中的eth0,vif3.0的arp是关闭的,它不需要响应arp,只是将数据包发送到domU中.
引用
[root@target xen]# brctl show
bridge name     bridge id               STP enabled     interfaces
test            8000.feffffffffff       no              vif3.0
                                                        peth1
                                                        vif0.1

更简单的是按照官方推荐做法,直接使用略加修改缺省脚本,使xend启动时自动执行。
#!/bin/sh
dir=$(dirname "$0")
"$dir/network-bridge" "$@" vifnum=0
"$dir/network-bridge" "$@" vifnum=1
   保持为一个可执行文件,然后通过/etc/xen/xend-config.sxp调用即可,脚本非常简单,定义了不同的两个变量,执行了两遍罢了。
补充一点,在centos5中,启动后有一个默认网桥virbr0被创建,这个网桥是通过脚本/etc/init.d/libvirtd创建的,用于在没有dhcp环境下为虚拟网络分配ip地址,配置文件在/usr/share/libvirt/networks/default.xml中,下面做一个小实验。
引用
[root@target ~]# ls /etc/init.d/libvirtd ; cat /usr/share/libvirt/networks/default.xml
/etc/init.d/libvirtd

  default
   (默认网桥名称)
  
  (网桥ip)
    
      (ip地址范围)
    

  


启动libvirtd服务,从test中删除vif3.0,把vif3.0添加到virbr0中,使用dhclient获取地址。。。
引用
[root@target ~]# /etc/init.d/libvirtd start && brctl show
Starting libvirtd daemon: [确定]
bridge name     bridge id               STP enabled     interfaces
test            8000.feffffffffff       no              vif3.0
                                                        peth1
                                                        vif0.1
virbr0          8000.000000000000       no
[root@target ~]# brctl delif test vif3.0 && brctl addif virbr0 vif3.0 && brctl show
bridge name     bridge id               STP enabled     interfaces
test            8000.feffffffffff       no              peth1
                                                        vif0.1
virbr0          8000.feffffffffff       yes             vif3.0

切换到test控制台,获取地址。
引用
[root@target ~]# xm console test
[root@test ~]# dhclient
Internet Systems Consortium DHCP Client V3.0.5-RedHat
Copyright 2004-2006 Internet Systems Consortium.
All rights reserved.
For info, please visit

Listening on LPF/eth0/00:16:3e:10:e4:53
Sending on   LPF/eth0/00:16:3e:10:e4:53
Sending on   Socket/fallback
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 4
DHCPOFFER from 192.168.122.1
DHCPREQUEST on eth0 to 255.255.255.255 port 67
DHCPACK from 192.168.122.1
bound to 192.168.122.32 -- renewal in 1772 seconds.

   可以看到已经成功的获取到ip地址了。
  就到这里了,希望这一篇中的一些东西能够给大家带来一点点小小的帮助,小时候语文课总是喜欢偷偷的看金庸的小说,现在长大了,想想以前那么贪玩,搞的现在语言表达能力相当的差劲,只是想写点什么,好坏都请朋友们包涵了.......
阅读(2437) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~