Ubuntu18.04如何设置服务随系统启动

本文指导如何在Ubuntu18.04中使用systemd管理器配置rc-local.service实现开机启动,包括检查文件、创建链接、添加安装配置、设置开机启动以及解决rc-local.service文件结构和PIDFile问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


starting up
很多时候我们希望Linux系统启动时,同时启动一些服务。比如:我们期望部署MySQL的服务器重启后自动启动MySQL服务,部署Redis的服务器重启后自动启动redis-server服务…


一、背景说明

  • Ubuntu 18.04不再使用initd管理系统,改用systemd,包括用systemctl命令来替换了service和chkconfig的功能。
     
  • systemd 默认读取 /etc/systemd/system 下的配置文件,该目录下的文件会链接/lib/systemd/system/下的文件。
     
  • 不同于以往的版本,ubuntu18.04默认不带/etc/rc.local文件,我们需要通过配置来让rc.local.service生效。

二、操作步骤

根据背景说明中的内容,我们首先确定/etc/systemd/system目录下是否有rc-local.service文件。

2.1、检查/etc/systemd/system/rc-local.service是否存在

默认/etc/systemd/system目录中是不存在rc-local.service文件的:
在这里插入图片描述
此时再检查下/lib/systemd/system/rc-local.service文件是否存在:

# 检查/lib/systemd/system/rc-local.service是否存在
cd /lib/systemd/system/ && ll|grep rc

结果如下:
在这里插入图片描述
可以看到文件是存在的。

2.2、链接文件

执行如下命令:

# 链接文件
ln -s /lib/systemd/system/rc-local.service /etc/systemd/system/rc-local.service

打开目录:

cd /etc/systemd/system && ll

可以看到目录下多了一个链接文件:
在这里插入图片描述
注:其实这一节的步骤是可以省略的,后面3.1.1节会说明为什么可以省略。
 

2.3、rc-local.service追加Install配置

打开目录/lib/systemd/system/rc-local.service:

vim /lib/systemd/system/rc-local.service

内容如下:
在这里插入图片描述

在末尾追加配置:

...
[Install]
WantedBy=multi-user.target
Alias=rc-local.service

有关rc-local.service各个节的说明见:3.1.1

 

2.4、创建/etc/rc.local

在Ubuntu18.04中默认是没有/etc/rc.local这个文件(而上一节的配置中是指向这个文件的),所以需要手动创建:

# 创建rc.local文件
touch rc.local
# 编辑rc.local
vim rc.local

输入如下内容:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
exit 0

注:这个文件是开机启动的重点,前面的设置只需要设置一次。如果后续需要添加新的开机启动服务,只需要修改/etc/rc.local这一个文件

查看并设置权限

# 查看权限
ll|grep rc.local
# 增加执行权限
chmod +x rc.local

效果如下所示:
在这里插入图片描述

2.5、设置开机自动启动

设置开启启动:

systemctl enable rc-local

注:这里使用服务的别名(rc-local.service)。但是没有后缀.service
上面的命令只是将服务设为开机启动。如果不打算立即重启系统,但是又想立即启动 开机启动项,需要手动启动相关服务:

# 启动服务
systemctl start rc-local.service
# 查看服务是否启动
systemctl status rc-local.service

2.6、重启系统验证

重启系统:

reboot

重启好后,验证服务:

systemctl status rc-local.service

如若结果如下:
在这里插入图片描述
说明服务成功开机启动!!!

 

三、问题与总结

3.1、问题

3.1.1、Q1:rc-local.service文件的结构是怎样的?每个部分的作用分别是什么?

首先,systemd将系统资源划分为12种,每一种资源称为单元,对应的单元文件也有12种。其中扩展名为.service的资源文件作用如下:

封装守护进程的启动、停止、重启和重载操作,是最常见的一种 Unit 文件。

可以通过如下命令显示加载到内存的所有单元:

systemctl --all

或是通过如下命令查询服务类型的单元:

systemctl --type=service

Unit 文件可以分为三个配置区段:

  • Unit段 (通用段)
  • Service段 【服务(Service)类型的 Unit 文件(后缀为 .service)特有的
  • Install段 (通用段)

下面结合rc-local.service文件的内容介绍每个配置的意义
在这里插入图片描述

Unit段

该段定义:服务的启动顺序、依赖关系。
 

  • Description

当前服务的简单描述

  • Documentation

文档地址,可以是一个或多个文档的URL路径
 
但是图中的 man:systemd-rc-local-generator(8) 不是太明白是什么意思。
可能下面的命令

man 8 systemd-rc-local-generator

用于打开systemd-rc-local-generator的操作手册

  • ConditionFileIsExecutable

检查指定的绝对路径是否存在,是否是regular file,并且是否是可执行的。
 
相关配置可参考:https://manpages.ubuntu.com/manpages/lunar/en/man5/systemd.unit.5.html

  • After

指定的 Unit 全部启动完成以后,才会启动当前 Unit
 
图中network.target也是一种单元文件。它表示系统的一种状态(网络可用的状态)

Service段

  • Type

