17.1 什么是 daemon 与服务(service)

service(服务):系统为了某些功能必须提供的服务(系统功能或网络功能)。

daemon(守护进程):达成 service 的程序。在背景中运行,提供系统或网络功能。惯例命名:服务名末尾加 d(如 crond, atd, httpd, vsftpd)。

两者不必刻意区分——没有 daemon 就不会有 service,实际使用中视为相同概念。

17.1.1 早期 System V 的 init 管理行为中 daemon 的主要分类(Optional)

CentOS 7 之前使用 SysV init 管理服务,核心概念:

① 服务脚本位置/etc/init.d/daemon,通过 start|stop|restart|status 参数控制。

② 服务启动分类

类型说明特点
stand alone服务独立启动,常驻内存反应快,始终占用资源
super daemon由 xinetd/inetd 总管,有请求时才唤醒对应服务省资源,唤醒有延迟;可做连线控制

③ 执行等级(runlevel)

runlevel模式对应 systemd target
0关机
1单人维护模式rescue.target
3纯文本模式multi-user.target
5图形界面graphical.target

各 runlevel 的启动脚本在 /etc/rc.d/rc[0-6].d/ 下,以 SXXdaemon / KXXdaemon 链接到 /etc/init.d/daemonS = 启动,K = 关闭,XX = 数字顺序。

④ 管理指令

service daemon start/stop/restart/status   # 早期管理服务
chkconfig daemon on/off                    # 设置开机启动
init 3 / init 5                            # 切换 runlevel

17.1.2 systemd 使用的 unit 分类

CentOS 7.x 起用 systemd 取代 SysV init。优势:

特性说明
平行处理所有服务可同时启动,加速开机
按需启动(on-demand)单一 systemd + systemctl 管理,常驻内存,即时响应
相依性自检启动 B 时自动先启动 B 依赖的 A
功能分类将服务定义为不同的 unit type
群组管理将多个 daemon 集合为 target
向下相容兼容旧的 init 启动脚本

systemd 的局限

  • runlevel 仅有 1, 3, 5 有对应
  • systemctl 语法固定,不可自订参数(不像 /etc/init.d/daemon 是纯脚本)
  • 无法侦测手动启动的服务(必须通过 systemctl 启动)
  • 启动过程中无法与管理员通过 stdin 互动

配置文件目录(优先级从低到高)

目录说明
/usr/lib/systemd/system/官方软件安装的默认启动脚本(尽量不要改)
/run/systemd/system/系统执行过程中产生的服务脚本
/etc/systemd/system/管理员自订的执行脚本(优先级最高)

unit 类型分类(看扩展名)

扩展名类型说明
.service系统服务最常见,服务器本机/网络服务
.socket数据插槽服务IPC 传输,监控 socket file,按需唤醒 daemon(类似旧 xinetd)
.target执行环境一群 unit 的集合,类似旧 runlevel
.mount / .automount文件系统挂载自动挂载、NFS 等
.path目录侦测侦测特定目录以启动伫列服务(如打印)
.timer循环执行systemd 内置的定时任务,比 anacrontab 更有弹性

17.2 通过 systemctl 管理服务

所有管理统一使用 systemctl 一个指令。

17.2.1 通过 systemctl 管理单一服务(service unit)的启动/开机启动与观察状态

两阶段概念:“现在要不要启动” vs “开机时要不要启动”,两者独立。

systemctl [command] [unit]
命令说明
start立刻启动
stop立刻关闭
restart关闭后启动(stop + start)
reload不关闭服务,重新加载配置文件
enable设置开机自动启动
disable设置开机不启动
status查看状态(是否启动、开机是否启用、登录信息)
is-active当前是否运行中
is-enabled开机是否默认启用

systemctl status 输出解读

Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled)   ← 开机是否启动
Active: active (running) since ...                               ← 当前状态

Active 状态

状态说明
active (running)正在执行中
active (exited)执行一次就正常结束(如 quotaon),无须常驻内存
active (waiting)执行中但等待其他事件(如打印伫列)
inactive目前没有运行

Loaded 状态(开机启动设置)

状态说明
enabled开机时执行
disabled开机不执行
static不可自己 enable,但可被其他 enabled 服务唤醒
masked强制注销,无论如何都无法启动

⚠️ 不要用 kill 关闭服务!systemctl 无法继续监控被 kill 掉的服务。正规方法是 systemctl stop

mask 与 unmask:强制注销/恢复

systemctl mask cups.service      # 强制注销(链接到 /dev/null)
systemctl unmask cups.service    # 恢复

cups 案例——socket 按需唤醒:即使 disable 了 cups.service,但 cups.socketcups.path 仍可能在被请求时自动唤醒 cups.service。要彻底关闭需三者都 disable+stop,或直接 mask cups.service

17.2.2 通过 systemctl 观察系统上所有的服务

