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/daemon。S = 启动,K = 关闭,XX = 数字顺序。
④ 管理指令:
service daemon start/stop/restart/status # 早期管理服务
chkconfig daemon on/off # 设置开机启动
init 3 / init 5 # 切换 runlevel17.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.socket 和 cups.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/stop!systemctl 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.socket17.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] 部分:
| 参数 | 说明 |
|---|---|
Description | systemctl 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 | 关闭服务时执行的指令 |
ExecReload | reload 时执行的指令 |
Restart | 服务终止后是否自动重启 |
RemainAfterExit | 设为 1 时,所有程序终止后会尝试重启(适合 oneshot) |
TimeoutSec | 启动/关闭超时,多久后强制结束 |
KillMode | process(只杀主程序)、control-group(杀所有相关程序)、none |
RestartSec | 重启前等待时间(默认 100ms) |
[Install] 部分:
| 参数 | 说明 |
|---|---|
WantedBy | 附挂在哪个 target 下(通常是 multi-user.target) |
Also | enable 本 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.service17.3.4 多重的重复设置方式:以 getty 为例
@ 模板机制:getty@.service 是模板,getty@tty1.service 是实例。systemd 解析流程:
- 先找
getty@tty1.service→ 若有则执行 - 若无则找
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.targetsystemctl daemon-reload # 重载配置文件
systemctl start backup.serviceType=simple 的脚本执行完就结束,Active 会显示
inactive (dead)——这是正常的。
17.4 systemctl 针对 timer 的配置文件
systemd 内置的定时任务功能,可以替代部分 crontab 场景。
systemd.timer 优势:与 systemd 服务结合,所有信息有 log、可与 cgroup 结合限制资源、精度可达毫秒(cron 仅到分钟)。
劣势:无 email 通知、无 random_delay(anacron 有)。
必要条件:
timers.target必须启动- 有对应的
xxx.service - 有
xxx.timer配置文件
[Timer] 参数:
| 参数 | 说明 |
|---|---|
OnActiveSec | timers.target 启动后多久执行 |
OnBootSec | 开机完成后多久执行 |
OnStartupSec | systemd 第一次启动后多久执行 |
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 2days | 2hrs = 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.targetsystemctl daemon-reload
systemctl enable backup.timer # 注意:enable 的是 timer 不是 service!
systemctl restart backup.timer示例:每周日凌晨 2 点备份:
[Timer]
OnCalendar=Sun *-*-* 02:00:00
Persistent=true
Unit=backup.service17.5 CentOS 7.x 默认启动的服务简易说明
核心系统服务(不可关闭):
| 服务 | 功能 |
|---|---|
auditd | SELinux 稽核信息写入 /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 可关) |
重要网络服务:
| 服务 | 端口 | 功能 |
|---|---|---|
sshd | 22 | 远端连线(不能关) |
httpd | 80 | WWW 服务器 |
vsftpd | 21 | FTP 服务器 |
named | 53 | DNS 服务器 |
dovecot | 110/143 | POP3/IMAP 收信 |
nfs | 2049 | Unix 网络文件系统 |
smb | 139/445 | Windows 网上邻居 |
firewalld | — | 防火墙(取代 iptables) |