默认类型是simple,ExecStart字段启动的进程为主进程。
 
forking类型时,ExecStart字段以fork()方式启动子进程,子进程创建后父进程退出,子进程变为主进程。

  • 通常需要指定PIDFile字段,以便 Systemd 能够跟踪服务的主进程。

但是我设置了PIDFile字段后,启动服务发生了报错。报错信息如下:

root@proxy_server_01:/var/run# systemctl status rc-local
● rc-local.service - /etc/rc.local Compatibility
   Loaded: loaded (/lib/systemd/system/rc-local.service; enabled-runtime; vendor preset: enabled)
  Drop-In: /lib/systemd/system/rc-local.service.d
           └─debian.conf
   Active: activating (start) since Sat 2023-08-19 10:08:38 UTC; 3min 12s ago
     Docs: man:systemd-rc-local-generator(8)
    Tasks: 5 (limit: 1104)
   CGroup: /system.slice/rc-local.service
           └─2943 /usr/local/redis/bin/redis-server *:6379

Aug 19 10:08:38 proxy_server_01 systemd[1]: Stopped /etc/rc.local Compatibility.
Aug 19 10:08:38 proxy_server_01 systemd[1]: Starting /etc/rc.local Compatibility...
Aug 19 10:08:38 proxy_server_01 systemd[1]: rc-local.service: Can't open PID file /var/run/rc_local.pid (yet?) after start: No such file or direct

上面rc-local.service内容发生改变时,需要执行如下命令重新加载单元:

systemctl daemon-reload

说明:

  • 重启服务前,手动创建了/var/run/rc-local.pid文件
  • 重启时,手动创建的文件会被删除。

    有些网友的解释是每次服务重启时都会清空原pid文件。
    那么如何配置才能使得PIDFile生效,并且服务启动成功呢?

  • ExecStart

启动当前服务的命令

  • TimeoutSec

停止当前服务前等待的秒数

  • RemainAfterExit

值为yes时,表示服务进程退出时,服务依然保持执行(状态是激活的)。这样即使进程不存在了(可能是服务停止)依然可以重启服务。

  • GuessMainPID

指定systemd在无法确切的查明服务的时候是否需要猜测服务的main pid。

当Type=forking,且PIDFile没有指定值时,该配置才有意义,否则会忽略这个字段。

Install段

  • WantedBy

值是一个或多个target。

对应这个参数官方的解释是这样的:

After running systemctl enable, a symlink
/etc/systemd/system/multi-user.target.wants/foo.service linking to the actual unit will be
created. It tells systemd to pull in the unit when starting multi-user.target. The inverse
systemctl disable will remove that symlink again.

 
来源:https://manpages.ubuntu.com/manpages/lunar/en/man5/systemd.unit.5.html

WantedBy=multi-user.target
在systemctl enable执行后,会在/etc/systemd/system/multi-user.target.wants/目录生成符号链接?
但是好像没有找到…
在这里插入图片描述

重新执行如下命令后:

# 禁用服务
systemctl disable rc-local
# 结果输出:
Removed /etc/systemd/system/rc-local.service.
# 开机启动
systemctl enable rc-local.service 
# 结果:重新创建链接
Created symlink /etc/systemd/system/rc-local.service → /lib/systemd/system/rc-local.service.
Created symlink /etc/systemd/system/multi-user.target.wants/rc-local.service → /lib/systemd/system/rc-local.service.

查看符号链接
符号链接1:
在这里插入图片描述
符号链接2:
在这里插入图片描述
可以看到第二次执行systemctl enable后,重新生成了2个符号链接。由此可知官方文档所言非虚。
其中第一个符号链接是在2.2中生成过的。

那么,是不是2.2中的操作可以省略呢?

执行命令

# 禁用服务
systemctl disable rc-local.service
# 禁用服务的结果:删除2个符号链接
Removed /etc/systemd/system/rc-local.service.
Removed /etc/systemd/system/multi-user.target.wants/rc-local.service.

重新执行:

systemctl enable rc-local
systemctl start rc-local.service

服务可以正常启动,reboot后服务也可以随系统启动。
所以,步骤2.2是可以省略的

  • Alias

该单元的别名

 
有关systemd的详细讲解可参考下面的文章:

 

3.2、总结

本文主要介绍了Ubuntu18.04中如何增加开机启动,我们是基于/lib/systemd/system/rc-local.service去配置开机启动的。当然也可以选择创建自己的.service文件。

需要将/lib/systemd/system/rc-local.service链接到/etc/systemd/system,并在rc-local.service中追加Install段。rc-local.service前面介绍过是一种单元文件。符号链接无需像2.2节那样手动生成,执行systemctl enable时会自动生成2个符号链接(/etc/systemd/system/rc-local.service和 /etc/systemd/system/multi-user.target.wants/rc-local.service)

所有的服务启动命令是定义在/etc/rc.local中的,但是系统默认是没有该文件的,所以需要手动创建。输入启动命令后,为该文件赋执行权限(chmod +x)。

使用systemctl enable 启用服务随系统开机启动。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值