systemctl                           # 等同于 list-units,列出已启动的 unit
systemctl list-units --all          # 含未启动的
systemctl list-units --type=service --all    # 只看 service 类型
systemctl list-unit-files           # 列出所有已安装的 unit(含未启动)
systemctl list-unit-files --type=service     # 只看 service 类型

17.2.3 通过 systemctl 管理不同的操作环境(target unit)

常见 target

target说明
graphical.target图形界面(内含 multi-user.target)
multi-user.target纯文本模式
rescue.target救援模式(额外临时系统)
emergency.target紧急救援模式
shutdown.target关机流程
getty.target管理 tty 数量

管理命令

systemctl get-default                        # 查看默认 target
systemctl set-default multi-user.target      # 设置默认
systemctl isolate graphical.target           # 切换模式(注意:target 用 isolate,不是 start!)
 
# 快捷命令
systemctl poweroff      # 关机
systemctl reboot        # 重启
systemctl suspend       # 暂停(状态存内存,唤醒快)
systemctl hibernate     # 休眠(状态存硬盘,唤醒慢但省电)
systemctl rescue        # 救援模式
systemctl emergency     # 紧急救援模式

⚠️ target 的切换用 isolate不是 start/stopsystemctl stop graphical.target 不会回到 multi-user。

17.2.4 通过 systemctl 分析各服务之间的相依性

systemctl list-dependencies                  # 当前 target 依赖哪些 unit(树状显示)
systemctl list-dependencies --reverse        # 谁依赖当前 target
systemctl list-dependencies graphical.target # 指定 target 的依赖关系

例如 graphical.target = multi-user.target + accounts-daemon + gdm + network 等额外的图形相关服务。

17.2.5 与 systemd 的 daemon 运行过程相关的目录简介

