分类:
2010-01-20 10:38:11
本文介绍了在Solaris 10中如何运用虚拟化技术来实现动态CPU资源管理。
关键字:Solaris 10, Container, 资源管理,resource management, CMT
Solaris 10中提供了一项强大的虚拟化技术:Container(容器),通过使用Container,我们可以在一个操作系统实例中虚拟出多个运行环境(Zone),每个Zone有自己的文件系统和网络地址,各个Zone中运行的应用互相不影响,从而实现应用级的隔离,并提高了安全性。如下图所示, 在一个Solaris 10 的操作系统中,划分了3个Container,分别运行App Server, Web Server和Database Server。
Container的使用非常简单,通常只需要5-10分钟的配置即可,所以Container的虚拟化技术得到了广泛的应用。
资源管理的作用
在缺省的情况下,各个Container都可以看见物理机器上的所有CPU 和内存,也就是说物理机上的所有CPU和内存在各个Container中是共享的。在实际运用中,往往需要对各个Container使用的资源加以指定,以便确保一些关键应用的资源。另外一种场景是需要动态调节各个Container中的资源,例如,在月末做报表时,希望临时给数据库的Zone多分配一些CPU资源,在月末压力高峰之后,就可以恢复成原来的CPU资源。动态资源调整(Dynamic Reconfiguration)的功能在中高端服务器上(如E25K,M4000-M9000等)可由硬件实现,在其他中低端类型的服务器中,我们可以用Container 来实现。
Container
Solaris 10 的Container 包括两层功能:Zone和Resource Management(RM)。Zone是指隔离的虚拟运行环境,RM是以前版本的Solaris就有的功能,可以结合Zone来动态分配资源。本文以T5220为例子加以说明,在实际中对所有运行Solaris10的多处理器机器都适用,包括X86机器。T5220 有一个UltraSPARC T2处理器,可以拥有8个核心(cores),每个核心有8个硬件线程,因此,T5220可以拥有64个硬件线程,在操作系统中可以看到有64个物理CPU,如
# psrinfo 0 on-line since 04/08/2009 14:22:42 1 on-line since 04/08/2009 14:22:45 2 on-line since 04/08/2009 14:22:45 3 on-line since 04/08/2009 14:22:45 4 on-line since 04/08/2009 14:22:45 5 on-line since 04/08/2009 14:22:45 6 on-line since 04/08/2009 14:22:45 ( 略去部分输出) 61 on-line since 04/08/2009 14:22:45 62 on-line since 04/08/2009 14:22:45 63 on-line since 04/08/2009 14:22:45
创建Zone
1.创建Zone: # mkdir –p /export/home/zones/zone1 # 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/zones/zone1 zonecfg:zone1>set autoboot=true zonecfg:zone1>add net zonecfg:zone1:net>set address=192.168.0.1 zonecfg:zone1:net>set physical=e1000g0 zonecfg:zone1:net>end zonecfg:zone1>verify zonecfg:zone1>commit zonecfg:zone1>exit 2. 查看配置的zone: # ls -l /etc/zones/*xml 可以看到zone1.xml的配置文件 # zoneadm list –cv 可以看到刚刚配置好的zone 3.安装zone: # zoneadm –z zone1 install 4. 检查zone状态可以看到zone1 的状态为installed: # zoneadm list –cv 5. 启动zone: # zoneadm –z zone1 boot 6.首次启动需要初始化服务和配置,可用命令登陆console监控: # zlogin -C zone1 7. 系统会出现配置界面,如主机名,命名服务等。完成配置后,zone会重新启动, 即可完成系统的启动。 8.如果在zone1里面运行psrinfo命令,可以看到64个CPU,也就是说, global zone和local zone里面的CPU目前是共享的,下一步我们可以 把zone里的资源进一步限定。
CPU资源分配
假定我们需要给这个zone分配8个CPU资源(即一个core),可以用以下资源管理命令:
1.先检查资源管理服务是否启用: # svcs -a | grep pool disabled Jan_03 svc:/system/pools:default disabled Jan_03 svc:/system/pools/dynamic:default 如果显示disabled,则需要启用: # svcadm enable pools # svcadm enable pools/dynamic # svcs -a | grep pool online Jan_03 svc:/system/pools:default online Jan_03 svc:/system/pools/dynamic:default 2. 启动资源管理功能和生成基本配置文件 : # pooladm -e # pooladm -s 3. 创建资源池(pool): # poolcfg -dc ‘create pool pool1’ 4. 创建CPU集(pset), 包括8个CPU,其中pset.min和pset.max限定了CPU的个数: # poolcfg -dc ‘create pset pset1 ( uint pset.min=8; uint pset.max=8 )’ 5. 指定特定的CPU到CPU集中,此步骤可选,如果不指定CPU编号,则系统自动分配CPU。 为了使T5220的分区具有较好的性能,我们把同一个core中的CPU分配到同一个CPU集中: # poolcfg -dc ‘transfer to pset pset1 ( cpu 0; cpu 1; cpu 2; \ cpu 3; cpu 4; cpu 5; cpu 6; cpu 7)’ 6.把资源池pool1和CPU集pset1作关联: # poolcfg -dc ‘associate pool pool1 ( pset pset1 )’ 7.保存配置到文件(save): # pooladm -s 8.查看当前CPU资源的配置,可以看到pool1已经关联上pset1, pset1中有8个CPU(id:0-7),而缺省的pset_default中只有56个CPU 了: # pooladm system default string system.comment int system.version 1 boolean system.bind-default true string system.poold.objectives wt-load pool pool_default int pool.sys_id 0 boolean pool.active true boolean pool.default true int pool.importance 1 string pool.comment pset pset_default pool pool1 int pool.sys_id 2 boolean pool.active true boolean pool.default false int pool.importance 1 string pool.comment pset pset1 pset pset1 int pset.sys_id 1 boolean pset.default false uint pset.min 8 uint pset.max 8 string pset.units population uint pset.load 0 uint pset.size 8 string pset.comment cpu int cpu.sys_id 5 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 4 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 7 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 6 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 1 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 0 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 3 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 2 string cpu.comment string cpu.status on-line pset pset_default int pset.sys_id -1 boolean pset.default true uint pset.min 1 uint pset.max 65536 string pset.units population uint pset.load 807 uint pset.size 56 string pset.comment cpu int cpu.sys_id 13 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 12 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 15 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 14 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 9 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 8 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 11 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 10 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 21 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 20 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 23 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 22 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 17 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 16 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 19 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 18 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 29 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 28 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 31 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 30 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 25 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 24 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 27 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 26 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 53 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 52 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 55 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 54 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 49 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 48 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 51 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 50 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 61 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 60 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 63 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 62 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 57 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 56 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 59 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 58 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 37 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 36 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 39 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 38 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 33 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 32 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 35 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 34 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 45 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 44 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 47 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 46 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 41 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 40 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 43 string cpu.comment string cpu.status on-line cpu int cpu.sys_id 42 string cpu.comment string cpu.status on-line
配置Zone的CPU资源
此时,如果在Zone1中运行psrinfo命令,会发现只有56个CPU了(8-63),原因是zone1缺省情况下使用了pool_default这个资源池。我们用zonecfg命令,把pool1分配给zone1:
# zonecfg -z zone1 zonecfg:zone1>set pool=pool1 zonecfg:zone1>commit zonecfg:zone1>exit # zoneadm –z zone1 reboot 在Zone1重新启动后,我们在这个zone里可以看到只有8个CPU了: Zone1# psrinfo 0 on-line since 04/08/2009 14:22:42 1 on-line since 04/08/2009 14:22:45 2 on-line since 04/08/2009 14:22:45 3 on-line since 04/08/2009 14:22:45 4 on-line since 04/08/2009 14:22:45 5 on-line since 04/08/2009 14:22:45 6 on-line since 04/08/2009 14:22:45 7 on-line since 04/08/2009 14:22:45
动态分配CPU资源
如果需要改变zone1的CPU资源的分配配置,例如需要增加CPU到16个,可以通过重新配置pset1来实现,注意,这个操作可以在不停止zone 的情况下进行:
1)先取消原来pset1的配置: # poolcfg –dc ‘destroy pset pset1’ 2)此时zone1中的CPU数恢复到64个,我们再用命令创建一个包含16个CPU的pset1, 命令和前述的过程差不多: # poolcfg -dc 'create pool pool1' # poolcfg -dc 'create pset pset1 ( uint pset.min=16; uint pset.max=16 )' # poolcfg -dc 'transfer to pset pset1 ( cpu 0; cpu 1; cpu 2; cpu 3;\ cpu 4; cpu 5; cpu 6; cpu 7)' # poolcfg -dc 'transfer to pset pset1 ( cpu 8; cpu 9; cpu 10; cpu 11; \ cpu 12; cpu 13; cpu 14; cpu 15)' # poolcfg -dc 'associate pool pool1 ( pset pset1 )' # pooladm –s 3)这时,在zone1中的CPU数目改为16个。
这样,我们就在Solaris 10中实现了通常由硬件实现的CPU资源动态管理功能。