使用 Debian 9 stable,我想在启动 NGINX 进程和 shorewall 防火墙之前启动自定义 shell 脚本:
- 做一些初始化工作
- 挂载一个目录(overlayfs)以覆盖
/etc
NGINX 配置、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)以覆盖/etc
NGINX 配置、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 。