systemd和sysv服务管理和配置
systemd服务管理和配置
systemd是centos7的系统初始化进程,它通过 Unit(xxx.service)文件来管理linux系统的服务。
Unit文件目录
路径 |
说明 |
/etc/systemd/system |
系统或用户的配置文件 |
/run/systemd/system |
软件运行时生成的配置文件 |
/lib/systemd/system |
系统的配置文件 |
/usr/lib/systemd/system |
系统或第三方软件的配置文件 |
Unit文件结构
Service 的 Unit 文件可以分为3个配置区段,其中 Unit 和 Install 段是所有 Unit 文件通用的,用于配置服务(或其他系统资源)的描述、依赖和随系统启动方式。而 Service 段则是服务类型的 Unit 文件(后缀.service)特有的,用于定义服务的具体管理和操作方法。其他的每种配置文件也都会有一个特有的配置段,这就是几种不同 Unit 配置文件最明显的区别。
一、Unit 段
- Description
一段描述这个 Unit 文件的文字,通常只是简短的一句话。
- Documentation
指定服务的文档,可以是一个或多个文档的URL路径。
- Requires
依赖的其他 Unit 列表,列在其中的 Unit 模块会在这个服务启动的同时被启动,并且如果其中有任意一个服务启动失败,这个服务也会被终止。
- Wants
与 Requires 相似,但只是在被配置的这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模块启动是否成功。
- After
与 Requires 相似,但会在后面列出的所有模块全部启动完成以后,才会启动当前的服务。
- Before
与 After 相反,在启动指定的任一个模块之前,都会首先确保当前服务已经运行。
- BindsTo
与 Requires 相似,但是一种更强的关联。启动这个服务时会同时启动列出的所有模块,当有模块启动失败时终止当前服务。反之,只要列出的模块全部启动以后,也会自动启动当前服务。并且这些模块中有任意一个出现意外结束或重启,这个服务会跟着终止或重启。
- PartOf
这是一个 BindTo 作用的子集,仅在列出的任何模块失败或重启时,终止或重启当前服务,而不会随列出模块的启动而启动。
- OnFailure
当这个模块启动失败时,就自动启动列出的每个模块。
- Conflicts
与这个模块有冲突的模块,如果列出模块中有已经在运行的,这个服务就不能启动,反之亦然。
二、Install 段
这个段中的配置与 Unit 有几分相似,但是这部分配置需要通过 systemctl enable 命令来激活,并且可以通过 systemctl disable 命令禁用。另外这部分配置的目标模块通常是特定启动级别的 .target 文件,用来使得服务在系统启动时自动运行。
- WantedBy
和前面的 Wants 作用相似,只是后面列出的不是服务所依赖的模块,而是依赖当前服务的模块。
- RequiredBy
和前面的 Requires 作用相似,同样后面列出的不是服务所依赖的模块,而是依赖当前服务的模块。
- Also
当这个服务被 enable/disable 时,将自动 enable/disable 后面列出的每个模块。
“WantedBy=multi-user.target 表明当系统以多用户方式(默认的运行级别)启动时,这个服务需要被自动运行。当然还需要 systemctl enable 激活这个服务以后自动运行才会生效。关于 Linux 系统启动时的运行级别,可以参看这篇文章。
三、Service 段
这个段是 .service 文件独有的,也是对于服务配置最重要的部分。这部分的配置选项非常多,主要分为服务生命周期控制和服务上下文配置两个方面,下面是比较常用到的一些参数。
服务生命周期控制相关的参数:
- Type
服务的类型,常用的有 simple(默认类型) 和 forking。默认的 simple 类型可以适应于绝大多数的场景,因此一般可以忽略这个参数的配置。而如果服务程序启动后会通过 fork 系统调用创建子进程,然后关闭应用程序本身进程的情况,则应该将 Type 的值设置为 forking,否则 systemd 将不会跟踪子进程的行为,而认为服务已经退出。
- PIDFile
守护进程的PID文件,必须是绝对路径。 强烈建议在 Type=
forking
的情况下明确设置此选项。 systemd 将会在此服务启动后从此文件中读取主守护进程的PID 。 systemd 不会写入此文件, 但会在此服务停止后删除它(若存在)。
- RemainAfterExit
值为 true 或 false(也可以写 yes 或 no),默认为 false。当配置值为 true 时,systemd 只会负责启动服务进程,之后即便服务进程退出了,systemd 仍然会认为这个服务是在运行中的。这个配置主要是提供给一些并非常驻内存,而是启动注册后立即退出然后等待消息按需启动的特殊类型服务使用
- ExecStart
这个参数是几乎每个 .service 文件都会有的,指定服务启动的主要命令,在每个配置文件中只能使用一次。
- ExecStartPre
指定在启动执行 ExecStart 的命令前的准备工作,可以有多个,如前面第二个例子中所示,所有命令会按照文件中书写的顺序依次被执行。
- ExecStartPost
指定在启动执行 ExecStart 的命令后的收尾工作,也可以有多个。
- TimeoutStartSec
启动服务时的等待的秒数,如果超过这个时间服务任然没有执行完所有的启动命令,则 systemd 会认为服务自动失败。这一配置对于使用 Docker 容器托管的应用十分重要,由于 Docker 第一次运行时可以能会需要从网络下载服务的镜像文件,因此造成比较严重的延时,容易被 systemd 误判为启动失败而杀死。通常对于这种服务,需要将 TimeoutStartSec 的值指定为 0,从而关闭超时检测,如前面的第二个例子。
- ExecStop
停止服务所需要执行的主要命令。
- ExecStopPost
指定在 ExecStop 命令执行后的收尾工作,也可以有多个。
- TimeoutStopSec
停止服务时的等待的秒数,如果超过这个时间服务仍然没有停止,systemd 会使用 SIGKILL 信号强行杀死服务的进程。
- Restart
这个值用于指定在什么情况下需要重启服务进程。常用的值有 no,on-success,on-failure,on-abnormal,on-abort 和 always。默认值为 no,即不会自动重启服务。这些不同的值分别表示了在哪些情况下,服务会被重新启动,参见下表。
服务退出原因 |
no |
always |
on-failure |
on-abnormal |
on-abort |
no-success |
正常退出 |
√ |
√ |
||||
异常退出 |
√ |
√ |
||||
启动/停止超时 |
√ |
√ |
√ |
|||
被异常KILL |
√ |
√ |
√ |
√ |
- RestartSec
如果服务需要被重启,这个参数的值为服务被重启前的等待秒数。
- ExecReload
重新加载服务所需执行的主要命令。
- Environment
为服务添加环境变量,如前面的第一个例子中所示。
- EnvironmentFile
指定加载一个包含服务所需的环境变量列表的文件,文件中的每一行都是一个环境变量的定义。
- Nice
服务的进程优先级,值越小优先级越高,默认为0。-20为最高优先级,19为最低优先级。
- WorkingDirectory
指定服务的工作目录。
- RootDirectory
指定服务进程的根目录( / 目录),如果配置了这个参数后,服务将无法访问指定目录以外的任何文件。
- User
指定运行服务的用户,会影响服务对本地文件系统的访问权限。
- Group
指定运行服务的用户组,会影响服务对本地文件系统的访问权限。
- LimitCPU / LimitSTACK / LimitNOFILE / LimitNPROC 等
限制特定服务可用的系统资源量,例如 CPU,程序堆栈,文件句柄数量,子进程数量… 不再展开说明了,值的含义可参考 Linux 文档资源配额部分中 RLIMIT_ 开头的那些参数们。
Unit文件模板
在现实中,往往有一些应用需要被复制多份运行,例如在一个负载均衡实例后面运行的多个相同的服务实例。但是按照之前的例子,每个服务都需要一个单独的 Unit 文件,这样复制多份相同文件的做显然不便于服务的管理。为此 Systemd 定义了一种特殊的 Service Unit文件,称为 Unit 模板。
模板文件的主要特点是,文件名以@符号结尾,而启动的时候指定的Unit名称为模板名称附加一个参数字符串。例如,将之前的例子第二个 Unit 文件修改为可以用于启动多个实例的模板。一、首先修改文件名,添加一个@符号
例如原来的文件名是 apache.service,那么可以将它修改为 apache@.service,这样做的目的是表面这个文件是一个模板文件。而在服务启动时可以在@后面放置一个用于区分服务实例的附加字符串参数,通常这个参数会使用监听的端口号或使用的控制台TTY编号等。例如 “systemctl start apache@8080.service”。二、然后修改 Unit 文件内容
Unit 文件中可以获取服务启动时的附加参数,因此需要使用站位符替换Unit 文件中不应固定的部分,例如服务监听的 IP 和端口。
常用的占位符有6种(占位符文档),这些占位符会在 Unit 启动时被实际的值动态的替换掉。
占位符 |
作用 |
%n |
完整的 Unit 文件名字,包括 .service 后缀名 |
%m |
实际运行的节点的 Machine ID,适合用来做Etcd路径的一部分,例如 /machines/%m/units |
%b |
作用有点像 Machine ID,但这个值每次节点重启都会改变,称为 Boot ID |
%H |
实际运行节点的主机名 |
%p |
Unit 文件名中在 @ 符号之前的部分,不包括 @ 符号 |
%i |
Unit 文件名中在 @ 符号之后的部分,不包括 @ 符号和 .service 后缀名 |
配置nginx服务
配置nginx.service
[Unit] Description=nginx After=network.target #一般服务都配置成在网络模块启动后启动 [Service] Type=forking PIDFile=/var/run/nginx.pid #需要在nginx.conf中配置nginx.pid ExecStart=/usr/local/bin/nginx -c /usr/local/nginx/conf/nginx.conf ExecStop=/usr/local/bin/nginx -s stop ExecReload=/usr/local/bin/nginx -s reload [Install] WantedBy=multi-user.target #一般服务都配置成在多用户下自动启动
配置nginx.conf
#运行用户 user root; #启动进程,通常设置成和cpu的数量相等 worker_processes 1; #全局错误日志及PID文件 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; pid /var/run/nginx.pid; #与nginx.service中相同 events{ . . . } http{ . . . }
启动nginx服务
mv nginx.service /usr/lib/systemd/system chmod 766 /usr/lib/systemd/system/nginx.service systemctl daemon-reload systemctl enable nginx systemctl start nginx
systemctl和service
systemd使用systemctl管理linux的所有服务,sysV使用service管理linux的所有服务。
以下是systemctl和service命令的对比:
Sysvinit Command | Systemd Command | Notes |
---|---|---|
service nginx start | systemctl start nginx.service | Used to start a service (not reboot persistent) |
service nginx stop | systemctl stop nginx.service | Used to stop a service (not reboot persistent) |
service nginx restart | systemctl restart nginx.service | Used to stop and then start a service |
service nginx reload | systemctl reload nginx.service | When supported, reloads the config file without interrupting pending operations. |
service nginx condrestart | systemctl condrestart nginx.service | Restarts if the service is already running. |
service nginx status | systemctl status nginx.service | Tells whether a service is currently running. |
ls /etc/rc.d/init.d/ | systemctl list-unit-files --type=service (preferred) ls /lib/systemd/system/*.service /etc/systemd/system/*.service |
Used to list the services that can be started or stopped Used to list all the services and other units |
chkconfig nginx on | systemctl enable nginx.service | Turn the service on, for start at next boot, or other trigger. |
chkconfig nginx off | systemctl disable nginx.service | Turn the service off for the next reboot, or any other trigger. |
chkconfig nginx | systemctl is-enabled nginx.service | Used to check whether a service is configured to start or not in the current environment. |
chkconfig --list | systemctl list-unit-files --type=service(preferred) ls /etc/systemd/system/*.wants/ |
Print a table of services that lists which runlevels each is configured on or off |
chkconfig nginx --list | ls /etc/systemd/system/*.wants/nginx.service | Used to list what levels this service is configured on or off |
chkconfig nginx --add | systemctl daemon-reload | Used when you create a new service file or modify any configuration |