去年OpenSolaris 2009.06发布时,有一个名为Crossbow的网络虚拟化项目是Sun公司大力宣传的,自从Oracle收购了Sun之后,Oracle继续支持了 Solaris Networking组的这个项目。现在随着Solaris 11 Express的发布,大家又可以尝试使用这个Solaris的新特性了。当年的Crossbow 1.0已经更新到了Solaris 11 Express中的Crossbow 1.4。大家可以用google搜“Solaris 11 Express”这个关键字来免费下载这个新的Solaris版本并尝试使用这个项目带来的新技术。

Crossbow包括不同的组件和配置工具,我将会通过一系列的文章进行介绍。

这篇文章将要介绍VNIC在Solaris 11 Express上的应用和配置。而VNIC则是Crossbow项目引入的最重要的一个特性。顾名思义,VNIC就是Virtual Network Interface Card。在Solaris内核看来,每一个VNIC就是一个虚拟的链路层(datalink)对象,用户可以像使用物理网卡一样在上面建立IP实例,如在其上配置网络地址、将其分配给不同的虚拟机或Zone。利用VNIC,用户可以在只有一个物理网卡的情况下创建多个链路接口同外网连接。即使使用一台没有网卡的机器,也可以在其中建立一个虚拟的复杂的网络拓扑结构,用来虚拟网络和连接多个虚拟机或Zone。这就是所谓Network in a Box理念的一种体现。

熟悉Solaris 10的朋友可能会知道,Solaris的dladm(1M)命令是用来配置和检查系统链路层对象的工具,同样在Solaris 11中,这个命令有了很大的扩展,用户可以用dladm(1M)来创建VNIC。假如用户安装了Solaris 11 Express,有下面的IP配置:

global-zone# ifconfig -a
 lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
 inet 127.0.0.1 netmask ff000000
 bge0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
 inet 10.11.19.169 netmask ffffff00 broadcast 10.11.19.255
 ether 0:9:3d:11:79:f8
 lo0: flags=2002000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv6,VIRTUAL> mtu 8252 index 1
 inet6 ::1/128



我们可以使用“dladm create-vnic”子命令来创建一个基于活动网卡bge0的名字叫“v1”的VNIC对象:

global-zone# dladm create-vnic -l bge0 v1



其中“-l”选项指定了基于哪个物理网卡创建VNIC,这样新创建的v1可以像bge0一样访问外网。我们可以使用“dladm show-vnic”查看新创建的VNIC的属性摘要:

global-zone# dladm show-vnic
 LINK OVER SPEED MACADDRESS MACADDRTYPE VID
 v1 bge0 1000 2:8:20:7a:5d:ed random 0



其中SPEED属性显示了可以通过这个VNIC的最大带宽,以兆比特每秒为单位。同时VNIC还有自己的MAC地址,而且由MACADDRTYPE显示这个 MAC地址是随机设置的。而VID显示的是这个VNIC的VLAN ID。默认是0,即没有设置VLAN。若要设置VID,可以在创建VNIC时使用“-v”选项。

这样,一个新的VNIC就创建好了。我们可以创建一个新的IP实例:

global-zone# ifconfig v1 plumb 10.11.19.170/24 up
 global-zone# ifconfig v1
 v1: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 3
 inet 10.11.19.170 netmask ffffff00 broadcast 10.11.19.255
 ether 2:8:20:7a:5d:ed



同时,Solaris系统也自动地为v1添加了一个网络接口路由:

global-zone# netstat -rnf inet
 Routing Table: IPv4
 Destination Gateway Flags Ref Use Interface
 -------------------- -------------------- ----- ----- ---------- ---------
 default 10.11.19.1 UG 6 4344271 bge0
 10.11.19.0 10.11.19.170 U 2 0 v1
 10.11.19.0 10.11.19.169 U 6 12645 bge0
 127.0.0.1 127.0.0.1 UH 2 1202 lo0



这样,其他的主机就可以通过这个基于VNIC新建的IP来访问本主机了。

有时候,用户会想搭建一个新的系统来配置网络服务,要求这个系统和当前主机系统上的网络服务相互隔离,互不干扰。但是我不想重装系统或使用新的主机,而且要给这个新系统一个独立的网络接口。应该怎么办呢?在这种情况下,VNIC就派上用场了。在实际应用中,Zone和VNIC这两个虚拟化技术的组合所显示出的威力是非常强大的,我们可以在本机系统中创建一个Non-global Zone来搭建这个新系统,而把VNIC分配给这个Zone作为在这个Zone中可以操作的网络接口。

让我们新建一个VNIC,名叫“v2”:

global-zone# dladm create-vnic -l bge0 v2
 global-zone# dladm show-vnic
 LINK OVER SPEED MACADDRESS MACADDRTYPE VID
 v1 bge0 1000 2:8:20:7a:5d:ed random 0
 v2 bge0 1000 2:8:20:ee:f0:cc random 0



然后将创建一个non-global zone,名为zone1,并通过“add net”将VNIC v2加入到zone1中:

global-zone# zonecfg -z zone1
 zone1: No such zone configured
 Use 'create' to begin configuring a new zone.
 zonecfg:zone1> create
 zonecfg:zone1> set zonepath=/export/home/zone1
 zonecfg:zone1> set ip-type=exclusive
 zonecfg:zone1> add net
 zonecfg:zone1:net> set physical=v2
 zonecfg:zone1:net> end
 zonecfg:zone1> verify
 zonecfg:zone1> commit
 zonecfg:zone1> exit
 global-zone# zoneadm -z zone1 install
 :
 global-zone# zoneadm -z zone1 boot



注意,在zone1创建时,指定了ip-type为exclusive,即创建一个具有独立IP协议栈的Zone。这样的话管理员才能在这个non- global zone中用ifconfig(1M)创建新的IP实例。否则,如果不指定这样的ip-type,在默认情况下会创建一个和global zone共享IP协议栈的Zone,这样在新创建的zone中用户是没有权限创建新的IP实例的。

当 zone1第一次启动以后(成功执行了“zoneadm -z zone1 boot”),我们可以用“zlogin -C zone1”像配置一个新的solaris系统一样配置这个zone,假如我们在v2上设置网络地址为10.11.19.171,子网掩码为 255.255.255.0,这个zone的主机名为zone1。此时,zone1的网络配置如下:

global-zone# zlogin zone1
 [Connected to zone 'zone1' pts/5]
 root@zone1:~# ifconfig -a
 lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1
 inet 127.0.0.1 netmask ff000000
 v2: flags=1000863<UP,BROADCAST,NOTRAILERS,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
 inet 10.11.19.171 netmask ffffff00 broadcast 10.11.19.255
 ether 2:8:20:ee:f0:cc
 lo0: flags=2002000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv6,VIRTUAL> mtu 8252 index 1
 inet6 ::1/128



需要注意的是,要保在zone1中有一个可用的默认路由,否则,这个新建的zone无法通过VNIC访问外网。

root@zone1:~# netstat -rnf inet
 Routing Table: IPv4
 Destination Gateway Flags Ref Use Interface
 -------------------- -------------------- ----- ----- ---------- ---------
 default 10.11.19.1 UG 3 71736 v2
 10.11.19.0 10.11.19.171 U 5 76807 v2
 127.0.0.1 127.0.0.1 UH 2 76 lo0



然后,我们可以尝试ping global-zone的地址:

root@zone1:~# ping 10.11.19.169
 10.11.19.169 is alive



这里需要说明的是,zone1和原来的global-zone是相互隔离的(可以把global-zone看作是实际的物理机器,而zone1是安装在 global-zone中的与其具有网络连接但是环境隔离的操作系统),如果在zone1中查看该zone中的链路对象,我们只能看到分配给这个zone 的网络接口:

root@zone1:~# dladm show-link
 LINK CLASS MTU STATE BRIDGE OVER
 v2 vnic 1500 up -- ?



同时,我们无法看到global zone中的任何网络接口(注意到OVER属性为“?”,即“未知”)。同时,在zone1中,用户也没有权限删除这个VNIC对象,因为这个VNIC是在global zone中创建的,如果想删除的话必须在zone1被halt之后,在 global zone中 使用"dladm delete-vnic v2"来删除。

如果用户想在zone1中的新系统环境中提供HTTP服务,我们可以这样这样实验:

(在zone1中执行)
安装apache服务器:

root@zone1:~# pkg install pkg:/web/server/apache-22
 Packages to install: 5
 Create boot environment: No
 Services to restart: 1
 DOWNLOAD PKGS FILES XFER (MB)
 Completed 5/5 907/907 4.7/4.7

 PHASE ACTIONS
 Install Phase 1171/1171

 PHASE ITEMS
 Package State Update Phase 5/5
 Image State Update Phase 2/2
 root@zone1:~# mkfile 100m /var/apache2/2.2/htdocs/largefile
 root@zone1:~# chown webservd:webservd /var/apache2/2.2/htdocs/largefile
 root@zone1:~# svcadm enable apache22



这样,apache服务器已经在zone1中启动了,我们可以在其他的机器上访问“10.11.19.171”来查看zone1中服务器上的主页。同时,注意到我在上面创建了一个名为largefile的大小为100M的文件,我们可以在本机的global zone或其他的机器上下载这个文件:

global-zone# /usr/sfw/bin/wget http://10.11.19.171/largefile
 --2010-12-19 13:35:46-- http://10.11.19.171/largefile
 Connecting to 10.11.19.171:80... connected.
 HTTP request sent, awaiting response... 200 OK
 Length: 104857600 (100M) [text/plain]
 Saving to: `largefile'
 100%[======================================>] 104,857,600 117M/s in 0.9s
 2010-12-19 13:35:46 (117 MB/s) - `largefile' saved [104857600/104857600]



很好!我们使用VNIC和Zone创建了一个新的HTTP服务器而没有添加新的硬件,采用VNIC技术可以提高网络设备的利用率和复用性。在本系列的下一篇文章中,我将介绍etherstub,并给大家演示在一个没有网络连接的系统中,采用etherstub和VNIC创建一个虚拟的网络环境。