服务 (service) 管理
服务 (service) 管理
服务 (service) 本质就是进程(守护进程),但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如sshd
,其实就是后台的一个进程,监听 22 端口,等待ssh
连接,比如mysqld
(前面我们接触过的很多最后带了一个字母 d 的都是类似的进程)、防火墙等,因此我们又称为守护进程(daemon),是 Linux 中非常重要的知识点。
在 Linux 中,无论何时当你安装任何带有服务和守护进程的包,系统默认会把这些服务的初始化及 systemd
脚本添加进去,不过此时它们并没有被启用。我们需要手动的开启或者关闭那些服务。
systemd
使用 .service
文件而不是 bash 脚本。systemd 将所有守护进程添加到 cgroups 中排序,你可以通过浏览/cgroup/systemd
文件查看系统等级。
service 命令
|
|
在CentOS7.0
后很多服务不再使用service
,而是systemctl
(后文的systemctl
小节)
比如:
service network start
service network stop
防火墙的状态
service firewalld status
可以看到在当前版本中 Centos 7 中,service firewalld
调用的,实际上是重定向到 systemctl:Redirecting to /bin/systemctl ……….
关闭防火墙
service firewalld stop
service
指令管理的服务在/etc/init.d
查看,/etc/init.d
下的服务仍然还是用service
管理,不会显示Redirecting to /bin/systemctl
,
当然,systemctl
本身也是兼容service
的,可以管理/etc/init.d
下的服务。
network
是一个基础服务,所有依赖网络的服务都要求network
服务正常运行,如果network
服务关闭,有的服务比如ssh
将直接瘫痪(不会自动关闭,但是会瘫痪)
service
命令本身是一个 shell 脚本,它在/etc/init.d/
目录查找指定的服务脚本,然后调用该服务脚本来完成任务。
自己写 service 脚本试试
在 /etc/init.d
下创建文件 lkser
|
|
. /etc/rc.d/init.d/functions
:functions 这个脚本是给/etc/init.d
里边的文件使用的(可理解为全局文件)。
然后赋权 chmod +x lkser
否则执行的时候会提示:
然后执行:
66666666 !!!
查看服务名
运行setup
命令,然后选择 系统服务
就可以看到全部服务
<SysV initscripts>
标签下的,就是/etc/init.d
下的几个服务
前面有 *
号的,会随着 Linux 的启动自动启动,把光标放到 *
号上,按空格键取消 *
号,这样你就可以在这里设置服务自启动。
按 enter 确定,按 tab 切换确定和取消
服务自启动就是后面要谈到的服务的运行级别的问题。
Centos7 以后,使用systemctl
,可以更方便的查看所有服务:systemctl -t service
具体请查看后文的
systemctl
小节。
运行级别和 chkconfig 命令
运行级别相关知识,请回看《Linux 指令基础》的
指定运行级别
小节。
Linux 系统有0-6
这 7 中运行级别,Linux 运行级别的重点是使管理员可以控制在特定条件下运行的服务。对系统进行这种细粒度控制可以增强安全性,因为您可以确保没有多余的服务在运行。
从 centos7 开始,/etc/inittab
不在起作用,不再使用runlevel
这个概念,转而开始使用targets
这个概念
查看当前运行级别:runlevel
获取默认的运行级别:systemctl get-default
设置默认的运行级别:systemctl set-default TARGET.target
Linux 系统开机流程:
chkconfig
通过chkconfig
命令可以给服务的各个运行级别设置自启动/关闭。(从查看服务名
小节中可知,setup
命令中也可以修改)。
chkconfig
指令管理的服务在/etc/init.d
查看 (只能管理这些服务),注意:Centos7.0
后,可以systemctl
简化操作,这两个命令的区别查看常用指令
小节。
chkconfig
基本用法
chkconfig --list
:查看服务在各个运行级别下的开启关闭情况
开的意思就是如果系统以此运行级别开机,则开机运行,关的意思就是开机不运行
chkconfig --list 服务名
:查看特定服务在各个运行级别下的开启关闭情况
chkconfig --level 5 服务名on/off
:让特定服务在运行级别 5 开启或关闭,chkconfig
重新设置服务后自启动或关闭,需要重启机器 reboot 生效。
chkconfig --level 35 mysqld on
:设定 mysqld 在等级 3 和 5 为开机运行服务,--level 35
表示操作只在等级 3 和 5 执行,on 表示启动,off 表示关闭
chkconfig mysqld on
:设定 mysqld 在各等级为 on,“各等级”包括 2、3、4、5 等级,1 和 6 一般不包含在内,因为一个是关机,一个是重启
systemctl 命令
systemd
是 Linux 系统最新的初始化系统 (init
),作用是提高系统的启动速度,尽可能启动较少的进程,尽可能更多进程并发启动。
systemd
对应的进程管理命令是systemctl
,centos7 以后,推荐使用systemctl
命令来管理服务,而不再使用service
和chkconfig
,systemctl
命令的功能包含了service
和chkconfig
的功能,而且功能更多。当然service
和chkconfig
还是可以继续使用。
systemctl
命令兼容了service
,即systemctl
也会去/etc/init.d
目录下查看,执行相关程序。
systemctl
主要的功能就是查看服务当前的运行状态和开机是否自启。
systemd
核心概念 unit(单元)类型:unit 表示不同类型的systemd
对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听 socket、保存的系统快照以及其它与 init 相关的信息
下面为 unit 类型(路径:/usr/lib/systemd/system/
) :
-
service:文件扩展名为
.service
, 用于定义系统服务,最常见 -
target:文件扩展名为
.target
,用于模拟实现运行级别最常见的就是这 7 个文件:
ll *.target
-
device:用于定义内核识别的设备
-
mount:定义文件系统挂载点
-
socket:用于标识进程间通信用的 socket 文件,也可在系统启动时,延迟启动服务,实现按需启动
-
snapshot:管理系统快照
-
swap:用于标识 swap 设备
-
automount:文件系统的自动挂载点
-
path:用于定义文件系统中的一个文件或目录使用,常用于当文件系统变化时,延迟激活服务
那么如何查看这些类型呢?可以使用-t
加上类型去查看,以service
为例
systemctl -t service
……
-
LOAD: 是否载入内存
-
ACTIVE:父 unit 是否正在运行
-
SUB: 子 unit 是否正在运行
-
ACTIVE 和 SUB 都表示运行状态,运行状态即:当前程序是否在运行,可能的值:
-
active(running):正有一只或多只程序正在系统中执行的意思;
-
active(exited):仅执行一次就正常结束的服务,目前并没有任何程序在系统中执行;
-
active(waiting):正在执行当中,不过还需要等待其他的事件才能继续处理;
-
inactive:这个服务目前没有运行;
-
dead:程序已经清除;
-
加上all
参数,查看已经载入但是没有运行的 units,基本上就是查看系统所有服务得意思
systemctl --all -t service
……
当然还可以是别的类型,比如 target 类型
systemctl --all -t target
常用指令
任务 | 旧指令 | 新指令 |
---|---|---|
检查服务状态 | service httpd status | systemctl status httpd.service(服务详细信息)systemctl is-active httpd.service(仅显示是否 Active) |
启动某服务 | service httpd start | systemctl start httpd.service |
停止某服务 | service httpd stop | systemctl stop httpd.service |
重启某服务 | service httpd restart | systemctl restart httpd.service |
服务运行情况(对service
命令的兼容)
|
|
运行状态:
-
active(running):正有一只或多只程序正在系统中执行的意思;
-
active(exited):仅执行一次就正常结束的服务,目前并没有任何程序在系统中执行;
-
active(waiting):正在执行当中,不过还需要等待其他的事件才能继续处理;
-
inactive:这个服务目前没有运行;
-
dead:程序已经清除;
系统的所有服务的运行状态(不包括/etc/init.d
下的服务):systemctl --all -t service
查看服务的状态信息:systemctl status sshd
-
loaded 表示启动状态,
sshd.service
会开机自启 -
active 表示运行状态,active 表示正在运行
-
pid 不用说,表示进程 ID
-
下面也列出了此服务的日志信息
服务是否正在运行:systemctl is-active sshd
查看服务所有配置详细信息:systemctl show sshd
……
systemctl start firewalld.service
:开启防火墙
systemctl status firewalld.service
:查看防护墙状态
systemctl stop firewalld.service
:关闭防护墙
服务开机自启情况
启动状态:程序是否开机自启
-
enabled:这个 daemon 将在(3 或者 5 这两个级别)开机时被执行;
-
disabled:这个 daemon 在(3 或者 5 这两个级别)开机时不会被执行;
-
static:这个 daemon 不可以自己启动(enable 不可),不过可能会被其他的 enabled 的服务来唤醒(关联属性的服务);
-
mask:这个 daemon 无论如何都无法被启动,因为已经被强制注销(非删除),可通过
systemctl unmask
方式改回原本状态
查看所有已安装(loaded)的 unit 文件的开机自启情况(当然,不包括/etc/init.d
下的服务):systemctl list-unit-files
……
其中 STATE 为启动状态
带上 service 参数,则只会显示服务(.service
)的开机自启情况
systemctl list-unit-files --type=service
查看所有已启动服务:systemctl list-units --type=service
结果列跟 systemctl list-unit-files --type=service
类似,只是范围有差别,这里只列出已启动的 unit,systemctl list-unit-files --type=service
会列出所有的 unit
设置服务在 3 和 5 这两个运行级别开机自启动或者禁止启动
centos7 简化运行级别为graphical.target.wants
、multi-user.target.wants
两个 target,systemctl enable/disable
就是设置此服务在 3 和 5 的运行级别是否自启。
systemctl enable/disable xxx.service(也可以简写成xxx)
操作/etc/init.d
下的服务的时候本质上还是调用chkconfig
,在 level 2、3、4、5 中开启自启。相当于chkconfig --level 2345 服务名 on/off
或者chkconfig 服务名 on/off
操作/etc/init.d
以外的服务的服务的时候就是到/usr/lib/systemd/system/
下删除或者创建对应服务的链接文件,我现在的运行级别是 5,但是它是到 3 对应的运行级别下修改,因为运行级别为 5 的自启动服务包含了运行级别为 3 的自启动服务。
查询某个服务是否是自启动的
systemctl is-enabled 服务名
chkconfig
注释里说清楚了 chkconfig
和systemctl
(管理软件自启动相关指令)的区别:
chkconfig
只能控制/etc/init.d
下的服务(setup
命令的结果中的<SysV>
下的服务就是/etc/init.d
下的服务),无法控制systemd
中的服务,
但是systemctl
(systemd
的服务控制命令)可以操作/etc/init.d
下的服务,并覆盖chkconfig
对这些服务的自启动设置:
举个例例子
lkser
是我在/etc/init.d
下新建的服务。
systemctl enable lkser
操作/etc/init.d
下的服务的时候本质上还是调用chkconfig
,在 level 2、3、4、5 中开启自启。相当于chkconfig --level 2345 服务名 on/off
或者chkconfig 服务名 on/off
查看systemd
的服务启动情况(systemd
看不到/etc/init.d
下的服务):systemctl list-unit-files --service
,这个前面已经演示了
查看特定运行级别下的服务:systemctl list-dependencies [target]
比如:
systemctl list-dependencies graphical.target
可以注意到其包含了运行级别为 3 的服务。
红灯表示没运行,绿灯表示正在运行
systemctl list-dependencies sshd
:获取服务的依赖项列表
相关目录
-
/usr/lib/systemd/system/
:每个服务最主要的启动脚本的配置放在这,有点类似以前的/etc/init.d
; -
/run/systemd/system/
:系统执行过程中所产生的服务脚本所在目录,这些脚本的优先级要比/usr/lib/systemd/system/
高; -
/etc/systemd/system/
:管理员根据主机系统的需求所创建的执行脚本所在目录,执行优先级比/run/systemd/system/
高;其中的 service 文件全都是链接文件,指向
/usr/lib/systemd/system/
下的 service 文件
从上面的功能及优先级次序,我们可以知道,/etc/systemd/system/
目录下的相关配置,决定系统了会不会执行某些服务,所以该目录下面一般放着一大堆链接文件。而/usr/lib/systemd/system/
下,则放着实际执行的systemd
启动脚本配置文件。同时,每一个运行级别在这个目录下都有对应的目录,下面放着对应运行级别会启动的服务,比如最常见的两个运行级别对应的文件就是graphical.target.wants
、multi-user.target.wants
,
因此如果你想要修改某个服务启动的设置,应该去/usr/lib/systemd/system/
下面修改,systemctl enable/disable
命令(操作/etc/init.d
以外的服务时)实际上就是在/usr/lib/systemd/system/
目录下创建连接或者删除连接。/etc/systemd/system/
仅是链接到正确的执行脚本配置文件而已。所以想要看执行脚本设置,应该就得要到/usr/lib/systemd/system/
去查阅。
详解 /usr/lib/systemd/system
systemctl
命令管理systemd
的资源 Unit。systemd
的 Unit 放在目录/usr/lib/systemd/system
(Centos) 或/etc/systemd/system
(Ubuntu)
centos:
…….
这里还有我们熟悉的服务:
这个目录下主要有四种类型的文件.mount
,.service
,.target
,.wants
-
.mount
文件,比如tmp.mount
,.mount
文件定义了一个挂载点,[Mount]
节点里配置了 What,Where,Type 三个数据项,等同于以下命令:1
mount -t [Type] [What] [Where]
-
.service
文件,比如atd.service
.service
文件定义了一个服务,分为[Unit],[Service],[Install]三个小节,常用的配置项如下,如果需要查看完整的配置项,请看systemd.service 中文手册 [译者:金步国]。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[Unit] Description # 描述, After # 在 哪些服务启动之后再启动 ConditionPathExists # 执行条件 [Service] Type # 服务类型,可以简单设置为 simple EnvironmentFile # 环境变量所在文件,一般指定 PATH ExecStart # systemctl start 时执行的脚本 ExecStop # systemctl stop 时执行的脚本 Restart # 什么时候重启 User # 以什么用户执行此服务 Group # 以什么用户执行此服务 [Install] Alias # 服务别名 WangtedBy # 在什么模式下使用,一般在指定为多用户模式 multi-user.target
-
.target
文件,.target
定义了一些基础的组件,供.service
文件调用 -
.wants
文件,.wants
文件定义了要执行的文件集合,每次执行,.wants
文件夹里面的文件都会执行
自定义 service 服务
我们可以自定义 service 服务,然后用 systemctl 来管理我们的服务,常见的做法时将一些脚本通过 service 服务包一层,然后通过 systemctl 来实现在任意目录下的一键执行,而且可以设置其开机自启,非常方便。
自定义 service 服务非常简单,在前面的详解 /usr/lib/systemd/system
小节我们已经了解过service
文件有哪些常见配置,现在我们就来写一个简单版本的 service 服务
首先我们在/opt
目录下创建两个两个脚本
start.sh
:
|
|
执行命令chmod a+rwx start.sh
赋权。
stop.sh
:
|
|
执行命令chmod a+rwx stop.sh
赋权。
然后创建simpleserv.service
文件:
|
|
并将其复制到/usr/lib/systemd/system/
或者/etc/systemd/system/
,
关于这两个目录的作用,请看
相关目录
小节
然后执行systemctl daemon-reload
刷新一下,然后即可通过systemctl start simpleserv
启动服务,启动之后通过systemctl status simpleserv
查看服务状态如下:
|
|
通过systemctl stop simpleserv
关闭服务,此时日志文件/opt/log.txt
的日志如下
|
|
甚至还可以通过systemctl enable simpleserv
设置此服务开机自启。
注意,在simpleserv.service
中有一个配置项RemainAfterExit=yes
,其作用是确定当该服务的所有进程全部退出之后是否依然将此服务视为活动 (active) 状态。默认值为 no
。
因为我们的ExecStart
配置的start.sh
脚本就是一个简单的 echo 语句,执行完之后,进程就退出了,此时如果不配置RemainAfterExit=yes
的话,执行完ExecStart
的命令后,service 就视为 inactive 状态,就会自动调用ExecStop
中的脚本。因此为了保证ExecStart
的脚本执行完之后,服务保持启动,我们就需要设置RemainAfterExit=yes
。
.service
文件的完整的配置项介绍,请看systemd.service 中文手册 [译者:金步国]。
在实际的场景中,ExecStart
一般不会为一个简单的 echo 命令,一般都会是一个长期执行的进程,比如 java 进程,此时也就不需要配置RemainAfterExit=yes
了。
systemctl 常见错误
-
code=exited, status=203/EXEC
,可能原因-
ExecStart
或者ExecStop
的脚本路径不对,或者脚本权限不够,不可执行,或者脚本没有 shebang 行,或者 shebang 行路径错误 -
SELinux 可能阻止了脚本的执行,可以到
/var/log/audit/audit.log
中检查,消息格式为type=AVC msg=audit([...]): avc: denied { execute }
,或者直接执行ausearch -ts recent -m avc -i
.
-
日志管理
Systemd 统一管理所有 Unit 的启动日志。带来的好处就是,可以只用 journalctl 一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是 /etc/systemd/journald.conf
。
journalctl 功能强大,用法非常多。
|
|
防火墙相关
什么是防火墙?防火墙相当于一个拦截器,Linux 系统外的程序想要访问系统端口,必须先通过防火墙,如果没有配置防火墙,则请求会被拦截,配置了防火墙规则,这个请求就可以通过防火墙正常访问端口。
在生产环境,一定要打开防火墙。
centos7 以后,防火墙(firewall)的服务不再是iptables
,而是firewalld
,需要 root 权限才可以运行。
firewall-cmd --state
:查看 firewall 的状态
firewall-cmd --query-port=8089/tcp
:查询端口状态
firewall-cmd --permanent --add-port=8089/tcp
:开启端口,重新载入,才能生效,对于协议,可以通过netstat -anp
查看对应端口的 IP
firewall-cmd --permanent --remove-port=8089/tcp
:移除端口,重新载入,才能生效
firewall-cmd --reload
:刷新(重载)防火墙配置
firewall-cmd --list-ports
:查看已经开放的端口
其他操作
systemctl status firewalld.service
:防火墙的状态
systemctl start firewalld.service
:开启防火墙
systemctl stop firewalld.service
:关闭防火墙
systemctl restart firewalld.service
:重启防火墙
案例:
在防火墙中打开一个端口,然后用 Windows 中用telnet
命令测试
首先本地启动 Tomcat,使用 8080 端口,这个时候 8080 端口没有开启,在 Windows 中用telnet
访问 Linux 虚拟机的 8080 是不通的,然后防火墙开启 8080 端口,然后 reload 防火墙,再在 Windows 中用telnet
访问 Linux 虚拟机的 8080 端口,就是通的了。
打开的端口和关闭的端口都各自有一个列表,添加端口就相当于在开启列表里加了一个端口。