systemd:在启动 nginx 之前完成自定义 shell 脚本的执行

systemd:在启动 nginx 之前完成自定义 shell 脚本的执行

使用 Debian 9 stable,我想在启动 NGINX 进程和 shorewall 防火墙之前启动自定义 shell 脚本:

  • 做一些初始化工作
  • 挂载一个目录(overlayfs)以覆盖/etcNGINX 配置、shorewall 配置和/etc/hosts
  • 该脚本也以 结尾sync,不确定这是否是一个好主意

systemctl 列表依赖项
default.target
● ├─display-manager.service
● ├─systemd-update-utmp-runlevel.service
● └─multi-user.target
● ├─console-setup.service
● ├─cron.service
● ├─dbus.service
● ├─dropbear.service
● ├─myservice.service <-- 我的服务(使用systemctl启用创建的链接)
● ├─networking.service
● ├─nginx.service <-- 在myservice之后执行
[ ...]
● ├─basic.target
● │ ├─-.mount
● │ ├─myservice.service <-- 我的服务(使用 systemctl enable 创建的链接)
● │ ├─shorewall.service <-- 之后执行我的服务

myservice.service 尝试 1

[Unit]
Description=我的启动服务
Requires=shorewall.service nginx.service
Before=shorewall.service nginx.service

[Service]
RemainAfterExit=yes
ExecStart=/usr/local/bin/myservice start
ExecStop=/usr/local/bin/ myservice stop

[安装]
WantedBy=multi-user.target
WantedBy=basic.target

日志:

Journalctl [...]
10 月 12 日 11:31:43 server-dev nginx[448]: nginx: [emerg] 在 /etc/nginx/sites-enabled/default 中的上游“server-dev.com”中找不到主机: 10 月 12 日33
11:31:43 server-dev nginx[448]: nginx: 配置文件 /etc/nginx/nginx.conf 测试失败 <== NGINX: BAD
10 月 12 日 11:31:43 server-dev systemd[1] : nginx.service: 控制进程已退出,code=exited status=1
Oct 12 11:31:43 server-dev systemd[1]: 无法启动高性能 Web 服务器和反向代理服务器。
10 月 12 日 11:31:43 server-dev systemd[1]:nginx.service:单元进入失败状态。
10 月 12 日 11:31:43 server-dev systemd[1]:nginx.service:失败,结果为“退出代码”。
10 月 12 日 11:31:43 server-dev systemd[1]:达到目标多用户系统。
10 月 12 日 11:31:43 server-dev systemd[1]:达到目标图形界面。
10 月 12 日 11:31:43 server-dev systemd[1]:开始更新有关系统运行级别更改的 UTMP...
10 月 12 日 11:31:43 server-dev systemd[1]:开始更新有关系统运行级别更改的 UTMP。
10 月 12 日 11:31:43 server-dev server[423]: DO: 服务器启动 DONE <== 脚本结束 myservice
10 月 12 日 11:31:43 server-dev shorewall[449]: 使用 Shorewall 5.0.15.6 进行编译.. <== SHOREWALL:好
10 月 12 日 11:31:44 server-dev shorewall[449]:正在处理 /etc/shorewall/shorewall.conf...
10 月 12 日 11:31:44 server-dev shorewall[449]:正在加载模块...

执行 myservice 后,Shorewall 系统正确启动。 Nginx 大部分时间是在 myservice 执行期间启动的,在/etc正确覆盖(覆盖?)之前,因此无法正确初始化。

myservice.service 尝试 2

我也尝试过改变

[安装]
WantedBy=default.target

并改变

[单位]
之前=多用户.目标

它也不起作用。

如何确保nginx和shorewall在myservice执行后启动?

答案1

如果您不指定 systemd 服务的类型,则默认为Type=simple.这意味着服务在其主服务进程被分叉时被视为启动(此时它甚至还没有执行命令ExecStart)。您可能想改用Type=oneshot它,它会等待ExecStart命令退出,然后再考虑服务已启动。请参阅man systemd.service了解更多详情。

答案2

您可以使用ExecStartPre=插入式片段配置中的选项将选项添加到 Nginx 服务单元,而不是使用单独的选项(或添加Requires=shorewall.service到 nginx 服务单元,尽管我建议不要这样做)。

使用该命令(它使用嵌入式片段配置sudo systemctl edit nginx.service创建目录)。/etc/systemd/system/nginx.service.d

类型:

[Unit]
Requires=shorewall.service
After=shorewall.service

或者:

[Service]
ExecStartPre=/usr/bin/your_script

这将始终在启动 nginx 服务单元之前执行您的脚本。您应该将(因为它是 shell 脚本并且默认情况下不支持重定向)添加IgnoreSIGPIPE=no到服务部分,否则 Systemd 将忽略重定向、管道和信号。

用于:挂载一个目录(overlayfs)以覆盖/etcNGINX 配置、shorewall 配置和 /etc/hosts。

添加到服务部分:

TemporaryFileSystem=/etc:ro,nodev,noexec,nosuid

这会在目录顶部安装一个空白的 tmpfs 安装点/etc。您需要绑定挂载(使用BindReadOnlyPaths=, ) (2 个目录和 5 个文件)BindPaths=中的所有必需文件。/etc

要绑定挂载主机文件:

BindReadOnlyPaths=/etc/hosts

(将 openssl、ca 证书和名称服务添加到;))

systemd.exec使用.无需任何脚本即可设置环境、容器化、命名空间、沙箱、MAC/IPS 。

相关内容