II. 系统管理
第6章 配置与调整
6.1概要
正确地配置系统能充分地减少以后维护和升级系统所需的工作量。这章将描述一些FreeBSD系统管理配置的情况。这章也会描述一些用来调整FreeBSD系统最佳性能的参数。
读完这章,你将了解到这些:
为什么和如何在你的硬盘上分配空间,规划和放置文件系统与交换分区。
rc.conf配置文件和/usr/local/etc/rc.d启动系统的基础知识。
如何在你的网络设备上配置虚拟主机。
如何在/etc上使用不同的配置文件。
如何使用sysctl变量调整FreeBSD。
如何调整磁盘的性能和修改内核的限制。
在阅读这章之前你应当:
了解UNIX和FreeBSD的基础知识(第3章)。
熟悉如何与FreeBSD的源代码保持同步(第19章)。
内核配置和编译的基础知识(第9章)。
6.2初步配置
6.2.1分区设计
基本分区
当使用disklabel或sysinstall命令划分你的文件系统时,需要记住,硬盘驱动器从外磁道传输数据要比从内磁道传输数据来得快,这一点很重要。记住这点,你可以把比较小的,经常访问的如root和swap放在靠近外磁道的地方。可以把比较大的分区如/usr放在内磁道上。这样做,按照相同的顺序创建分区是个好主意:root,swap,/var,/usr。
你的/var分区大小能反映你机器的使用状况。/var主要用来存放:邮箱,打印缓存和日志文件。特别是邮箱和日志文件可能会达到一个无法预料的数量,这主要取决于在你的系统上有多少用户和你的日志文件可以保存多长时间。如果你想要运行一个邮件服务器,一个超过G数量级的/var分区是必要的。另外,/var/tmp要足够大,以便于能够包含足够的你可能会添加的package。
/usr分区保存了用于支持系统的大量文件和一个叫做/usr/local的,保存有从ports目录安装的大量文件的子目录。如果你根本不使用port,也不希望把系统源代码(/usr/src)保存在机器上,你可以节省超过1G的/usr分区。然而,如果你安装了许多port(特别是视窗管理器和Linux兼容程序),我们建议至少要为/usr保留2G的空间,如果你也想把系统源代码保存在你的机器上,我们建议为/usr保留3G的空间。不要低估了这个分区所需要的空间的数量,它可能会不断增加,让你非常吃惊!
当你调整分区的大小时,记住你的系统可能会不断增加对空间的需求。在一个分区上用完了空间而在另一个上还有很多,可能会导致出现很多的错误。
注意:一些使用sysinstall的自动默认分区(Auto-defaults)的用户会发现,一段时间以后他们的root或/var分区会变得很小。建议尽可能把分区分得大一些。
交换分区(Swap)
通常你的交换分区应当是主内存的两倍。例如,如果机器有128 M的内存,交换分区应当是256MB。带有比较少内存的机器可以通过增大交换分区来提高机器的性能。我们不建议你配置少于256MB的交换分区,你应当记住将来随着内存的扩充,交换分区也要相应地扩大。当交换分区至少是主内存的两倍时,内核的VM(虚拟内存)页面调度算法才能调节系统到最佳状态。如果给你的机器添加更多的内存,配置太小的交换分区会导致在VM页面中扫描代码效率低下。
最后,在配置有很多SCSI(或IDE)磁盘的较大系统中,强烈建议给每一个磁盘都创建一个交换分区。交换分区应当拥有同样的大小。内核可能会使用任意大小,但内部数据结构则是最大交换分区的4倍。保持交换分区同样的大小,可以允许内核最佳地调度交换空间来访问磁盘。不要为此过分担心,交换空间正是UNIX系统的长处。即使你通常不使用更多的交换空间,在被迫重新启动之前,它可以给你更多的时间从一个失败的程序中恢复。
为什么要分区?
为什么要分区?为什么不创建一个大的根分区?我并不介意大小问题!
有很多原因证实这不是一个好主意。首先,每个分区有不同的操作特性,把它们分开可以允许文件系统去自动调节自己以适应那些特性。例如,根和/usr分区通常是读得比较频繁,写得比较少,而像/var和/var/tmp则读写都比较频繁。
通过适当地划分你的系统,用比较小的分区方法,那些以写为主的分区将不会比以读为主的分区付出更高的代价。另外,将以写为主的分区放在靠近磁盘的边缘,例如放在实际的大硬盘的前面代替放在分区表的后面,将会提高你需要的分区的I/O性能。现在,你可能也需要在比较大的分区上有很好的I/O性能,但它们是如此之大,以至把它们移到磁盘的边缘将不会有一个重大性能的提升,反而,将/var移到磁盘的边缘会有一个好的效果。最后,还关系到安全问题。拥有一个只读的小巧而灵活的分区,可以提高从一个严重的系统崩溃中恢复过来的机会。
6.3核心配置
负责系统配置信息的主要位置是在/etc/rc.conf。这个文件包含了很宽范围的配置信息,在系统启动时主要用来配置系统。它的名字直接表明了这点。配置信息一般是rc*这样类型的文件。
一个系统管理员应当在rc.conf文件中建立一个记录来修改/etc/defaults/rc.conf的默认配置。默认文件不应当被逐字地拷到/etc——它包含默认值,而不是例子。所有系统的特定变化将自己记录在rc.conf文件中。
为了将管理成本降下来,有很多策略可以应用在成群的应用程序中来从系统指定的配置中分离site-wide配置。建议的方法是将site-wide配置放在另一个文件中,例如/etc/rc.conf.site,然后把这个文件包括进只包含系统指定信息的/etc/rc.conf。
由于rc.conf可以被sh命令打开阅读,所以完成这点很简单。例如:
rc.conf:
rc.conf.site
hostname=“node15.webcompany.com”
network_interfaces=“fxp0 lo0”
ifconfig_fxp0=“inet 10.1.1.1”
rc.conf.site:
defaultrouter=“10.1.1.254”
saver=“daemon”
blanktime=“100”
rc.conf.site文件会被分发给每一个使用rsync或相似程序的系统,同时rc.conf文件仍保持独立。通过使用sysinstall或make world来升级系统不会覆盖rc.conf文件,所以系统配置信息不会被丢失。
6.4应用程序配置
典型的,已安装的应用程序有它自己的配置文件,有它自己的语法。这些文件与基本系统相分离是很重要的,以至于它们能被package管理工具很好地定位和管理。另外,这些文件被安装在/usr/local/etc中。在这个例子中,一个应用程序有许多配置文件,还会创建一个子目录来保存它们。
通常,当一个port或package被安装时,默认的配置文件也会被安装。这些通常可以通过“.default”后缀来辨别。如果不存在应用程序的配置文件,它们会通过拷贝.default文件来创建。例如,这儿是/usr/local/etc/apache:
rw-r-r-- 1 root wheel 2184 May 20
1998 access.conf
rw-r-r-- 1 root wheel 2184 May 20
1998 access.conf.default
rw-r-r-- 1 root wheel 9555 May 20
1998 httpd.conf
rw-r-r-- 1 root wheel 9555 May 20
1998 httpd.conf.default
rw-r-r-- 1 root wheel 12205 May 20
1998 magic
rw-r-r-- 1 root wheel 12205 May 20
1998 magic.default
rw-r-r-- 1 root wheel 2700 May 20
1998 mime.types
rw-r-r-- 1 root wheel 2700 May 20
1998 mime.types.default
rw-r-r-- 1 root wheel 7980 May 20
1998 srm.conf
rw-r-r-- 1 root wheel 7933 May 20
1998 srm.conf.default
可以看到只有srm.conf文件已发生了变化。apache port以后的升级就不会修改这个已变化的文件。
6.5启动服务
对一个系统来说,支持许多服务是很普通的。这些可能是用不同的方式来启动的,每一个都有不同的长处。
从ports或packages
collection安装的软件通常把一个脚本放在/usr/local/etc/rc.d中,它会在用start启动系统的时候和在用stop关闭系统的时候被自动调用。这是一种我们推荐使用的将要用root或期望用root来启动服务的方法。这些脚本会作为安装package的一部分被注册,当package被删除的时候,它也会被删除。在/usr/local/etc/rc.d中,一个普通的启动脚本是这样的:
#!/bin/sh
echo -n ' FooBar'
case “$1” in
start)
/usr/local/bin/foobar
;;
stop)
kill -9 'cat /var/run/foobar.pid'
;;
*)
echo “Usage: 'basename $0' {start|stop}” >&2
exit 64
;;
esac
exit 0
这个脚本在启动时用start,在关闭时用stop来呼叫,以完成它的任务。当一个连接被一个相配的port接收到时,一些服务会被inetd所调用。这对邮件阅读服务器(POP,IMAP等)来说是很普通的。这些服务可以通过编辑/etc/inetd.conf文件来启用。可以看看inetd命令的联机手册中有关编辑这个文件的细节。
一些额外的系统服务不太可能会被隐藏在/etc/rc.conf中。这些通常能够使用命令在/etc/rc.local中调用它们。就像在FreeBSD3.1中,没有默认的/etc/rc.local。如果它被系统管理员创建,它将不可能以普通的形式得到尊重。注意rc.local通常被作为是最后一个访问的记录。如果有一个更好的地方能启动一个服务,就在那儿启动。
注意:不要把任何命令都放在/etc/rc.conf中。要启动守护程序,或在启动时运行任何命令,可以在/usr/local/etc/rc.d中添加一行脚本。
使用cron程序来启动系统服务也是可以的。这种方法有很多优势,不仅仅是因为cron能以cortab主人的身份运行这些进程,这些服务也可以被没有root权限的用户来启动和操作。
这利用了cron的一个特性:时钟形式可以用@reboot这种形式来代替,系统启动以后不久,当cron程序运行的时候,工作才会运行。
6.6虚拟主机
FreeBSD的一个非常普通的应用是虚拟主机功能,一台服务器可以虚拟成多台服务器来提供网络服务。这只需要分配多个网络地址给一个简单的接口就可以实现。
一个给定的网络接口有一个真实(real)地址,也会有很多别名(alias)地址。这些别名通常通过在/etc/rc.conf中添加别名记录来得到添加。
一个接口为“fxp0”的别名记录是这样的:
ifconfig_fxp0_alias0=“inet
xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx”
注意别名记录必须用alias0开始,然后按顺序逐步加大,(如_alias1,_alias2依次类推。)配置进程将在第一个缺少数字的地方停止。
别名子网掩码的计算是很重要的,但幸运的是它非常简单。对于一个给定的接口,必须有一个正确反映网络的子网掩码地址。任何属于这个网络的其他地址必须有一个全是1的子网掩码。
例如:假设fxp0接口连接到两个网络,10.1.1.0的子网掩码是255.255.255.0,而202.0.75.16的子网掩码是255.255.255.240。我们要求系统使用从10.1.1.1到10.1.1.5和202.0.75.17到202.0.75.20的网络范围。
下面这些记录将为这个安排正确地配置适配器:
ifconfig_fxp0=“inet 10.1.1.1 netmask 255.255.255.0”
ifconfig_fxp0_alias0=“inet 10.1.1.2 netmask 255.255.255.255”
ifconfig_fxp0_alias1=“inet 10.1.1.3 netmask 255.255.255.255”
ifconfig_fxp0_alias2=“inet 10.1.1.4 netmask 255.255.255.255”
ifconfig_fxp0_alias3=“inet 10.1.1.5 netmask 255.255.255.255”
ifconfig_fxp0_alias4=“inet 202.0.75.17 netmask 255.255.255.240”
ifconfig_fxp0_alias5=“inet 202.0.75.18 netmask 255.255.255.255”
ifconfig_fxp0_alias6=“inet 202.0.75.19 netmask 255.255.255.255”
ifconfig_fxp0_alias7=“inet 202.0.75.20 netmask 255.255.255.255”
6.7配置文件
6.7.1 /etc规划
在配置信息中有很多的目录。这些包括:
/etc |
一般的系统配置信息;这儿的数据是系统指定的。 |
/etc/defaults |
系统配置文件的默认版本。 |
/etc/mail |
除了sendmail之外,还有其他的MTA配置文件。 |
/etc/ppp |
用于用户级和内核级PPP程序的配置。 |
/etc/namedb |
named数据的默认定位。通常启动文件是定位在这儿,在/var/db中包含了一个参考其他数据的指示。 |
/usr/local/etc |
安装应用程序的配置文件。可以参考每个应用程序的子目录。 |
/usr/local/etc/rc.d |
已安装应用程序的启动/停止脚本。 |
/var/db |
稳定的系统指定的数据文件:像named区域文件,数据库文件等等。 |
6.7.2主机名
/etc/resolv.conf
/etc/resolv.conf描述了FreeBSD如何访问internet的域名系统(DNS)。最普通的resolv.conf的记录是:
nameserver |
要查询的域名服务器的IP地址。服务器按照顺序查询。 |
search |
搜索域名的列表。这通常是由本地的域名决定的。 |
domain |
本地域名。 |
一个典型的resolv.conf:
search foobar.com
nameserver 147.11.1.11
nameserver 147.11.100.30
如果你使用DHCP,dhclient通常会用从DHCP服务器接收到的信息重写resolv.conf文件。
/etc/hosts
/etc/hosts是因特网发展早期使用的一个简单的文本数据库。它结合DNS和NIS给IP地址的映射表提供名字。本地的计算机通过一个LAN进行连接,可以作为一个简单的命名目的而放在这儿,以代替设置一个名称服务器。另外,/etc/hosts可以被用来提供一个本地internet名称的记录,减少搜索普通访问名称的需求。
# $FreeBSD$
#
# Host Database
# This file should contain the addresses and aliases
# for local hosts that share this file.
# In the presence of the domain name service or NIS, this file may
# not be consulted at all; see /etc/nsswitch.conf for the resolution
order.
#
#
::1
localhost localhost.my.domain myname.my.domain
127.0.0.1
localhost localhost.my.domain myname.my.domain
#
# Imaginary network.
#10.0.0.2
myname.my.domain myname
#10.0.0.3
myfriend.my.domain myfriend
#
# According to RFC 1918,
you can use the following IP networks for
# private nets which will never be connected to the Internet:
#
#
10.0.0.0 - 10.255.255.255
#
172.16.0.0
- 172.31.255.255
#
192.168.0.0
- 192.168.255.255
#
# In case you want to be able to connect to the Internet, you need
# real official assigned numbers.
PLEASE PLEASE PLEASE do not try
# to invent your own network numbers but instead get one from your
# network provider (if any) or from the Internet Registry (ftp to
# rs.internic.net,
directory '/templates').
#
/etc/hosts使用的简单格式:
[Internet address] [offical hostname]
[alias1] [alias2] ...
例如:
10.0.0.1 myRealHostname.foobar.com
myRealHostname foobar1 foobar2
可以参考hosts的联机手册了解更多信息。
6.7.3日志文件配置
syslog.conf
Syslog.conf是syslogd程序的配置文件。它指出了哪种类型的syslog信息能被记录到特定的日志文件中。
#
$FreeBSD$
#
# Spaces
ARE valid field separators in this file. However,
# other
*nix-like systems still insist on using tabs as field
#
separators. If you are sharing this file between systems, you
# may want
to use only tabs as field separators here.
# Consult
the syslog.conf manpage.
*.err;kern.debug;auth.notice;mail.crit /dev/console
*.notice;kern.debug;lpr.info;mail.crit;news.err
/var/log/messages
security.* /var/log/security
mail.info
/var/log/maillog
lpr.info
/var/log/lpd-errs
cron.*
/var/log/cron
*.err
root
*.notice;news.err
root
*.alert
root
*.emerg
*
#
uncomment this to log all writes to /dev/console to /var/log/console.log
#console.info
/var/log/console.log
#
uncomment this to enable logging of all log messages to /var/log/all.log
#*.*
/var/log/all.log
# uncomment
this to enable logging to a remote loghost named loghost
#*.*
@loghost
#
uncomment these if you're running inn
#
news.crit
/var/log/news/news.crit
#
news.err /var/log/news/news.err
#
news.notice
/var/log/news/news.notice
!startslip
*.*
/var/log/slip.log
!ppp
*.*
/var/log/ppp.log
可以参考syslog.conf的联机手册了解更多信息。
newsyslog.conf
Newsyslog.conf是newsyslog(一个通过cron安排来正常运行的程序)的配置文件。newsyslog决定了什么时候日志文件需要重新存档或整理。Logfile会被移到logfile.0,
logfile.0会被移到logfile.1等等。另外,日志文件也会用gzip格式进行存档。它们是这样命名的:logfiel.0.gz,logfile.1.gz等等。
newsyslog.conf指出了哪个文件需要被管理,有多少需要被保存,什么时候它们会被调用。当它们达到一定大小或到一个适当的周期时,日志文件需要被重新整理。
# configuration file for newsyslog
# $FreeBSD$
#
# logfilename
[owner:group]
mode count size when [ZB] [/pid_file] [sig_num]
/var/log/cron
600 3 100 * Z
/var/log/amd.log
644 7 100 * Z
/var/log/kerberos.log
644 7 100
* Z
/var/log/lpd-errs
644 7 100
* Z
/var/log/maillog
644 7 * @T00
Z
/var/log/sendmail.st
644 10 * 168
B
/var/log/messages
644 5 100 * Z
/var/log/all.log
600 7 * @T00 Z
/var/log/slip.log
600 3 100 * Z
/var/log/ppp.log
600 3 100 * Z
/var/log/security
600 10 100
* Z
/var/log/wtmp
644 3 * @01T05 B
/var/log/daily.log
640 7 * @T00 Z
/var/log/weekly.log
640 5 1 $W6D0 Z
/var/log/monthly.log
640 12 * $M1D0 Z
/var/log/console.log
640 5 100
* Z
看看newsyslog的联机手册了解更多信息。
6.7.4 sysctl.conf
Sysctl.conf看起来很像rc.conf。它的值以这种形式来设置:variable=value。指定的值需要在进入多用户模式时才能被设置。不是所有的变量都以这种模式来设置的。
下面是一个例子:sysctl.conf关闭了重要signal退出时产生的日志,然后让Linux程序知道它们真的运行在FreeBSD下面。
kern.logsigexit=0 #
Do not log fatal signal exits (e.g. sig 11)
compat.Linux.osname=FreeBSD
compat.Linux.osrelease=4.3-STABLE
6.8用sysctl进行调整
sysctl是一个允许你对一个运行着的FreeBSD系统进行修改的接口。这包括许多TCP/IP堆栈和虚拟内存系统的高级选项,它通常可以让一个有经验的系统管理员提高系统的性能。有超过5百个的系统变量能够使用sysctl来阅读和设置。
基于这点,sysctl起到两个功能:阅读和修改系统设置。
要看看所有可读的变量,只要这样:
% sysctl -a
阅读一个特定的变量,例如,kern.maxproc:
% sysctl kern.maxproc
kern.maxproc: 1044
设置一个特定的变量,使用variable= value选项:
# sysctl kern.maxfiles=5000
kern.maxfiles: 2088 -> 5000
Sysctl变量的设置通常不是字符、数字,就是布尔类型的。一个布尔类型的1代表yes,0代表no。
6.9调整磁盘
6.9.1 Sysctl变量
vfs.vmiodirenable
vfs.vmiodirenable sysctl变量默认为0(off),也可以被设置成0(off)或1(on)。这个参数控制着有多少目录可以被系统缓存到。很多目录是比较小,在缓存中只使用一小片段(典型的:1k),甚至更少(典型的:512 bytes)。然而,当在默认的模式下操作时,即使你有很多内存,缓存器也只缓存固定数量的目录。打开这个sysctl可以允许缓存器使用VM页面缓存来缓存目录。这样的优势是所有的内存都能被缓存目录所利用。不利的是最小的用来缓存目录的核心内存要大于512 bytes(典型的是:4K)。如果你正在运行有大量文件处理的服务,我们建议把这个选项打开。这样的服务包括web缓存、大邮件系统和新闻系统。打开这项服务通常不会降低系统的性能,只是会浪费一点内存,但你要仔细检查一下。
hw.ata.wc
FreeBSD 通常把IDE写入缓存关闭掉。这可以减少写入磁盘时需要的带宽。基本上,当写入完成后,IDE基本上就没事了。由于IDE写入缓存被打开,IDE驱动器将不再按顺序把数据写入到硬盘中。当磁盘处于比较大的负荷时,它们通常能缓冲写入的数据。不幸的是,这样会丢失很多性能,最好还是改回默认值。你应当通过观察hw.ata.wc sysctl变量来检查你的系统的默认情况。如果IDE的写入缓存被关闭,你可以在内核变量中把它改回1就可以把它打开。这必须在启动后从引导程序中执行。在内核启动之后再这样做就没有用了。你可以看看ata的联机手册了解更多信息。
6.9.2 SoftUpdates
Tunefs能被用来很好地调整文件系统。这个程序有很多不同的选项,但现在,我们只介绍Soft Updates的打开和关闭,可以这样做:
# tunefs -n enable /filesystem
# tunefs -n disable /filesystem
当一个文件系统被挂上的时候,它是不能使用tunefs进行修改的。在单用户模式下,在所有分区都没有被挂上之前,启用SoftUpdates是最佳时机。
通过使用内存缓冲器,SoftUpdates能够极大地提高文件的性能,主要是文件创建和删除。我们建议在你的所有文件系统上都打开SoftUpdates。你应当清楚两点:第一,SoftUpdates能在系统出现错误时保证系统的一致性,在升级了物理磁盘后可能只需要几秒钟。如果你的系统崩溃了,可能会丢失很多的工作。第二,SoftUpdates可以推迟文件系统块的释放时间。如果你的文件系统快满了,对它作一个主升级,make installworld,可能会超出运行空间,从而引起升级失败。
6.10调整内核限制
6.10.1文件/进程限制
kern.maxfiles
kern.maxfiles可以根据你系统的要求加大或减小。这个变量指出了在你系统上的最大数量的文件描述符。当文件描述符满了时,file: table is full这条语句会在系统信息缓存中重复出现,可以用dmesg来查看文件描述符的情况。
每一个打开的文件,套接字,或fifo使用的文件描述符,都依赖于当前运行的服务的种类和数量。
kern.maxfile的默认值可以在你的内核配置中通过maxusers选项来指定。kern.maxfiles可以按比例地增加maxuser的值。当编译一个定制的内核时,根据你系统的使用情况来设定内核的配置选项是个好主意。从这个数字中,内核给出了绝大多数它预先定义的限制。即使一台机器可能不会有256个用户同时连接过来,所需要的资源仍然可能会与一个高负载的web服务器差不多。
6.10.2网络限制
NMBCLUSTERS内核配置选项指出了系统可用的网络缓存(mbuf)的数量。一个具有大量负载的服务器如果MBUF比较少,就会影响FreeBSD的性能。每一个cluster大概需要2K的内存,所以1024个cluster就需要保留2MB的内存给网络缓存。如果你的服务器超过1000个并发连接,那每个连接需要吃掉一个16k的接收缓存和一个16K的发送缓存,你需要提供32MB的内存给网络缓存以确保web服务器的稳定。一个最笨的计算方法是乘以2,所以32MBx2=64MB/2K
=32768。