zsx

zsx

先作为主站备份 源站:https://my.toho.red

在Docker容器中运行服务

在 Docker 容器中运行服务#

最近正在写的某个容器升级了一下架构,在启动容器时需要同时运行一个 frps 服务。根据我的习惯,一开始打算使用 systemctl 添加 frps 服务,然后 enable 一下以实现开机自启。但在我实际使用时,发现服务没有跑起来。查了一下日志,发现了这条报错:

错误:systemctl:frps.service:可执行路径不是绝对路径,忽略:./frps -c /frps.ini
错误:systemctl:Exec 不是绝对路径:ExecStart=./frps -c /frps.ini
错误:systemctl:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
错误:systemctl:在 /etc/systemd/system/frps.service 中发现 1 个问题
错误:systemctl:根据定义,SystemD 命令必须始终是绝对路径。
错误:systemctl:早期版本的 systemctl.py 确实使用子 shell,因此使用 $PATH
错误:systemctl:但是较新的版本使用与真实 SystemD 守护程序相同的 execve
错误:systemctl:因此,您的仅限于 docker 的服务脚本可能会突然失败。
错误:systemctl:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

去官网稍微找了下,发现了这段解释:

这是设计如此。Docker 应该在容器中前台运行一个进程,并且它将作为 PID 1 在容器的 pid 命名空间中生成。Docker 设计用于进程隔离,而不是用于操作系统虚拟化,因此容器内没有其他操作系统进程和守护程序运行(如 systemd、cron、syslog 等),只有您的入口点或您运行的命令。
如果它们包含 systemd 命令,您会发现很多事情无法正常工作,因为您的入口点替换了 init。Systemd 还使用 cgroups,而 docker 在容器内限制了对 cgroups 的更改,因为更改 cgroups 的能力可能允许进程逃脱容器的隔离。在容器内没有作为 init 运行的 systemd,没有守护程序来处理您的启动和停止命令。

大意就是:docker 只是提供了进程隔离,不是操作系统的虚拟,所以不能运行 systemd。

如果只想同时运行两个服务,应该用什么办法呢?其实很简单:在 Dockerfile CMD 内运行 start.sh,然后再用 nohup 挂起 frps 服务就好了:
nohup ./frps -c /frps.ini &
python3 /main.py
顺利运行 frps 服务。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。