【BASH】回顾与知识点梳理(三十四)

【BASH】回顾与知识点梳理 三十四

    • 三十四. 认识系统服务(二)
      • 34.1 systemctl 针对 service 类型的配置文件
        • systemctl 配置文件相关目录简介
        • systemctl 配置文件的设定项目简介
          • [Unit] 部份
          • [Service] 部份
          • [Install] 部份
        • 两个 vsftpd 运作的实例
        • 多重的重复设定方式:以 getty 为例
          • 将 tty 的数量由 6 个降低到 4 个
          • 暂时新增 vsftpd 到 2121 埠口
        • 自己的服务自己作
      • 34.2 systemctl 针对 timer 的配置文件
        • systemd.timer 的优势
        • 任务需求
          • [Timer] 部份
        • 使用于 OnCalendar 的时间
        • 一个循环时间运作的案例
        • 一个固定日期运作的案例
      • 34.3 CentOS 7.x 预设启动的服务简易说明
        • CentOS 7.x 预设启动的服务内容
        • 其他服务的简易说明

该系列目录 --> 【BASH】回顾与知识点梳理(目录)

三十四. 认识系统服务(二)

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

以前,我们如果想要建立系统服务,就得要到 /etc/init.d/ 底下去建立相对应的 bash shell script 来处理。那么现在 systemd 的环境底下, 如果我们想要设定相关的服务启动环境,那应该如何处理呢?这就是本小节的任务啰!

systemctl 配置文件相关目录简介