目录用途
/usr/lib/systemd/system/官方默认启动脚本,尽量不修改
/run/systemd/system/运行时产生,优先级高于 /usr/lib
/etc/systemd/system/管理员自订,优先级最高
/etc/sysconfig/*服务的初始化选项(如网络设置、mandb 参数)
/var/lib/服务产生的数据(如 MySQL 数据库)
/run/daemon 暂存盘(lock file, PID file)

查看 socket file 位置

systemctl list-sockets          # 列出所有监听本机的 socket file

/etc/services:记录端口号与服务名的对应关系(纯参考文件,不影响实际运行)。修改它不会改变服务绑定的端口。

17.2.6 关闭网络服务

网络服务 = 会产生网络监听端口(port)的程序。非必要的应关闭。

netstat -tlunp                              # 列出所有监听的网络端口及对应 PID/程序
systemctl list-units --all | grep avahi     # 追踪端口对应的服务
systemctl stop avahi-daemon.service avahi-daemon.socket
systemctl disable avahi-daemon.service avahi-daemon.socket

17.3 systemctl 针对 service 类型的配置文件

17.3.1 systemctl 配置文件相关目录简介

官方建议不修改 /usr/lib/systemd/system/,而是在 /etc/systemd/system/ 下操作:

路径用途
/etc/systemd/system/<name>.service.d/*.conf累加设置到原配置文件
/etc/systemd/system/<name>.service.wants/启动本服务后建议启动的相依服务(链接文件)
/etc/systemd/system/<name>.service.requires/启动本服务前必须启动的服务(链接文件)

17.3.2 systemctl 配置文件的设置项目简介

sshd.service 为例:

[Unit]
Description=OpenSSH server daemon
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
 
[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
 
[Install]
WantedBy=multi-user.target

[Unit] 部分

参数说明
Descriptionsystemctl status 显示的简短说明
Documentation文档位置(URL / man / file)
After在哪个 daemon 启动之后才启动(仅顺序,非强制)
Before在哪个服务启动之前启动(仅顺序,非强制)
Requires强制相依——依赖的服务没启动,本 unit 就不会启动
Wants建议相依——依赖的服务没启动,不影响本 unit
Conflicts冲突服务——互斥,不能同时启动

[Service] 部分

参数说明
Type启动方式:simple(默认,常驻)、forking(产生子程序、父程序退出,传统 daemon)、oneshot(执行完就结束)、dbus(需取得 D-Bus 名称)、idle(最后才执行)
EnvironmentFile启动脚本的环境配置文件
ExecStart实际执行的指令(不接受 <, >, `
ExecStop关闭服务时执行的指令
ExecReloadreload 时执行的指令
Restart服务终止后是否自动重启
RemainAfterExit设为 1 时,所有程序终止后会尝试重启(适合 oneshot)
TimeoutSec启动/关闭超时,多久后强制结束
KillModeprocess(只杀主程序)、control-group(杀所有相关程序)、none
RestartSec重启前等待时间(默认 100ms)

[Install] 部分

参数说明
WantedBy附挂在哪个 target 下(通常是 multi-user.target
Alsoenable 本 unit 时,也一并 enable 指定的 unit
Alias链接别名

17.3.3 两个 vsftpd 运行的实例

需求:同时启动 21 端口和 555 端口两个 vsftpd。

# 1. 准备两个配置文件
cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd2.conf
# vsftpd.conf 还原为 21 端口,vsftpd2.conf 设置 listen_port=555
 
# 2. 复制启动脚本
cp /usr/lib/systemd/system/vsftpd.service /etc/systemd/system/vsftpd2.service
# 修改 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd2.conf
 
# 3. 重载并启动
systemctl daemon-reload
systemctl restart vsftpd.service vsftpd2.service
systemctl enable vsftpd.service vsftpd2.service

17.3.4 多重的重复设置方式:以 getty 为例

@ 模板机制getty@.service 是模板,getty@tty1.service 是实例。systemd 解析流程:

  1. 先找 getty@tty1.service → 若有则执行
  2. 若无则找 getty@.service,将 @ 后面的 tty1 代入为 %I 变量
# getty@.service 中的关键行:
ExecStart=-/sbin/agetty --noclear %I $TERM
# %I 会被替换为 @ 后面的值(如 tty1)

同样,vsftpd@.service 中有 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/%i.conf,可以用 systemctl start vsftpd@vsftpd3.service 直接使用 vsftpd3.conf 启动新实例。

修改 tty 数量:编辑 /etc/systemd/logind.conf 中的 NAutoVTs=4,然后 systemctl restart systemd-logind.service

17.3.5 自己的服务自己作

创建一个备份服务 /etc/systemd/system/backup.service

[Unit]
Description=backup my server
Requires=atd.service
 
[Service]
Type=simple
ExecStart=/bin/bash -c " echo /backups/backup.sh | at now"
 
[Install]
WantedBy=multi-user.target
systemctl daemon-reload       # 重载配置文件
systemctl start backup.service

Type=simple 的脚本执行完就结束,Active 会显示 inactive (dead)——这是正常的。

17.4 systemctl 针对 timer 的配置文件

systemd 内置的定时任务功能,可以替代部分 crontab 场景。

systemd.timer 优势:与 systemd 服务结合,所有信息有 log、可与 cgroup 结合限制资源、精度可达毫秒(cron 仅到分钟)。

劣势:无 email 通知、无 random_delay(anacron 有)。

必要条件

  1. timers.target 必须启动
  2. 有对应的 xxx.service
  3. xxx.timer 配置文件

[Timer] 参数

参数说明
OnActiveSectimers.target 启动后多久执行
OnBootSec开机完成后多久执行
OnStartupSecsystemd 第一次启动后多久执行
OnUnitActiveSec该 service 上次启动后隔多久再执行
OnUnitInactiveSec该 service 上次停止后隔多久再执行
OnCalendar使用实际日历时间(非相对时间),格式:英文周名 YYYY-MM-DD HH:MM:SS
Persistent配合 OnCalendar,补执行错过的任务(类似 anacron),应设为 true
Unit指定对应的 service(默认同名)

OnCalendar 时间格式

格式说明示例
now立即
hourly / daily / weekly / monthly每小时/每天/每周/每月daily = *-*-* 00:00:00
间隔时间10s 300m 2days2hrs = 2 小时
指定时间Sun *-*-* 02:00:00每周日凌晨 2 点

OnCalendar 对照的是 Unix 标准时间(1970-01-01),不是 timers.target 启动时间。

示例:每两天执行一次备份

# /etc/systemd/system/backup.timer
[Unit]
Description=backup my server timer
 
[Timer]
OnBootSec=2hrs
OnUnitActiveSec=2days
 
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable backup.timer      # 注意:enable 的是 timer 不是 service!
systemctl restart backup.timer

示例:每周日凌晨 2 点备份

[Timer]
OnCalendar=Sun *-*-* 02:00:00
Persistent=true
Unit=backup.service

17.5 CentOS 7.x 默认启动的服务简易说明

核心系统服务(不可关闭)

服务功能
auditdSELinux 稽核信息写入 /var/log/audit/audit.log
crond例行性工作调度
dbus应用程序间讯息传递
dm-event / multipathd设备对应表监控
irqbalance多核心硬件 IRQ 分配
lvm2-*LVM 管理
rsyslog系统登录文件记录(绝不能关
smartd硬盘状态自动侦测
systemd-*系统运行所需
postfix寄件服务(cron/atd 会通过它发 email)

可考虑关闭的服务(服务器场景)

服务原因
avahi-daemon区网 Zeroconf 服务,桌面用
cups打印服务
alsa-*音效相关
gdm图形登陆管理(无图形界面可关)
hyper* / libvirt*虚拟机相关
kdump核心错误内存记录(非核心开发者可不启动)
iscsi*网络磁盘挂载(没用 SAN 可关)

重要网络服务

服务端口功能
sshd22远端连线(不能关)
httpd80WWW 服务器
vsftpd21FTP 服务器
named53DNS 服务器
dovecot110/143POP3/IMAP 收信
nfs2049Unix 网络文件系统
smb139/445Windows 网上邻居
firewalld防火墙(取代 iptables)