systemd替代xinetd
背景
systemd已经逐步取代了init,现在又在蚕食xinetd这种init的衍生品,感觉cron也难逃魔爪。systemd在各大新的发行版上也是无往不利,感觉今后的服务器必将成为一大重器。但国内这方面资料还是比较少,大多都是官方手册的简单变换,少有见到一个真的实际使用。刚好手上有一个老的用xinetd的socket服务程序,手贱把服务器搞挂了,直接升了最新的fedora-server。系统默认不安装crond,远程服务器包里甚至完全没有xinetd程序。无赖只能自己编译安装xinetd或者使用systemd代替。编译安装是安装上了,但问题是编译安装好后不给提供service管理界面,头疼!用yum包安装的daemon程序都会有service文件,可以直接使用systemctl启动,关闭什么的。自己编译的xinetd简直不是亲儿子,啥都没有。还要自己考虑service文件。于是没办法反正都绕不开systemd就学习学习呗。
本文内容
systemd 简单认识
systemd.socket认识
systemd socket和service文件编写
firewalld 配置
systemd 简单认识
systemd是为取代initd这样的程序而产生的,对于比较早的linux系统开机有runlevel概念,现在都还一大堆教你怎么改runlevel的文章,对于比较新的发行版一般都没啥用了。基本上新一点的系统都用systemd取代了initd。为什么会用systemd而不继续使用initd啦?原因比较多,我一个菜鸟就不妄断了。大概就知道systemd管的比initd宽,启动上可以欺骗系统从而更快点。
对于用户而言最重要的就是怎么用的问题,systemd是后台服务程序不用如何在意,systemctl才是用户界面。平时打交道也都是这个程序,这个命令就比较麻烦了。功能太多所以交互也复杂,这里罗列一点平时经常使用的部分,对于更详细的介绍可以移步Systemctl详解
开启一个服务
systemctl start xxx.service
关闭一个服务
systemctl stop xxx.service
重启一个服务
systemctl restart xxx.service
查看服务状态
systemctl status xxx.service
设置开机启动target, 相当于老系统runlevel,常用target有multi-user.target(多用户带网络)
systemctl set-default xxx.target
设置service/socket/timer开机启动
systemctl enable xxx.service
关闭service/socket/timer开机启动
systemctl disable xxx.service
daemon程序重载
systemctl daemon-reload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
systemd.socket 认识
systemd有以下几种文件后缀结尾的文件:
target: 可以包含多种服务、程序的集合,打开这个target就会打开这个target关联的所有程序
socket: 定义一个套接字用,可以在socket文件里面关联端口和依赖等信息
timer: 定义一个时钟启动任务,可以理解为功能类似crond,只是配置方法不一样
service: 定义一个启动程序由systemctl管理。service文件有两种,一种包含@字符,一种不包含@字符。具体啥区别我也说不清楚,可以自行man systemd.service
mount/device/path/swap: 目前还没有使用过,有兴趣可以自行使用man命令查看
针对systemd替代xinetd主要就使用socket和service两种,而socket是要加入到target文件中才能实现开机启动
每一种文件都分为几个段落,每个段落有不同功能,具体可以使用man命令自行查看。这里只是简单说一下
service文件包含Unit,Service,Install三个段落。Unit主要定义本服务描述,依赖,启动先后等内容。Service包含启动相关信息,如启动命令,配置文件,启动时间,启动模式,工作目录等。其中的工作模式要说一下,主要使用的一般就simple,forking,oneshot,simple就相当于命令行启动;forking是后台运行相当于使用xinetd打开,oneshot只运行一次。Install字段定义这个服务包含于那一个target
socket文件包含Unit,Install,Socket三个字段。Unit和Service中的一样功能也类似,Socket字段包含了使用的端口信息和ip信息等相关内容
以上文件存放位置可以通过man systemd.unit查看有详细罗列。本人是将自己编写的文件存放在/etc/systemd/system/中,如果是单独的用户文件可以存放在~/.config/systemd/user/下,没有这个目录可以自行创建。管理user目录下的服务要在systemctl命令上加上–user选项,否则是管理的系统服务
以上信息都可以通过man命令自行查看手册完整内容
systemd socket和service文件编写
开始编写前说一下服务程序相关信息:
服务名 服务开启命令 服务使用端口号
xxserver xxserver 9888
file /etc/systemd/system/xxserver.socket
[Unit]
套接字描述
Description=XXX server
[Socket]
端口号
ListenStream=9888
IP类型ipv4 + ipv6
BindIPv6Only=both
使用socket功能就要开这个Accept
Accept=true
[Install]
包含在那个target中
WantedBy=sockets.target
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
file /etc/systemd/system/[email protected]
[Unit]
Description=xxserver
依赖上一个文件
Requires=xxserver.socket
在下面两个target后开启,因为我程序用了数据库,所以有mysqld.target
After=multi-user.target mysqld.target
[Service]
后台运行方式
Type=forking
有用到一个配置文件
EnvironmentFile=-/etc/xxxx
开启服务命令行
ExecStart=/usr/local/bin/pwserver
只能由socket调用开启
StandardInput=socket
Restart=on-failure
[Install]
WantedBy=multi-user.target
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
以上两个文件编好后就可以使用systemctl命令管理这个socket了
systemctl enable xxserver.socket // 把xxserver.socket加入到multi-user.target.wants,这个目录下全是一些service,timier,socket文件的链接
systemctl start xxserver.socket // 开启服务
systemctl stop xxserver.socket // 关闭服务
systemctl status xxserver.socket // 如果看到绿色的 Active: active (listening)就表示开启并监听成功,但很可能会开启出错可以使用键盘右方向键看下那里有错误。也可以使用journalctl命令查看,两个显示信息大部份也是相同的,只是journalctl要相对更详细一点
systemctl daemon-reload // 开启有错误,更改文件后使用它重载配置
1
2
3
4
5
firewalld 配置
上面一步完成其实就已经完成了使用systemd代替xinetd,后面的内容只是因为fedora34使用firewalld防火墙导致服务不能正常访问,写一起记录下。
firewalld是一个防火墙后台服务程序,前台界面是firewall-cmd。firewall-cmd使用有比较全的firewall-cmd的使用方法。
这里我只说下我的认识和注意项:
防火墙通过服务、端口、网卡三个项目管理电脑服务,所以要打开一个服务的访问就要分别开启这3个开关,废话不多说上命令
firewall-cmd --zone=public --list-ports // 当前打开的端口
firewall-cmd --zone=public --add-port=9888/tcp --permanent // 开机依然有效的打开9888的tcp端口
firewall-cmd --zone=public --add-interface=eth0 --permanent // 永久开启网卡对外权限,eth0是你的网卡名字,可以使用ifconfig查看
firewall-cmd --add-service=xxx --permanent
/* 以上命令是最麻烦的一个,因为如果你要自定义一个服务,那就要改文件。xinetd时代是通过更改/etc/service文件实现,
*在里面加入一行新内容就可以了。而firewalld明明有/etc/service文件它不用非要使用什么反人类.xml文件配置服务,也是不得不吐槽下。
- /etc/firewalld/services/目录下复制一个/lib/firewalld/services/下的任意xxx.xml文件。更改里面的
xxx 和 - 有了上面的文件firewall-cmd才能识别你的服务项不然就会显示下面这个错误*/
Authorization failed.
Make sure polkit agent is running or run the application as superuser.
还有一个注意项就是开服务时不能加上--zone=public,也不知道为什么。可以使用firewall-cmd --query-service=xxxx
查看一个服务是否开启,开启是yes,未开启是no
不确定是不是防火墙问题可以使用systemctl stop firewalld.service关闭防火墙先
除了防火墙linux还有一个selinux也会限制你通过网络使用服务程序,所以在这方面可以逐步排查,这里给一个临时关闭selinux命令setenforce 0
。具体可以自行搜索或man