linux服务 Systemd 简介
systemctl常用命令介绍
Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器。
Systemd是一个系统管理守护进程、工具和库的集合,用于取代System V初始进程。Systemd的功能是用于集中管理和配置类UNIX系统。
启动及服务
大多数主流发行版要么已经采用 Systemd,要么即将在下个发布中采用(如 Debian 和 Ubuntu)。在本教程中,我们使用 Fedora 21(该发行版已经是 Systemd 的优秀实验场地)的一个预览版进行演示,但不论您用哪个发行版,要用到的命令和注意事项都应该是一样的。这是 Systemd 的一个加分点:它消除了不同发行版之间许多细微且琐碎的区别。
在终端中输入 ps ax | grep systemd
,看到第一行,其中的数字 1 表示它的进程号是1,也就是说它是 Linux 内核发起的第一个程序。因此,内核一旦检测完硬件并组织好了内存,就会运行 /usr/lib/systemd/systemd
可执行程序,这个程序会按顺序依次发起其他程序。(在还没有 Systemd 的日子里,内核会去运行 /sbin/init
,随后这个程序会在名为 SysVinit 的系统中运行其余的各种启动脚本。)
Systemd 的核心是一个叫单元unit的概念,它是一些存有关于服务service(在运行在后台的程序)、设备、挂载点、和操作系统其他方面信息的配置文件。Systemd 的其中一个目标就是简化这些事物之间的相互作用,因此如果你有程序需要在某个挂载点被创建或某个设备被接入后开始运行,Systemd 可以让这一切正常运作起来变得相当容易。(在没有 Systemd 的日子里,要使用脚本来把这些事情调配好,那可是相当丑陋的。)要列出您 Linux 系统上的所有单元,输入以下命令:
systemctl list-unit-files
现在,systemctl
是与 Systemd 交互的主要工具,它有不少选项。在单元列表中,您会注意到这儿有一些格式化:被启用enabled的单元显示为绿色,被禁用disabled的显示为红色。标记为“static”的单元不能直接启用,它们是其他单元所依赖的对象。若要限制输出列表只包含服务,使用以下命令:
systemctl list-unit-files --type=service
注意,一个单元显示为“enabled”,并不等于对应的服务正在运行,而只能说明它可以被开启。要获得某个特定服务的信息,以 GDM (Gnome Display Manager) 为例,输入以下命令:
systemctl status gdm.service
这条命令提供了许多有用的信息:一段给人看的服务描述、单元配置文件的位置、启动的时间、进程号,以及它所从属的 CGroups(用以限制各组进程的资源开销)。
如果您去查看位于 /usr/lib/systemd/system/gdm.service
的单元配置文件,您可以看到各种选项,包括要被运行的二进制文件(“ExecStart”那一行),相冲突的其他单元(即不能同时进入运行的单元),以及需要在本单元执行前进入运行的单元(“After”那一行)。一些单元有附加的依赖选项,例如“Requires”(必要的依赖)和“Wants”(可选的依赖)。
此处另一个有趣的选项是:
Al Alias=display-manager.service
当您启动 gdm.service 后,您将可以通过 systemctl status display-manager.service
来查看它的状态。当您知道有显示管理程序display manager在运行并想对它做点什么,但您不关心那究竟是 GDM,KDM,XDM 还是什么别的显示管理程序时,这个选项会非常有用。
使用 systemctl status 命令后面跟一个单元名,来查看对应的服务有什么情况。
“目标target”锁定
如果您在 /usr/lib/systemd/system
目录中输入 ls
命令,您将看到各种以 .target
结尾的文件。启动目标target是一种将多个单元聚合在一起以致于将它们同时启动的方式。例如,对大多数类 Unix 操作系统而言有一种“多用户multi-user”状态,意思是系统已被成功启动,后台服务正在运行,并且已准备好让一个或多个用户登录并工作——至少在文本模式下。(其他状态包括用于进行管理工作的单用户single-user状态,以及用于机器关机的重启reboot状态。)
如果您打开 multi-user.target 文件一探究竟,您可能期待看到的是一个要被启动的单元列表。但您会发现这个文件内部几乎空空如也——其实,一个服务会通过 WantedBy 选项让自己成为启动目标的依赖。因此如果您去打开 avahi-daemon.service, NetworkManager.service 及其他 .service 文件看看,您将在 Install 段看到这一行:
WantedBy=multi-user.target
因此,切换到多用户启动目标会启用enable那些包含上述语句的单元。还有其他一些启动目标可用(例如 emergency.target 提供一个紧急情况使用的 shell,以及 halt.target 用于机器关机),您可以用以下方式轻松地在它们之间切换:
systemctl isolate emergency.target
在许多方面,这些都很像 SysVinit 中的运行级runlevel,如文本模式的 multi-user.target 类似于第3运行级,graphical.target 类似于第5运行级,reboot.target 类似于第6运行级,诸如此类。
与传统的脚本相比,单元配置文件也许看起来很陌生,但并不难以理解。
开启与停止
现在您也许陷入了沉思:我们已经看了这么多,但仍没看到如何停止和开启服务!这其实是有原因的。从外部看,Systemd 也许很复杂,像野兽一般难以驾驭。因此在您开始摆弄它之前,有必要从宏观的角度看看它是如何工作的。实际用来管理服务的命令非常简单:
systemctl stop cups.service
systemctl start cups.service
(若某个单元被禁用了,您可以先通过 systemctl enable
加上该单元名的方式将其启用。这种做法会为该单元创建一个符号链接,并将其放置在当前启动目标的 .wants
目录下,这些 .wants
目录在/etc/systemd/system
文件夹中。)
还有两个有用的命令是 systemctl restart
和 systemctl reload
,后面接单元名。后者用于让单元重新加载它的配置文件。Systemd 的绝大部分都有良好的文档,因此您可以查看手册 (man systemctl
) 了解每条命令的细节。
定时器单元:取代 Cron
除了系统初始化和服务管理,Systemd 还染指了其他方面。在很大程度上,它能够完成 cron 的工作,而且可以说是以更灵活的方式(并带有更易读的语法)。cron是一个以规定时间间隔执行任务的程序——例如清除临时文件,刷新缓存等。
如果您再次进入 /usr/lib/systemd/system
目录,您会看到那儿有多个 .timer
文件。用 less
来查看这些文件,您会发现它们与 .service
和 .target
文件有着相似的结构,而区别在于 [Timer]
段。举个例子:
[Timer]
OnBootSec=1h
OnUnitActiveSec=1w
OnBootSec 选项告诉 Systemd 在系统启动一小时后启动这个单元。第二个选项的意思是:自那以后每周启动这个单元一次。关于定时器有大量选项您可以设置,输入 man systemd.time
查看完整列表。
Systemd 的时间精度默认为一分钟。也就是说,它会在设定时刻的一分钟内运行单元,但不一定精确到那一秒。这么做是基于电源管理方面的原因,但如果您需要一个没有任何延时且精确到毫秒的定时器,您可以添加以下一行:
AccuracySec=1us
另外, WakeSystem 选项(可以被设置为 true 或 false)决定了定时器是否可以唤醒处于休眠状态的机器。
有一个 Systemd 的图形界面程序,即便它已有多年未被积极维护。
日志文件:向 journald 问声好
Systemd 的第二个主要部分是 journal 。这是个日志系统,类似于 syslog 但也有些显著区别。如果您是个 Unix 日志管理模式的粉丝,准备好出离愤怒吧:这是个二进制日志,因此您不能使用常规的命令行文本处理工具来解析它。这个设计决定不出意料地在网上引起了激烈的争论,但它的确有些优点。例如,日志可以被更系统地组织,带有更多的元数据,因此可以更容易地根据可执行文件名和进程号等过滤出信息。
要查看整个 journal,输入以下命令:
journalctl
像许多其他的 Systemd 命令一样,该命令将输出通过管道的方式引向 less
程序,因此您可以使用空格键向下滚动,键入/
(斜杠)查找,以及其他熟悉的快捷键。您也能在此看到少许颜色,像红色的警告及错误信息。
以上命令会输出很多信息。为了限制其只输出本次启动的消息,使用如下命令:
journalctl -b
这就是 Systemd 大放异彩的地方!您想查看自上次启动以来的全部消息吗?试试 journalctl -b -1 吧。再上一次的?用 -2 替换 -1 吧。那自某个具体时间,例如2014年10月24日16:38以来的呢?
journalctl -b --since=”2014-10-24 16:38”
即便您对二进制日志感到遗憾,那依然是个有用的特性,并且对许多系统管理员来说,构建类似的过滤器比起写正则表达式而言容易多了。
我们已经可以根据特定的时间来准确查找日志了,那可以根据特定程序吗?对单元而言,试试这个:
journalctl -u gdm.service
(注意:这是个查看 X server 产生的日志的好办法。)那根据特定的进程号?
journalctl _PID=890
您甚至可以请求只看某个可执行文件产生的消息:
journalctl /usr/bin/pulseaudio
若您想将输出的消息限制在某个优先级,可以使用 -p 选项。该选项参数为 0 的话只会显示紧急消息(也就是说,是时候向 $DEITY 祈求保佑了)(LCTT 译注: $DEITY 是一个计算机方面的幽默,DEITY 是指广义上的“神”,$前缀表示这是一个变量),为 7 的话会显示所有消息,包括调试消息。请查看手册 (man journalctl
) 获取更多关于优先级的信息。
值得指出的是,您也可以将多个选项结合在一起,若想查看在当前启动中由 GDM 服务输出的优先级数小于等于 3 的消息,请使用下述命令:
journalctl -u gdm.service -p 3 -b
最后,如果您仅仅想打开一个随 journal 持续更新的终端窗口,就像在没有 Systemd 时使用 tail
命令实现的那样,输入 journalctl -f
就好了。
二进制日志并不流行,但 journal 的确有它的优点,如非常方便的信息查找及过滤。
参考:https://linux.cn/article-6888-1.html
更详细的教程可以参考:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
systemd常见命令汇总:
使某服务自动启动 | systemctl enable httpd.service | |
使某服务不自动启动 | systemctl disable httpd.service | |
检查服务状态 |
systemctl status httpd.service (服务详细信息) systemctl is-active httpd.service (仅显示是否 Active) |
|
显示所有已启动的服务 | systemctl list-units --type=service | |
启动某服务 | systemctl start httpd.service | |
停止某服务 | systemctl stop httpd.service | |
重启某服务 | systemctl restart httpd.service |
实例
1.启动nfs服务
systemctl start nfs-server.service
2.设置开机自启动
systemctl enable nfs-server.service
3.停止开机自启动
systemctl disable nfs-server.service
4.查看服务当前状态
systemctl status nfs-server.service
5.重新启动某服务
systemctl restart nfs-server.service
6.查看所有已启动的服务
systemctl list -units --type=service
开启防火墙22端口
iptables -I INPUT -p tcp --dport 22 -j accept
如果仍然有问题,就可能是SELinux导致的
关闭SElinux:
修改/etc/selinux/config
文件中的SELINUX=””
为disabled,然后重启。
彻底关闭防火墙:
sudo systemctl status firewalld.service
sudo systemctl stop firewalld.service
sudo systemctl disable firewalld.service
利用systemctl添加自定义系统服务
systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分,像需要开机不登陆就能运行的程序,还是存在系统服务里吧,即:/usr/lib/systemd/system目录下
每一个服务以.service结尾,一般会分为3部分:[Unit]、[Service]和[Install]
[[email protected] system]# cat ntpdate.service
[Unit]
Description=Set time via NTP
After=syslog.target network.target nss-lookup.target
Before=time-sync.target
Wants=time-sync.target
[Service]
Type=oneshot
ExecStart=/usr/libexec/ntpdate-wrapper
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Unit 描述信息
Description= #描述信息
After= #在那个程序之前启动
Before #在那个程序之后启动
Service 启动信息
Type= #启动类型。
#Type=oneshot :这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于**状态。
#Type=notify :与 Type=simple 相同,但约定服务会在就绪后向 systemd 发送一个信号。这一通知的实现由 libsystemd-daemon.so 提供。
#Type=dbus :若以此方式启动,当指定的 BusName 出现在DBus系统总线上时,systemd认为服务就绪。
#Type=idle :systemd会等待所有任务处理完成后,才开始执行 idle 类型的单元。其他行为与 Type=simple 类似。
#Type=forking :systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。使用此启动类型应同时指定 PIDFile=,以便 systemd 能够跟踪服务的主进程。
#Type=simple :(默认值) systemd认为该服务将立即启动。服务进程不会 fork 。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket **型。
RemainAfterExit=yes #通知systemctl结束
User=
Group=
Restart= #Restart=always的时候systemctl会不断重启这个脚本,这种适合程序是脚本的。
#Restart=no的时候不会重启,适合程序软件。
ExecStart= #后面跟程序的绝对路径,如果有启动参数,后面加上,如果程序没有参数不需要添加ExecStop这条语句
ExecStop= #后面跟程序的绝对路径,如果有停止参数,后面加上
PIDFile= #加上程序PID文件绝对路径
install 安装信息
WantedBy= #WantedBy=multi-user.target(单元被允许运行需要的弱依赖性单元,Wantby从Want列表获得依赖信息。)
重载服务
systemctl enable nginx.service
就会在/etc/systemd/system/multi-user.target.wants/目录下新建一个/usr/lib/systemd/system/nginx.service 文件的链接。
操作服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
参考:http://man.linuxde.net/systemctl