现在我们知道服务的管理是透过 systemd,而 systemd 的配置文件大部分放置于/usr/lib/systemd/system/ 目录内。但是 Red Hat 官方文件指出, 该目录的文件主要是原本软件所提供的设定,建议不要修改!而要修改的位置应该放置于 /etc/systemd/system/ 目录内。举例来说,如果你想要额外修改 vsftpd.service 的话, 他们建议要放置到哪些地方呢?

  • /usr/lib/systemd/system/vsftpd.service:官方释出的预设配置文件;
  • /etc/systemd/system/vsftpd.service.d/custom.conf:在 /etc/systemd/system 底下建立与配置文件相同文件名的目录,但是要加上 .d 的扩展名。然后在该目录下建立配置文件即可。另外,配置文件最好附档名取名为 .conf 较佳! 在这个目录下的文件会『累加其他设定』进入 /usr/lib/systemd/system/vsftpd.service 内喔!
  • /etc/systemd/system/vsftpd.service.wants/*:此目录内的文件为链接档,设定相依服务的连结。意思是启动了vsftpd.service 之后,最好再加上这目录底下建议的服务。
  • /etc/systemd/system/vsftpd.service.requires/*:此目录内的文件为链接档,设定相依服务的连结。意思是在启动 vsftpd.service 之前,需要事先启动哪些服务的意思。

基本上,在配置文件里面你都可以自由设定相依服务的检查,并且设定加入到哪些 target 里头去。但是如果是已经存在的配置文件,或者是官方提供的配置文件,Red Hat 是建议你不要修改原设定,而是到上面提到的几个目录去进行额外的客制化设定比较好!当然,这见仁见智~如果你硬要修改原始的 /usr/lib/systemd/system 底下的配置文件,那也是 OK 没问题的!并且也能够减少许多配置文件的增加~鸟哥自己认为,这样也不错!反正,就完全是个人喜好啰~

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

了解了配置文件的相关目录与文件之后,再来,当然得要了解一下配置文件本身的内容了!让我们先来瞧一瞧 sshd.service 的内容好了! 原本想拿 vsftpd.service 来讲解,不过该文件的内容比较阳春,还是看一下设定项目多一些的 sshd.service 好了!

[root@study ~]# cat /usr/lib/systemd/system/sshd.service
[Unit] # 这个项目与此 unit 的解释、执行服务相依性有关
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
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] # 这个项目说明此 unit 要挂载哪个 target 底下
WantedBy=multi-user.target

分析上面的配置文件,我们大概能够将整个设定分为三个部份,就是:

  • [Unit]: unit 本身的说明,以及与其他相依 daemon 的设定,包括在什么服务之后才启动此 unit 之类的设定值;
  • [Service], [Socket], [Timer], [Mount], [Path]…:不同的 unit type 就得要使用相对应的设定项目。我们拿的是sshd.service 来当模板,所以这边就使用 [Service] 来设定。 这个项目内主要在规范服务启动的脚本、环境配置文件档名、重新启动的方式等等。
  • [Install]:这个项目就是将此 unit 安装到哪个 target 里面去的意思!

至于配置文件内有些设定规则还是得要说明一下:

  • 设定项目通常是可以重复的,例如我可以重复设定两个 After 在配置文件中,不过,后面的设定会取代前面的喔!因此,如果你想要将设定值归零, 可以使用类似『 After= 』的设定,亦即该项目的等号后面什么都没有,就将该设定归零了 (reset)。
  • 如果设定参数需要有『是/否』的项目 (布尔值, boolean),你可以使用 1, yes, true, on 代表启动,用 0, no, false, off 代表关闭!随你喜好选择啰!
  • 空白行、开头为 # ;的那一行,都代表批注!

每个部份里面还有很多的设定细项,我们使用一个简单的表格来说明每个项目好了!

[Unit] 部份
设定参数 参数意义说明
Description 就是当我们使用 systemctl list-units 时,会输出给管理员看的简易说明!当然,使用 systemctl status 输出的此服务的说明,也是这个项目!
Documentation 这个项目在提供管理员能够进行进一步的文件查询的功能!提供的文件可以是如下的资料:
- Documentation=http://www…
- Documentation=man:sshd(8)
- Documentation=file:/etc/ssh/sshd_config
After 说明此 unit 是在哪个 daemon 启动之后才启动的意思!基本上仅是说明服务启动的顺序而已,并没有强制要求里头的服务一定要启动后此 unit 才能启动。 以 sshd.service 的内容为例,该文件提到 After 后面有 network.target 以及 sshd-keygen.service,但是若这两个 unit 没有启动而强制启动 sshd.service 的话, 那么 sshd.service 应该还是能够启动的!这与 Requires 的设定是有差异的喔!
Before 与 After 的意义相反,是在什么服务启动前最好启动这个服务的意思。不过这仅是规范服务启动的顺序,并非强制要求的意思。
Requires 明确的定义此 unit 需要在哪个 daemon 启动后才能够启动!就是设定相依服务啦!如果在此项设定的前导服务没有启动,那么此 unit 就不会被启动!
Wants 与 Requires 刚好相反,规范的是这个 unit 之后最好还要启动什么服务比较好的意思!不过,并没有明确的规范就是了!主要的目的是希望建立让使用者比较好操作的环境。 因此,这个 Wants 后面接的服务如果没有启动,其实不会影响到这个 unit 本身!
Conflicts 代表冲突的服务!亦即这个项目后面接的服务如果有启动,那么我们这个 unit 本身就不能启动!我们 unit 有启动,则此项目后的服务就不能启动! 反正就是冲突性的检查啦!
[Service] 部份
设定参数 参数意义说明
Type 说明这个 daemon 启动的方式,会影响到 ExecStart 喔!一般来说,有底下几种类型:
- simple:默认值,这个 daemon 主要由 ExecStart 接的指令串来启动,启动后常驻于内存中。
- forking:由 ExecStart 启动的程序透过 spawns 延伸出其他子程序来作为此 daemon 的主要服务。原生的父程序在启动结束后就会终止运作。 传统的 unit 服务大多属于这种项目,例如 httpd 这个 WWW 服务,当 httpd 的程序因为运作过久因此即将终结了,则 systemd 会再重新生出另一个子程序持续运作后, 再将父程序删除。据说这样的效能比较好!!
- oneshot:与 simple 类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中。
- dbus:与 simple 类似,但这个 daemon 必须要在取得一个 D-Bus 的名称后,才会继续运作!因此设定这个项目时,通常也要设定 BusName= 才行!
- idle:与 simple 类似,意思是,要执行这个 daemon 必须要所有的工作都顺利执行完毕后才会执行。这类的 daemon 通常是开机到最后才执行即可的服务!
比较重要的项目大概是 simple, forking 与 oneshot 了!毕竟很多服务需要子程序 (forking),而有更多的动作只需要在开机的时候执行一次(oneshot),例如文件系统的检查与挂载啊等等的。
EnvironmentFile 可以指定启动脚本的环境配置文件!例如 sshd.service 的配置文件写入到 /etc/sysconfig/sshd 当中!你也可以使用 Environment= 后面接多个不同的 Shell 变量来给予设定!
ExecStart 就是实际执行此 daemon 的指令或脚本程序。你也可以使用 ExecStartPre (之前) 以及ExecStartPost (之后) 两个设定项目来在实际启动服务前,进行额外的指令行为。 但是你得要特别注意的是,指令串仅接受『指令 参数 参数…』的格式,不能接受 <, >, >>, |, & 等特殊字符,很多的 bash 语法也不支持喔! 所以,要使用这些特殊的字符时,最好直接写入到指令脚本里面去!不过,上述的语法也不是完全不能用,亦即,若要支持比较完整的 bash 语法,那你得要使用 Type=oneshot 才行喔! 其他的 Type 才不能支持这些字符。
ExecStop 与 systemctl stop 的执行有关,关闭此服务时所进行的指令。
ExecReload 与 systemctl reload 有关的指令行为
Restart 当设定 Restart=1 时,则当此 daemon 服务终止后,会再次的启动此服务。举例来说,如果你在 tty2 使用文字界面登入,操作完毕后注销,基本上,这个时候 tty2 就已经结束服务了。 但是你会看到屏幕又立刻产生一个新的 tty2 的登入画面等待你的登入!那就是 Restart 的功能!除非使用 systemctl 强制将此服务关闭,否则这个服务会源源不绝的一直重复产生!
RemainAfterExit 当设定为 RemainAfterExit=1 时,则当这个 daemon 所属的所有程序都终止之后,此服务会再尝试启动。这对于 Type=oneshot 的服务很有帮助!
TimeoutSec 若这个服务在启动或者是关闭时,因为某些缘故导致无法顺利『正常启动或正常结束』的情况下,则我们要等多久才进入『强制结束』的状态!
KillMode 可以是 process, control-group, none 的其中一种,如果是 process 则 daemon 终止时,只会终止主要的程序 (ExecStart 接的后面那串指令),如果是 control-group 时, 则由此 daemon 所产生的其他 control-group 的程序,也都会被关闭。如果是 none 的话,则没有程序会被关闭喔!
RestartSec 与 Restart 有点相关性,如果这个服务被关闭,然后需要重新启动时,大概要 sleep 多少时间再重新启动的意思。预设是 100ms (毫秒)。
[Install] 部份
设定参数 参数意义说明
WantedBy 这个设定后面接的大部分是 *.target unit !意思是,这个 unit 本身是附挂在哪一个 target unit 底下的!一般来说,大多的服务性质的 unit 都是附挂在 multi-user.target 底下!
Also 当目前这个 unit 本身被 enable 时,Also 后面接的 unit 也请 enable 的意思!也就是具有相依性的服务可以写在这里呢!
Alias 进行一个连结的别名的意思!当 systemctl enable 相关的服务时,则此服务会进行连结档的建立!以multi-user.target 为例,这个家伙是用来作为预设操作环境 default.target 的规划, 因此当你设定用成default.target 时 , 这 个 /etc/systemd/system/default.target 就 会 连 结 到/usr/lib/systemd/system/multi-user.target 啰!

两个 vsftpd 运作的实例

我们在上一章将 vsftpd 的 port 改成 555 号了。不过,因为某些原因,所以你可能需要使用到两个埠口,分别是正常的 21 以及特殊的 555 ! 这两个 port 都启用的情况下,你可能就得要使用到两个配置文件以及两个启动脚本设定了!现在假设是这样:

  • 预设的 port 21:使用 /etc/vsftpd/vsftpd.conf 配置文件,以及 /usr/lib/systemd/system/vsftpd.service 设定脚本;
  • 特殊的 port 555:使用 /etc/vsftpd/vsftpd2.conf 配置文件,以及 /etc/systemd/system/vsftpd2.service 设定脚本。
# 1. 先建立好所需要的配置文件
[root@study ~]# cd /etc/vsftpd
[root@study vsftpd]# cp vsftpd.conf vsftpd2.conf
[root@study vsftpd]# vim vsftpd.conf
#listen_port=555
[root@study vsftpd]# diff vsftpd.conf vsftpd2.conf
128c128
< #listen_port=555
---
> listen_port=555
# 注意这两个配置文件的差别喔!只有这一行不同而已!

# 2. 开始处理启动脚本设定
[root@study vsftpd]# cd /etc/systemd/system
[root@study system]# cp /usr/lib/systemd/system/vsftpd.service vsftpd2.service
[root@study system]# vim vsftpd2.service
[Unit]
Description=Vsftpd second ftp daemon
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd2.conf
[Install]
WantedBy=multi-user.target
# 重点在改了 vsftpd2.conf 这个配置文件喔!

# 3. 重载 systemd 的脚本配置文件内容
[root@study system]# systemctl daemon-reload
[root@study system]# systemctl list-unit-files --all | grep vsftpd
vsftpd.service enabled
vsftpd2.service disabled
[email protected] disabled
vsftpd.target disabled
[root@study system]# systemctl status vsftpd2.service
vsftpd2.service - Vsftpd second ftp daemon
 Loaded: loaded (/etc/systemd/system/vsftpd2.service; disabled)
 Active: inactive (dead)
[root@study system]# systemctl restart vsftpd.service vsftpd2.service
[root@study system]# systemctl enable vsftpd.service vsftpd2.service
[root@study system]# systemctl status vsftpd.service vsftpd2.service
vsftpd.service - Vsftpd ftp daemon
 Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; enabled)
 Active: active (running) since Wed 2015-08-12 22:00:17 CST; 35s ago
Main PID: 12670 (vsftpd)
 CGroup: /system.slice/vsftpd.service
 └─12670 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
Aug 12 22:00:17 study.centos.vbird systemd[1]: Started Vsftpd ftp daemon.
vsftpd2.service - Vsftpd second ftp daemon
 Loaded: loaded (/etc/systemd/system/vsftpd2.service; enabled)
 Active: active (running) since Wed 2015-08-12 22:00:17 CST; 35s ago
Main PID: 12672 (vsftpd)
 CGroup: /system.slice/vsftpd2.service
 └─12672 /usr/sbin/vsftpd /etc/vsftpd/vsftpd2.conf
[root@study system]# netstat -tlnp 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1340/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2387/master
tcp6 0 0 :::555 :::* LISTEN 12672/vsftpd
tcp6 0 0 :::21 :::* LISTEN 12670/vsftpd
tcp6 0 0 :::22 :::* LISTEN 1340/sshd
tcp6 0 0 ::1:25 :::* LISTEN 2387/master

很简单的将你的 systemd 所管理的 vsftpd 做了另一个服务!未来如果有相同的需求,同样的方法作一遍即可!

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

我们的 CentOS 7 开机完成后,不是说有 6 个终端机可以使用吗?就是那个 tty1~tty6 的啊!那个东西是由 agetty 这个指令达成的。 OK!那么这个终端机的功能又是从哪个项目所提供的呢?其实,那个东东涉及很多层面,主要管理的是 getty.target 这个 target unit , 不过,实际产生 tty1~tty6 的则是由 [email protected] 所提供的!咦!那个 @ 是啥东西

先来查阅一下 /usr/lib/systemd/system/[email protected] 的内容好了:

[root@study ~]# cat //usr/lib/systemd/system/[email protected]
[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service
Before=getty.target
ConditionPathExists=/dev/tty0
[Service]
ExecStart=-/sbin/agetty --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes
[Install]
WantedBy=getty.target

比较重要的当然就是 ExecStart 项目啰!那么我们去 man agetty 时,发现到它的语法应该是『 agetty --noclear tty1 』之类的字样, 因此,我们如果要启动六个 tty 的时候,基本上应该要有六个启动配置文件。亦即是可能会用到 getty1.service, getty2.service…getty6.service 才对! 哇!这样控管很麻烦啊~所以,才会出现这个 @ 的项目啦!咦!这个 @ 到底怎么回事呢?我们先来看看 [email protected] 的上游,亦即是 getty.target 这个东西的内容好了!

[root@study ~]# systemctl show getty.target
# 那个 show 的指令可以将 getty.target 的默认设定值也取出来显示!
Names=getty.target
Wants=[email protected]
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=multi-user.target
After=[email protected] [email protected] [email protected] [email protected]
 [email protected] [email protected]
.....(后面省略).....

你会发现,咦!怎么会多出六个怪异的 service 呢?我们拿 [email protected] 来说明一下好了!当我们执行完 getty.target 之后, 他会持续要求 [email protected] 等六个服务继续启动。那我们的systemd 就会这么作:

  • 先看 /usr/lib/systemd/system/, /etc/systemd/system/ 有没有 [email protected] 的设定,若有就执行,若没有则执行下一步;
  • [email protected] 的设定,若有则将 @ 后面的数据带入成 %I 的变量,进入 [email protected] 执行!

这也就是说,其实 [email protected] 实际上是不存在的!他主要是透过 [email protected] 来执行~也就是说, [email protected] 的目的是为了要简化多个执行的启动设定, 他的命名方式是这样的:

源文件:执行服务名称@.service
执行文件:执行服务名称@范例名称.service

因此当有范例名称带入时,则会有一个新的服务名称产生出来!你再回头看看 [email protected] 的启动脚本:

ExecStart=-/sbin/agetty --noclear %I $TERM

上表中那个 %I 指的就是『范例名称』!根据 getty.target 的信息输出来看,[email protected] %I 就是tty1啰!因此执行脚本就会变成『 /sbin/agetty --noclear tty1 』! 所以我们才有办法以一个配置文件来启动多个 tty1 给用户登入啰!

将 tty 的数量由 6 个降低到 4 个

现在你应该要感到困扰的是,那么『 6 个 tty 是谁规定的』为什么不是 5 个还是 7 个?这是因为systemd 的登入配置文件 /etc/systemd/logind.conf 里面规范的啦! 假如你想要让 tty 数量降低到剩下 4 个的话,那么可以这样实验看看:

# 1. 修改预设的 logind.conf 内容,将原本 6 个虚拟终端机改成 4 个
[root@study ~]# vim /etc/systemd/logind.conf
[Login]
NAutoVTs=4
ReserveVT=0
# 原本是 6 个而且还批注,请取消批注,然后改成 4 吧!
# 2. 关闭不小心启动的 tty5, tty6 并重新启动 getty.target 啰!
[root@study ~]# systemctl stop [email protected]
[root@study ~]# systemctl stop [email protected]
[root@study ~]# systemctl restart systemd-logind.service

现在你再到桌面环境下,按下 [ctrl]+[alt]+[F1]~[F6] 就会发现,只剩下四个可用的 tty 啰!后面的 tty5, tty6 已经被放弃了!不再被启动喔! 好!那么我暂时需要启动 tty8 时,又该如何处理呢?需要重新建立一个脚本吗?不需要啦!可以这样作!

[root@study ~]# systemctl start [email protected]

无须额外建立其他的启动服务配置文件喔!

暂时新增 vsftpd 到 2121 埠口

不知道你有没有发现,其实在 /usr/lib/systemd/system 底下还有个特别的 [email protected] 喔!来看看他的内容:

[root@study ~]# cat /usr/lib/systemd/system/[email protected]
[Unit]
Description=Vsftpd ftp daemon
After=network.target
PartOf=vsftpd.target
[Service]
Type=forking
ExecStart=/usr/sbin/vsftpd /etc/vsftpd/%i.conf
[Install]
WantedBy=vsftpd.target

根据前面 [email protected] 的说明,我们知道在启动的脚本设定当中, %i 或 %I 就是代表 @ 后面接的范例文件名的意思! 那我能不能建立 vsftpd3.conf 文件,然后透过该文件来启动新的服务呢?就来玩玩看!

# 1. 根据 [email protected] 的建议,于 /etc/vsftpd/ 底下先建立新的配置文件
[root@study ~]# cd /etc/vsftpd
[root@study vsftpd]# cp vsftpd.conf vsftpd3.conf
[root@study vsftpd]# vim vsftpd3.conf
listen_port=2121
# 2. 暂时启动这个服务,不要永久启动他!
[root@study vsftpd]# systemctl start [email protected]
[root@study vsftpd]# systemctl status [email protected]
[email protected] - Vsftpd ftp daemon
 Loaded: loaded (/usr/lib/systemd/system/[email protected]; disabled)
 Active: active (running) since Thu 2015-08-13 01:34:05 CST; 5s ago
[root@study vsftpd]# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 0 0 :::2121 :::* LISTEN 16404/vsftpd
tcp6 0 0 :::555 :::* LISTEN 12672/vsftpd
tcp6 0 0 :::21 :::* LISTEN 12670/vsftpd

聪明的读者可能立刻发现一件事,为啥这次 FTP 增加了 2121 埠口却不用修改SELinux 呢?这是因为默认启动小于 1024 号码以下的端口口时, 需要使用到 root 的权限,因此小于 1024 以下埠口的启动较可怕。而这次范例中,我们使用 2121 端口口,他对于系统的影响可能小一些 (其实一样可怕!), 所以就忽略了 SELinux 的限制了!(笔者在上一个示例,端口改为555的时候已经把selinux关了,因为不关vsftp2起不来)

自己的服务自己作

[root@study ~]# vim /backups/backup.sh
#!/bin/bash
source="/etc /home /root /var/lib /var/spool/{cron,at,mail}"
target="/backups/backup-system-$(date +%Y-%m-%d).tar.gz"
[ ! -d /backups ] && mkdir /backups
tar -zcvf ${target} ${source} &> /backups/backup.log
[root@study ~]# chmod a+x /backups/backup.sh
[root@study ~]# ll /backups/backup.sh
-rwxr-xr-x. 1 root root 220 Aug 13 01:57 /backups/backup.sh
# 记得要有可执行的权限才可以喔!

接下来,我们要如何设计一只名为 backup.service 的启动脚本设定呢?可以这样做喔!

[root@study ~]# vim /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
# 因为 ExecStart 里面有用到 at 这个指令,因此, atd.service 就是一定要的服务!
[root@study ~]# systemctl daemon-reload
[root@study ~]# systemctl start backup.service
[root@study ~]# systemctl status backup.service
backup.service - backup my server
 Loaded: loaded (/etc/systemd/system/backup.service; disabled)
 Active: inactive (dead)
Aug 13 07:50:31 study.centos.vbird systemd[1]: Starting backup my server...
Aug 13 07:50:31 study.centos.vbird bash[20490]: job 8 at Thu Aug 13 07:50:00 2015
Aug 13 07:50:31 study.centos.vbird systemd[1]: Started backup my server.
# 为什么 Active 是 inactive 呢?这是因为我们的服务仅是一个简单的 script 啊!
# 因此执行完毕就完毕了,不会继续存在内存中喔!

完成上述的动作之后,以后你都可以直接使用 systemctl start backup.service 进行系统的备份了!而且会直接丢进 atd 的管理中, 你就无须自己手动用 at 去处理这项任务了~好像还不赖喔! ^_^

这样自己做一个服务好像也不难啊!^_^!自己动手玩玩看吧!

34.2 systemctl 针对 timer 的配置文件

有时候,某些服务你想要定期执行,或者是开机后执行,或者是什么服务启动多久后执行等等的。在过去,我们大概都是使用 crond 这个服务来定期处理, 不过,既然现在有一直常驻在内存当中的systemd 这个好用的东西,加上这 systemd 有个协力服务,名为 timers.target 的家伙,这家伙可以协助定期处理各种任务!那么,除了 crond 之外,如何使用 systemd 内建的 time 来处理各种任务呢?这就是本小节的重点啰!

systemd.timer 的优势

在 archlinux 的官网 wiki 上面有提到,为啥要使用 systemd.timer 呢?

  • 由于所有的 systemd 的服务产生的信息都会被纪录 (log),因此比 crond 在 debug 上面要更清楚方便的多;
  • 各项 timer 的工作可以跟 systemd 的服务相结合;
  • 各项 timer 的工作可以跟 control group (cgroup,用来取代 /etc/secure/limit.conf 的功能) 结合,来限制该工作的资源利用

虽然还是有些弱点啦~例如 systemd 的 timer 并没有 email 通知的功能 (除非自己写一个),也没有类似 anacron 的一段时间内的随机取样功能 (random_delay), 不过,总体来说,还是挺不错的!此外,相对于 crond 最小的单位到分, systemd 是可以到秒甚至是毫秒的单位哩!相当有趣!

任务需求

基本上,想要使用 systemd 的 timer 功能,你必须要有几个要件:

  • 系统的 timer.target 一定要启动
  • 要有个 sname.service 的服务存在 (sname 是你自己指定的名称)
  • 要有个 sname.timer 的时间启动服务存在

满足上面的需求就 OK 了!有没有什么案例可以来实作看看?这样说好了,我们上个小节不是才自己做了个 backup.service 的服务吗?那么能不能将这个 backup.service 用在定期执行上面呢?好啊!那就来测试看看!

sname.timer 的设定值
你可以到 /etc/systemd/system 底下去建立这个 *.timer 档,那这个文件的内容要项有哪些东西呢?基本设定主要有底下这些: (man systemd.timer & man systemd.time)

[Timer] 部份
设定参数 参数意义说明
OnActiveSec 当 timers.target 启动多久之后才执行这只 unit
OnBootSec 当开机完成后多久之后才执行
OnStartupSec 当 systemd 第一次启动之后过多久才执行
OnUnitActiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次启动后,隔多久后再执行一次的意思
OnUnitInactiveSec 这个 timer 配置文件所管理的那个 unit 服务在最后一次停止后,隔多久再执行一次的意思。
OnCalendar 使用实际时间 (非循环时间) 的方式来启动服务的意思!至于时间的格式后续再来谈。
Unit 一般来说不太需要设定,因此如同上面刚刚提到的,基本上我们设定都是 sname.server + sname.timer,那如果你的 sname 并不相同时,那在 .timer 的文件中, 就得要指定是哪一个service unit 啰!
Persistent 当使用 OnCalendar 的设定时,指定该功能要不要持续进行的意思。通常是设定为 yes ,比较能够满足类似 anacron 的功能喔!

使用于 OnCalendar 的时间

如果你想要从 crontab 转成这个 timer 功能的话,那么对于时间设定的格式就得要了解了解~基本上的格式如下所示:

语法:英文周名 YYYY-MM-DD HH:MM:SS
范例:Thu 2015-08-13 13:40:00

上面谈的是基本的语法,你也可以直接使用间隔时间来处理!常用的间隔时间单位有:

  • us 或 usec:微秒 (10-6 秒)
  • ms 或 msec:毫秒 (10-3 秒)
  • s, sec, second, seconds
  • m, min, minute, minutes
  • h, hr, hour, hrs, hours
  • d, day, days
  • w, week, weeks
  • month, months
  • y, year, years

常见的使用范例有:

3 小时: 3h 或 3hr 或 3hours
隔 300 分钟过 10 秒: 10s 300m
隔 5 天又 100 分钟: 100m 5day
# 通常英文的写法,小单位写前面,大单位写后面~所以先秒、再分、再小时、再天数等~

此外,你也可以使用英文常用的口语化日期代表,例如 today, tomorrow 等!假设今天是 2015-08-13 13:50:00 的话,那么:

英文口语 实际的时间格式代表
now Thu 2015-08-13 13:50:00
today Thu 2015-08-13 00:00:00
tomorrow Thu 2015-08-14 00:00:00
hourly *-*-* *:00:00
daily *-*-* 00:00:00
weekly Mon *-*-* 00:00:00
monthly *-*-01 00:00:00
+3h10m Thu 2015-08-13 17:00:00
2015-08-16 Sun 2015-08-16 00:00:00

一个循环时间运作的案例

现在假设这样:

  • 开机后 2 小时开始执行一次这个 backup.service
  • 自从第一次执行后,未来我每两天要执行一次 backup.service

好了,那么应该如何处理这个脚本呢?可以这样做喔!

[root@study ~]# vim /etc/systemd/system/backup.timer
[Unit]
Description=backup my server timer
[Timer]
OnBootSec=2hrs
OnUnitActiveSec=2days
[Install]
WantedBy=multi-user.target
# 只要这样设定就够了!储存离开吧!
[root@study ~]# systemctl daemon-reload
[root@study ~]# systemctl enable backup.timer
[root@study ~]# systemctl restart backup.timer
[root@study ~]# systemctl list-unit-files | grep backup
backup.service disabled # 这个不需要启动!只要 enable backup.timer 即可!
backup.timer enabled
[root@study ~]# systemctl show timers.target
ConditionTimestamp=Thu 2015-08-13 14:31:11 CST # timer 这个 unit 启动的时间!
[root@study ~]# systemctl show backup.service
ExecMainExitTimestamp=Thu 2015-08-13 14:50:19 CST # backup.service 上次执行的时间
[root@study ~]# systemctl show backup.timer
NextElapseUSecMonotonic=2d 19min 11.540653s # 下一次执行距离 timers.target 的时间

一个固定日期运作的案例

上面的案例是固定周期运作一次,那如果我希望不管上面如何运作了,我都希望星期天凌晨 2 点运作这个备份程序一遍呢?请注意,因为已经存在 backup.timer 了! 所以,这里我用 backup2.timer 来做区隔喔!

[root@study ~]# vim /etc/systemd/system/backup2.timer
[Unit]
Description=backup my server timer2
[Timer]
OnCalendar=Sun *-*-* 02:00:00
Persistent=true
Unit=backup.service
[Install]
WantedBy=multi-user.target
[root@study ~]# systemctl daemon-reload
[root@study ~]# systemctl enable backup2.timer
[root@study ~]# systemctl start backup2.timer
[root@study ~]# systemctl show backup2.timer
NextElapseUSecRealtime=45y 7month 1w 6d 10h 30min

与循环时间运作差异比较大的地方,在于这个 OnCalendar 的方法对照的时间并不是 times.target 的启动时间,而是 Unix 标准时间! 亦即是 1970-01-01 00:00:00 去比较的!因此,当你看到最后出现的 NextElapseUSecRealtime 时,哇!下一次执行还要 45 年 + 7 个月 + 1 周 + 6 天 + 10 小时过30 分~刚看到的时候,鸟哥确实因此揉了揉眼睛~确定没有看错…这才了解原来比对的是『日历时间』而不是某个 unit 的启动时间啊!呵呵!

透过这样的方式,你就可以使用 systemd 的 timer 来制作属于你的时程规划服务啰!

34.3 CentOS 7.x 预设启动的服务简易说明

随着 Linux 上面软件支持性越来越多,加上自由软件蓬勃的发展,我们可以在 Linux 上面用的daemons 真的越来越多了。所以,想要写完所有的 daemons 介绍几乎是不可能的,因此,鸟哥这里仅介绍几个很常见的 daemons 而已, 更多的信息呢,就得要麻烦你自己使用 systemctl list-unit-files --type=service 去查询啰! 底下的建议主要是针对 Linux 单机服务器的角色来说明的,不是桌上型的环境喔!

CentOS 7.x 预设启动的服务内容

服务名称 服务类型 功能简介
abrtd 系统 abrtd 服务可以提供使用者一些方式,让使用者可以针对不同的应用软件去设计错误登录的机制, 当软件产生问题时,用户就可以根据 abrtd 的登录档来进行错误克服的行为。还有其他的 abrt-xxx.service 均是使用这个服务来加强应用程序 debug 任务的。
accounts-daemon
可关闭
系统 使用 accountsservice 计划所提供的一系列 D-Bus 界面来进行使用者帐户信息的查询。 基本上是与 useradd, usermod, userdel 等软件有关。
alsa-X
可关闭
系统 开头为 alsa 的服务有不少,这些服务大部分都与音效有关!一般来说, 服务器且不开图形界面的话,这些服务可以关闭!
atd 系统 单一的例行性工作排程。 抵挡机制的配置文件在/etc/at.{allow,deny} 喔!
auditd 系统 还记得前一章的 SELinux 所需服务吧? 这就是其中一项,可以让系统需 SELinux 稽核的讯息写入 /var/log/audit/audit.log 中。
avahi-daemon
可关闭
系统 也是一个客户端的服务,可以透过 Zeroconf 自动的分析与管理网络。 Zeroconf 较常用在笔记本电脑与行动装置上,所以我们可以先关闭他啦!
brandbot
rhel-*
系统 这些服务大多用于开机过程中所需要的各种侦测环境的脚本,同时也提供网络界面的启动与关闭。 基本上,你不要关闭掉这些服务比较妥当!
chronyd
ntpd
ntpdate
系统 都是网络校正时间的服务!一般来说,你可能需要的仅有 chronyd 而已!
cpupower 系统 提供 CPU 的运作规范~可以参考 /etc/sysconfig/cpupower 得到更多的信息! 这家伙与你的 CPU 使用情况有关喔!
crond 系统 系统配置文件为 /etc/crontab。
cups
可关闭
系统/网络 用来管理打印机的服务,可以提供网络联机的功能,有点类似打印服务器的功能哩!你可以在 Linux 本机上面以浏览器的 http://localhost:631 来管理打印机喔!由于我们目前没有打印机,所以可以暂时关闭他。
dbus 系统 使用 D-Bus 的方式在不同的应用程序之间传送讯息,使用的方向例如应用程序间的讯息传递、每个用户登入时提供的讯息数据等。
dm-event
multipathd
系统 监控装置对应表 device mapper的主要服务,当然不能关掉啊! 否则就无法让 Linux 使用我们的外围装置与储存装置了!
dmraid-activation
mdmonitor
系统 用来启动 Software RAID 的重要服务!最好不要关闭啦!虽然你可能没有 RAID。
dracut-shutdown 系统 用来处理 initramfs 的相关行为,这与开机流程相关性较高~
ebtables 系统/网络 透过类似 iptables 这种防火墙规则的设定方式,设计网络卡作为桥接时的封包分析政策。 其实就是防火墙。不过与底下谈到的防火墙应用不太一样。如果没有使用虚拟化,或者启用了 firewalld ,这个服务可以不启动。
emergency
rescue
系统 进入紧急模式或者是救援模式的服务
firewalld 系统/网络 就是防火墙!以前有 iptables 与 ip6tables 等防火墙机制,新的 firewalld 搭配firewall-cmd 指令,可以快速的建置好你的防火墙系统喔!因此,从 CentOS 7.1 以后,iptables 服务的启动脚本已经被忽略了! 请使用 firewalld 来取代 iptables 服务喔!
gdm 系统 GNOME 的登入管理员,就是图形界面上一个很重要的登入管理服务!
getty@ 系统 就是要在本机系统产生几个文字界面 tty 登入的服务啰!
hyper*
ksm*
libvirt*
vmtoolsd
系统 跟建立虚拟机有关的许多服务!如果你不玩虚拟机, 那么这些服务可以先关闭。此外,如果你的 Linux 本来就在虚拟机的环境下,那这些服务对你就没有用!因为这些服务是让实体机器来建立虚拟机的!
irqbalance 系统 如果你的系统是多核心的硬件,那么这个服务要启动, 因为它可以自动的分配系统中断IRQ 之类的硬件资源。
iscsi* 系统 可以挂载来自网络驱动器机的服务!这个服务可以在系统内仿真好贵的 SAN 网络驱动器。如果你确定系统上面没有挂载这种网络驱动器,也可以将他关闭的。
kdump
可关闭
系统 在安装 CentOS 的章节就谈过这东西,主要是 Linux 核心如果出错时,用来纪录内存的东西。 鸟哥觉得不需要启动他!除非你是核心黑客!
lvm2-* 系统 跟 LVM 相关性较高的许多服务,当然也不能关!不然系统上面的 LVM2 就没人管了!
microcode 系统 Intel 的 CPU 会提供一个外挂的微指令集提供系统运作, 不过,如果你没有下载 Intel 相关的指令集文件,那么这个服务不需要启动的,也不会影响系统运作。
ModemManager
network
NetworkManager*
系统/网络 主要就是调制解调器、网络设定等服务!进入 CentOS 7 之后,系统似乎不太希望我们使用 network 服务了, 比较建议的是使用 NetworkManager 搭配 nmcli 指令来处理网络设定~所以,反而是 NetworkManager 要开,而 network 不用开哩!
quotaon 系统 启动 Quota 要用到的服务喔!
rc-local 系统 兼容于 /etc/rc.d/rc.local 的呼叫方式!只是,你必须要让 /etc/rc.d/rc.local 具有 x 的权限后, 这个服务才能真的运作!否则,你写入 /etc/rc.d/rc.local 的脚本还是不会运作的喔!
rsyslog 系统 这个服务可以记录系统所产生的各项讯息, 包括 /var/log/messages 内的几个重要的登录档啊。
smartd 系统 这个服务可以自动的侦测硬盘状态,如果硬盘发生问题的话, 还能够自动的回报给系统管理员,是个非常有帮助的服务喔!不可关闭他啊!
sysstat 系统 事实上,我们的系统有只名为 sar 的指令会记载某些时间点下,系统的资源使用情况,包括 CPU/流量/输入输出量等, 当 sysstat 服务启动后,这些纪录的数据才能够写入到纪录文件log 里面去!
systemd-* 系统 大概都是属于系统运作过程所需要的服务,没必要都不要更动它的预设状态!
plymount*
upower
系统 与图形界面的使用相关性较高的一些服务!没启动图形界面时,这些服务可以暂时不管他!

上面的服务是 CentOS 7.x 预设有启动的,这些预设启动的服务很多是针对桌面计算机所设计的,所以啰,如果你的 Linux 主机用途是在服务器上面的话,那么有很多服务是可以关闭的啦!如果你还有某些不明白的服务想要关闭的, 请务必要搞清楚该服务的功能为何喔!举例来说,那个 rsyslog 就不能关闭,如果你关掉他的话,系统就不会记录登录文件, 那你的系统所产生的警告讯息就无法记录起来,你将无法进行 debug 喔。

其他服务的简易说明

服务名称 服务类型 功能简介
dovecot 网络 可以设定 POP3/IMAP 等收受信件的服务,如果你的 Linux 主机是 email server 才需要这个服务,否则不需要启动他啦!
httpd 网络 这个服务可以让你的 Linux 服务器成为 www server 喔!
named 网络 这是领域名服务器 Domain Name System的服务, 这个服务非常重要,但是设定非常困难!目前应该不需要这个服务啦!
nfs
nfs-server
网络 这就是 Network Filesystem,是 Unix-Like 之间互相作为网络驱动器机的一个功能。
smb
nmb
网络 这个服务可以让 Linux 仿真成为 Windows 上面的网络上的芳邻。如果你的 Linux 主机想要做为 Windows 客户端的网络驱动器机服务器,这玩意儿得要好好玩一玩。
vsftpd 网络 作为文件传输服务器 FTP的服务。
sshd 网络 这个是远程联机服务器的软件功能, 这个通讯协议比 telnet 好的地方在于 sshd 在传送资料时可以进行加密喔!这个服务不要关闭他啦!
rpcbind 网络 达成 RPC 协议的重要服务!包括 NFS, NIS 等等都需要这东西的协助!
postfix 网络 寄件的邮件主机~因为系统还是会产生很多 email 讯息!例如 crond / atd 就会传送 email 给本机用户! 所以这个服务千万不能关!即使你不是 mail server 也是要启用这服务才行!

该系列目录 --> 【BASH】回顾与知识点梳理(目录)

你可能感兴趣的:(#,bash,shell整理,bash,开发语言)