11.8 通过NFS共享软件
额外的软件应该装在哪儿?装在各个客户机上,还是装在中央文件服务器上,然后通过NFS共享?Linux的标准回答是“装在客户机上”,但采用NFS的方案却能让更新的速度更快(更新10台NFS服务器要比更新1 000台客户机速度更快,也更可靠),而且节省了客户机上的硬盘空间(在硬盘容量高达400GB的世界里这不算多大问题)。
问题实际上归结到了可管理性和可靠性的比较上。基于网络文件系统的访问方法是集中式的,日常管理起来更容易,能立即在所有的客户机上修改bug和安装新软件包。不过,通过网络运行要比访问本地硬盘速度慢一些。此外,网络服务器模型增加了对网络和文件服务器的依赖性,不仅因为它增加了潜在的故障点,而且因为它要求客户机和服务器必须就某些方面取得一致,比如要用哪些共享库,这些共享库安装的版本等。底线在于,NFS软件库是一种高级管理技术,只应该用在允许高度集中协作的环境中。
如果您工作的环境里有高性能的网络,能够买得起用于中央服务器的快速RAID盘阵,那么您会发现网络服务器实际的性能要比本地IDE硬盘快得多。无论性能好坏,性能的影响可能都不大,对于性能的考虑不应该在体系结构设计上占据主导地位。
一般来说,异构系统的网络从共享软件库获得的好处最大。如果您的站点按标准只采用一种操作系统,而这种操作系统又提供了不错的软件包管理设施,可能最好还是坚持采用本来的系统,不用网络系统。
11.8.1 软件包的名字空间
传统的UNIX把新软件包的内容分散放到多个目录下。库放在/usr/lib下,二进制程序放在/usr/bin下,而文档放在/usr/share/docs下等。尽管FHS(Filesystem Hierarchy Standard,文件系统层次结构标准)有助于让文件的位置多一点能预测的可能性,但Linux还是或多或少继承了与UNIX一样的体系。
这一约定的优点是文件都会出现在已知的地方—只要您的环境变量PATH指向了/usr/bin和其他放二进制程序的标准目录,那么马上就能用上新安装的程序。
而它的缺点在于,必须能清楚地确定文件的来源(借助软件包管理系统),而且分散的文件难以在网络上共享。还好,乐意多做些额外工作的系统管理员有个不错的办法能摆脱这个问题:软件包的名字空间。
这个方案的要点是把每个软件包安装到它自己单独的根目录中。例如,您可以把gimp安装到/tools/graphics/gimp里,二进制程序的位置在/tools/graphics/gimp/bin/gimp。接下来,您就可以通过在目录(比如/tools/bin)里放上符号链接,为您自己的工具集重新建立一个集中的二进制目录:
/tools/bin/gimp -> /tools/graphics/gimp/bin/gimp |
随后,用户可以把/tools/bin加到他们自己的PATH变量里,好能找到所有的共享工具。
目录/tools的结构可以有多种选择。分层组织的方法(例如,/tools/graphics、/tools/editors等)既方便浏览,又加快了性能。您可以在自己的命名约定中包含软件版本、硬件体系结构、操作系统或者负责人姓名的首字母,让同一组工具集能服务多种客户机。例如,Solaris用户可以在他们的PATH中包括/tools/sun4/bin,而Fedora的用户则用/tools/fedora/bin。
当您安装了一个重要工具的新版本之后,不限期地保留它的老版本是个好想法,特别对于用户已经在使用该工具的项目上投入大量时间和精力的情况更要这么做。理想情况是,工具的新版本要向后兼容旧的数据文件和软件,但在实际操作时,出问题的情况却司空见惯。好的做法是,要求用户克服一些配置上的麻烦,仍能用上一个软件包的较早版本;不好的做法是,打断用户现在的工作,让他们自己去处理后果。
11.8.2 依赖关系的管理
有些软件包要依赖若干库或者其他软件包。当您通过一个软件包管理系统在本地安装软件的时候,您可以获得很多辅助手段,解决好这些问题。不过,当您建立自己站点用的网络软件库的时候,您就必须明确地处理这些问题。
如果您按照和管理应用软件一样的方式来管理库,那么可以编译您的工具,让它们使用被共享的/tools目录下的库。这样的做法可以让您同时使用一个库的多个版本。因为依赖库的应用软件链接到了库的特定版本上,所以即便发布了这个库的新版本,这种设置仍然保持稳定。缺点是随着时间的推移,对于使用和维护来说,这种设置会变得相当复杂。
要经得住诱惑,不要在全局的/tools/lib目录下,用不带版本号的通称给链到共享库的链接起名字。如果您改变了链接,就会遇到不确定且难以诊断的问题。共享库系统就是为解决一些这样的潜在问题而设计的,但是要在一个复杂的设置下安全地使用它才有意义。
要让编译时的链接器使用一个共享库的特定版本,所需的确切步骤随系统的不同而不同。在Linux下,您可以设置环境变量LD_LIBRARY_PATH或者使用链接器的-R选项。
11.8.3 封装脚本
遗憾的是,做到库一级的兼容只解决了问题的一半。有的工具还要调用别的工具,这种情况直接造成了另一个发生冲突的机会。例如,假定有个叫做foo的工具程序需要频繁调用名为bar的工具。如果您更新了bar的默认版本,那么您可能会发现foo突然就不干活了。在这种情况下,您可以断定foo依赖bar不再支持的某种行为(或者至少不再是默认的行为)。
如果您的软件库支持多版本(例如,/tools/util/bar-1.0和/tools/util/bar-2.0),就可以通过把foo原来的版本改为foo.real,然后再用一个小的封装脚本来代替它:
|
现在可以用一个定制过的PATH环境变量来启动foo,它会优先调用bar的老版本而不是新版本。
封装程序(wrapper)是一种功能很强的工具,它能够解决的不仅仅是软件包依赖性的问题,而且还能解决像安全、体系结构或者操作系统依赖性、以及跟踪使用情况等这样的问题。有些站点会把所有的共享库包裹起来。
11.8.4 实现工具
在系统管理工作中,维护共享软件库是一个共同面临的问题,系统管理员已经开发出了各种软件方案,从而有助于让这个过程更容易进行。和本地化一样,“自产自销”的方法似乎占据了主流,但总还是要找找看,在能获得的系统里是否会有满足需要的。
要找到其中一些经典系统,可以用google搜索一下CMU Depot、CERN ASIS或者CITES Encap。这些项目中有些开发还很活跃,而另外一些则已经被放弃了,因为受到了来自Windows主机,以及广泛采用RPM软件包更新的压力。
但是仍然还有几个比较新的项目。
— GNU Stow(www.gnu.org/software/stow)在一个保存二进制程序的中心目录里建立很多链接,链接到软件包所在目录里的实际二进制程序上。
— Chrisophe Kalt开发的Swpkg(web.taranis.org/swpkg)是一套工具,能够完成构建一个共享软件库所需要大部分步骤。
— Peter Kristensen的打包管理计划(Pack Management Project)则一开始就雄心勃勃,不仅要提供一个安装软件的系统,而且要能重新对软件打包(着重在Solaris上)。重新打包的这部分目标已经被放弃了,但是在软件工具上的开发工作仍然在继续进行。
— 在瑞士苏黎世理工(Swiss Federal Institute of Technology)里创建的SEPP系统(www.sepp. ee.ethz.ch),它实现了前面讨论的大部分想法。
| 回书目 上一节 下一节 |