系统服务 (daemons)
系统为了某些功能必须要提供一些服务 (不论是系统本身还是网络方面),这个服务就称为 service 。 但是 service 的提供总是需要程序的运行吧!否则如何运行呢?所以达成这个 service 的程序我们就称呼他为 daemon 啰! 举例来说,达成循环型例行性工作排程服务 (service) 的程序为 crond 这个 daemon 啦!本节节选自 鸟哥的 Linux 私房菜 -- 基础学习篇目录 第十八章、认识系统服务 (daemons)
daemon 的主要分类
如果依据 daemon 的启动与管理方式来区分,基本上,可以将 daemon 分为可独立启动的 stand alone , 与透过一支 super daemon 来统一管理的服务这两大类,这两类 daemon 的说明如下:
- stand_alone:此 daemon 可以自行单独启动服务
就字面上的意思来说,stand alone 就是『独立的启动』的意思。这种类型的 daemon 可以自行启动而不必透过其他机制的管理; daemon 启动并加载到内存后就一直占用内存与系统资源。最大的优点就是:因为是一直存在内存内持续的提供服务, 因此对于发生客户端的要求时,stand alone 的 daemon 响应速度较快。常见的 stand alone daemon 有 WWW 的 daemon (httpd)、FTP 的 daemon (vsftpd) 等等。
- super daemon: 一支特殊的 daemon 来统一管理
这一种服务的启动方式则是藉由一个统一的 daemon 来负责唤起服务!这个特殊的 daemon 就被称为 super daemon 。 早期的 super daemon 是 inetd 这一个,后来则被 xinetd 所取代了。这种机制比较有趣的地方在于, 当没有客户端的要求时,各项服务都是未启动的情况,等到有来自客户端的要求时, super daemon 才唤醒相对应的服务。当客户端的要求结束后,被唤醒的这个服务也会关闭并释放系统资源。
这种机制的好处是: (1)由于 super daemon 负责唤醒各项服务,因此 super daemon 可以具有安全控管的机制,就是类似网络防火墙的功能啦! (2)由于服务在客户端的联机结束后就关闭,因此不会一直占用系统资源。但是缺点是什么呢? 因为有客户端的联机才会唤醒该服务,而该服务加载到内存的时间需要考虑进去,因此服务的反应时间会比较慢一些啦!
服务与端口的对应
为了统一整个因特网的端口号对应服务的功能,好让所有的主机都能够使用相同的机制来提供服务与要求服务, 所以就有了『通讯协议』这玩意儿。也就是说,有些约定俗成的服务都放置在同一个埠号上面啦!举例来说, 网址列上面的 http 会让浏览器向 WWW 服务器的 80 埠号进行联机的要求!而 WWW 服务器也会将 httpd 这个软件激活在 port 80, 这样两者才能够达成联机的!
嗯!那么想一想,系统上面有没有什么配置可以让服务与埠号对应在一起呢?那就是 /etc/services 啦!
[root@www ~]# cat /etc/services ....(前面省略).... ftp 21/tcp ftp 21/udp fsp fspd ssh 22/tcp # SSH Remote Login Protocol ssh 22/udp # SSH Remote Login Protocol ....(中间省略).... http 80/tcp www www-http # WorldWideWeb HTTP http 80/udp www www-http # HyperText Transfer Protocol ....(底下省略).... # 这个文件的内容是以底下的方式来编排的: # <daemon name> <port/封包协议> <该服务的说明>
daemon 的启动脚本与启动方式
提供某个服务的 daemon 虽然只是一支程序而已,但是这支 daemon 的启动还是需要运行档、配置文件、运行环境等等, 举例来说,你可以查阅一下 httpd 这个程序 (man httpd) ,里面可谈到不少的选项与参数呢!此外,为了管理上面的方便, 所以通常 distribution 都会记录每一支 daemon 启动后所取得程序的 PID 在 /var/run/ 这个目录下呢! 还有还有,在启动这些服务之前,你可能也要自行处理一下 daemon 能够顺利运行的环境是否正确等等。鸟哥这里要讲的是, 要启动一支 daemon 考虑的事情很多,并非单纯运行一支程序就够了。
为了解决上面谈到的问题,因此通常 distribution 会给我们一个简单的 shell script 来进行启动的功能。 该 script 可以进行环境的侦测、配置文件的分析、PID 文件的放置,以及相关重要交换文件案的锁住 (lock) 动作, 你只要运行该 script ,上述的动作就一口气连续的进行,最终就能够顺利且简单的启动这个 daemon 啰!
那么这些 daemon 的启动脚本 (shell script) 放在哪里啊? 以及某些重要的配置文件又是放置到哪里?基本上是放在这些地方:
- /etc/init.d/* :启动脚本放置处
系统上几乎所有的服务启动脚本都放置在这里!事实上这是公认的目录,我们的 CentOS 实际上放置在 /etc/rc.d/init.d/ 啦! 不过还是有配置连结档到 /etc/init.d/ 的!既然这是公认的目录,因此建议您记忆这个目录即可! - /etc/sysconfig/* :各服务的初始化环境配置文件
几乎所有的服务都会将初始化的一些选项配置写入到这个目录下,举例来说,登录档的 syslog 这支 daemon 的初始化配置就写入在 /etc/sysconfig/syslog 这里呢!而网络的配置则写在 /etc/sysconfig/network 这个文件中。 所以,这个目录内的文件也是挺重要的; - /etc/xinetd.conf, /etc/xinetd.d/* :super daemon 配置文件
super daemon 的主要配置文件 (其实是默认值) 为 /etc/xinetd.conf ,不过我们上面就谈到了, super daemon 只是一个统一管理的机制,他所管理的其他 daemon 的配置则写在 /etc/xinetd.d/* 里头喔! - /etc/* :各服务各自的配置文件
- /var/lib/* :各服务产生的数据库
一些会产生数据的服务都会将他的数据写入到 /var/lib/ 目录中。举例来说,数据库管理系统 MySQL 的数据库默认就是写入 /var/lib/mysql/ 这个目录下啦! - /var/run/* :各服务的程序之 PID 记录处
既然 daemon 是程序,所以当然也可以利用 kill 或 killall 来管理啦!不过为了担心管理时影响到其他的程序, 因此 daemon 通常会将自己的 PID 记录一份到 /var/run/ 当中!例如登录文件的 PID 就记录在 /var/run/syslogd.pid 这个文件中。如此一来, /etc/init.d/syslog 就能够简单的管理自己的程序啰。
Stand alone 的 /etc/init.d/* 启动
刚刚谈到了几乎系统上面所有服务的启动脚本都在 /etc/init.d/ 底下,这里面的脚本会去侦测环境、搜寻配置文件、 加载 distribution 提供的函数功能、判断环境是否可以运行此 daemon 等等,等到一切都侦测完毕且确定可以运行后, 再以 shell script 的 case....esac 语法来启动、关闭、 观察此 daemon 喔!我们可以简单的以 /etc/init.d/syslog 这个登录档启动脚本来进行说明:
由于系统的环境都已经帮你制作妥当,所以利用 /etc/init.d/* 来启动、关闭与观察,就非常的简单!话虽如此, CentOS 还是有提供另外一支可以启动 stand alone 服务的脚本喔,那就是 service 这个程序。 其实 service 仅是一支 script 啦,他可以分析你下达的 service 后面的参数,然后根据你的参数再到 /etc/init.d/ 去取得正确的服务来 start 或 stop 哩!他的语法是这样的啦:[root@www ~]# /etc/init.d/syslog 用法: /etc/init.d/syslog {start|stop|status|restart|condrestart} # 什么参数都不加的时候,系统会告诉你可以用的参数有哪些,如上所示。 范例一:观察 syslog 这个 daemon 目前的状态 [root@www ~]# /etc/init.d/syslog status syslogd (pid 4264) 正在运行... klogd (pid 4267) 正在运行... # 代表 syslog 管理两个 daemon ,这两个 daemon 正在运行中啦! 范例二:重新让 syslog 读取一次配置文件 [root@www ~]# /etc/init.d/syslog restart 正在关闭核心记录器: [ 确定 ] 正在关闭系统记录器: [ 确定 ] 正在启动系统记录器: [ 确定 ] 正在启动核心记录器: [ 确定 ] [root@www ~]# /etc/init.d/syslog status syslogd (pid 4793) 正在运行... klogd (pid 4796) 正在运行... # 因为重新启动过,所以 PID 与第一次观察的值就不一样了!这样了解乎?[root@www ~]# service [service name] (start|stop|restart|...) [root@www ~]# service --status-all 选项与参数: service name:亦即是需要启动的服务名称,需与 /etc/init.d/ 对应; start|... :亦即是该服务要进行的工作。 --status-all:将系统所有的 stand alone 的服务状态通通列出来 范例三:重新启动 crond 这支 daemon : [root@www ~]# service crond restart [root@www ~]# /etc/init.d/crond restart # 这两种方法随便你用哪一种来处理都可以!不过鸟哥比较喜欢使用 /etc/init.d/* 范例四:显示出目前系统上面所有服务的运行状态 [root@www ~]# service --status-all acpid (pid 4536) 正在运行... anacron 已停止 atd (pid 4694) 正在运行... ....(底下省略)....
Super daemon 的启动方式
其实 Super daemon 本身也是一支 stand alone 的服务,因为 super daemon 要管理后续的其他服务嘛,他当然自己要常驻在内存中啦!所以 Super daemon 自己启动的方式与 stand alone 是相同的! 但是他所管理的其他 daemon 就不是这样做啰!必须要在配置文件中配置为启动该 daemon 才行。配置文件就是 /etc/xinetd.d/* 的所有文件。那如何得知 super daemon 所管理的服务是否有启动呢?你可以这样做:
因为 disable 是『取消』的意思,因此如果『 disable = yes 』则代表取消此项服务的启动,如果是『 disable = no 』 才是有启动该服务啦!(Minimal版本内没有Super daemon 的软件,查看时没有任何东西)[root@www ~]# grep -i 'disable' /etc/xinetd.d/* ....(前面省略).... /etc/xinetd.d/rsync: disable = yes /etc/xinetd.d/tcpmux-server: disable = yes /etc/xinetd.d/time-dgram: disable = yes /etc/xinetd.d/time-stream: disable = yes关于super daemon 的配置文件请详见解析 super daemon 的配置文件 。
系统开启的服务
使用 netstat 这个网络状态观察命令来检查我们的 port 呢!甚至他也可以帮我们找到该 port 的程序呢 (PID)!
范例一:找出目前系统开启的『网络服务』有哪些? [root@www ~]# netstat -tulp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 www.vbird.tsai:2208 *:* LISTEN 4575/hpiod tcp 0 0 *:737 *:* LISTEN 4371/rpc.statd tcp 0 0 *:sunrpc *:* LISTEN 4336/portmap tcp 0 0 www.vbird.tsai:ipp *:* LISTEN 4606/cupsd tcp 0 0 www.vbird.tsai:smtp *:* LISTEN 4638/sendmail: acce tcp 0 0 *:ssh *:* LISTEN 4595/sshd udp 0 0 *:filenet-tms *:* 4755/avahi-daemon: ....(底下省略).... # 看一下上头, Local Address 的地方会出现主机名与服务名称的,要记得的是, # 可以加上 -n 来显示 port number ,而服务名称与 port 对应则在 /etc/services 范例二:找出所有的有监听网络的服务 (包含 socket 状态): [root@www ~]# netstat -lnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 4575/hpiod ....(中间省略).... Active UNIX domain sockets (only servers) Proto RefCnt Flags Type State I-Node PID/Program name Path ....(中间省略).... unix 2 [ ACC ] STREAM LISTENING 10624 4701/xfs /tmp/.font-unix/fs7100 unix 2 [ ACC ] STREAM LISTENING 12824 5015/Xorg /tmp/.X11-unix/X0 unix 2 [ ACC ] STREAM LISTENING 12770 4932/gdm-binary /tmp/.gdm_socket ....(以下省略).... # 仔细的瞧一瞧啊,除了原有的网络监听 port 之外,还会有 socket 显示在上面, # 我们可以清楚的知道有哪些服务被启动呢! 范例三:观察所有的服务状态 [root@www ~]# service --status-all
配置启动后立即启动服务的方法
我们使用 netstat 仅能观察到目前已经启动的 daemon ,使用 service 这个命令或者是『 /etc/init.d/* start 』的方法则仅能在目前的环境下立即启动某个服务而已。 那么重新启动后呢?该服务是否还是继续的自动启动?这个时候我们就得要了解一下,到底我的 Linux 主机是怎么启动的呢?
- 打开计算机电源,开始读取 BIOS 并进行主机的自我测试;
- 透过 BIOS 取得第一个可启动装置,读取主要启动区 (MBR) 取得启动管理程序;
- 透过启动管理程序的配置,取得 kernel 并加载内存且侦测系统硬件;
- 核心主动呼叫 init 程序;
- init 程序开始运行系统初始化 (/etc/rc.d/rc.sysinit)
- 依据 init 的配置进行 daemon start (/etc/rc.d/rc[0-6].d/*)
- 加载本机配置 (/etc/rc.d/rc.local)
由上面的流程你可以看到系统服务在启动时就可以被启动的地方是在第六个步骤,而事实上第六个步骤就是以不同的运行等级呼叫不同的服务啦! 那么什么叫做运行等级呢?
我们在启动 Linux 系统时,可以进入不同的模式喔,这模式我们称为运行等级 (run level)。不同的运行等级有不同的功能与服务, 目前你先知道正常的运行等级有两个,一个是具有 X 窗口接口的 run level 5 ,另一个则是纯文本界面的 run level 3。
- chkconfig: 管理系统服务默认启动启动与否
[root@www ~]# chkconfig --list [服务名称] [root@www ~]# chkconfig [--level [0123456]] [服务名称] [on|off] 选项与参数: --list :仅将目前的各项服务状态栏出来 --level:配置某个服务在该 level 下启动 (on) 或关闭 (off) 范例一:列出目前系统上面所有被 chkconfig 管理的服务 [root@www ~]# chkconfig --list |more NetworkManager 0:off 1:off 2:off 3:off 4:off 5:off 6:off acpid 0:off 1:off 2:off 3:on 4:on 5:on 6:off ....(中间省略).... yum-updatesd 0:off 1:off 2:on 3:on 4:on 5:on 6:off xinetd based services: <==底下为 super daemon 所管理的服务 chargen-dgram: off chargen-stream: off ....(底下省略).... # 你可以发现上面的表格有分为两个区块,一个具有 1, 2, 3 等数字,一个则被 xinetd # 管理。没错!从这里我们就能够发现服务有 stand alone 与 super daemon 之分。 范例二:显示出目前在 run level 3 为启动的服务 [root@www ~]# chkconfig --list | grep '3:on' 范例三:让 atd 这个服务在 run level 为 3, 4, 5 时启动: [root@www ~]# chkconfig --level 345 atd on
chkconfig 是否很容易管理我们所需要的服务呢?真的很方便啦~ 你可以轻松的透过 chkconfig 来管理 super daemon 的服务喔!另外,你得要知道的是, chkconfig 仅是配置启动时默认会启动的服务而已, 所以该服务目前的状态如何是不知道的。我们举个底下的例子来说明好了:上面的范例四并没有启动 httpd 的原因很简单,因为我们并没有使用 /etc/init.d/httpd start 嘛!我们仅是配置启动时启动而已啊!那我们又没有重新启动,所以当然使用 chkconfig 并不会导致该服务立即被启动!也不会让该服务立即被关闭,而是只有在启动时才会被加载或取消加载而已喔。而既然 chkconfig 可以配置启动是否启动,那么我们能不能用来管理 super daemon 的启动与关闭呢?非常好!我们就来试看看底下的案例:范例四:先观察 httpd ,再观察默认有无启动,之后以 chkconfig 配置为默认启动 [root@www ~]# /etc/init.d/httpd status httpd 已停止 <==根本就没有启动 [root@www ~]# chkconfig --list httpd httpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off # 原因是默认并没有启动啊! [root@www ~]# chkconfig httpd on; chkconfig --list httpd httpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off # 已经配置为『启动默认启动』了,再来观察看看到底该服务启动没? [root@www ~]# /etc/init.d/httpd status httpd 已停止 # 哈!竟然还是没有启动喔!怎么会这样啊?范例五:查阅 rsync 是否启动,若要将其关闭该如何处理? [root@www ~]# /etc/init.d/rsync status -bash: /etc/init.d/rsync: No such file or directory # rsync 是 super daemon 管理的,所以当然不可以使用 stand alone 的启动方式来观察 [root@www ~]# netstat -tlup | grep rsync tcp 0 0 192.168.201.110:rsync *:* LISTEN 4618/xinetd tcp 0 0 www.vbird.tsai:rsync *:* LISTEN 4618/xinetd [root@www ~]# chkconfig --list rsync rsync on <==默认启动呢!将它处理成默认不启动吧 [root@www ~]# chkconfig rsync off; chkconfig --list rsync rsync off <==看吧!关闭了喔!现在来处理一下 super daemon 的东东! [root@www ~]# /etc/init.d/xinetd restart; netstat -tlup | grep rsync最后一个命令你会发现原本 rsync 不见了!这样是否很轻易的就能够启动与关闭你的 super daemon 管理的服务呢!
- chkconfig: 配置自己的系统服务
[root@www ~]# chkconfig [--add|--del] [服务名称] 选项与参数: --add :添加一个服务名称给 chkconfig 来管理,该服务名称必须在 /etc/init.d/ 内 --del :删除一个给 chkconfig 管理的服务如果我自己写了一个程序并且想要让该程序成为系统服务好让 chkconfig 来管理时, 可以怎么进行呢?只要将该服务加入 init 可以管理的 script 当中,亦即是 /etc/init.d/ 当中即可。 举个例子,我们在 /etc/init.d/ 里面创建一个 myvbird 文件,该文件仅是一个简单的服务范例,基本上,没有任何用途.... 对于该文件的必须性是这样的:
- myvbird 将在 run level 3 及 5 启动;
- myvbird 在 /etc/rc.d/rc[35].d 当中启动时,以 80 顺位启动,以 70 顺位结束。
关于所谓的顺位问题,我们会在第二十章介绍,这里你先看看即可。 你该如何进行呢?可以这样做:
这个文件很好玩喔!你可以参考你自己系统上面的文件;基本上,比较重要的是第二行,他的语法是: 『 chkconfig: [runlevels] [启动顺位] [停止顺位] 』其中, runlevels 为不同的 run level 状态,启动顺位 (start number) 与 结束顺位 (stop number) 则是在 /etc/rc.d/rc[35].d 内创建以 S80myvbird 及 K70myvbird 为档名的配置方式![root@www ~]# vim /etc/init.d/myvbird #!/bin/bash # chkconfig: 35 80 70 # description: 没啥!只是用来作为练习之用的一个范例 echo "Nothing"[root@www ~]# chkconfig --list myvbird service myvbird supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add myvbird') # 尚未加入 chkconfig 的管理机制中!所以需要再动点手脚 [root@www ~]# chkconfig --add myvbird; chkconfig --list myvbird myvbird 0:off 1:off 2:off 3:on 4:off 5:on 6:off # 看吧!加入了 chkconfig 的管理当中了! # 很有趣吧!如果要将这些数据都删除的话,那么就下达这样的情况: [root@www ~]# chkconfig --del myvbird [root@www ~]# rm /etc/init.d/myvbird