zsx

zsx

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

在Docker容器中運行服務

在 Docker 容器中運行服務#

最近正在寫的某個容器升級了一下架構,在啟動容器時需要同時運行一個 frps 服務。根據我的習慣,一開始打算使用 systemctl 添加 frps 服務,然後 enable 一下以實現開機自啟。但在我實際使用時,發現服務沒有跑起來。查了一下日誌,發現了這條報錯:

ERROR:systemctl: frps.service: 可執行路徑不是絕對路徑,忽略:./frps -c /frps.ini
ERROR:systemctl: Exec 不是絕對路徑: ExecStart=./frps -c /frps.ini
ERROR:systemctl: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR:systemctl: 在 /etc/systemd/system/frps.service 中發現 1 個問題
ERROR:systemctl: 根據定義,SystemD 命令必須始終是絕對路徑。
ERROR:systemctl: 早期版本的 systemctl.py 使用子殼層,因此使用 $PATH
ERROR:systemctl: 但是新版本使用 execve,就像真正的 SystemD 守護程序一樣
ERROR:systemctl: 因此,僅限於 Docker 的服務腳本可能會突然失敗。
ERROR:systemctl: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

去官網稍微找了下,發現了這段解釋:

This is by design. Docker should be running a process in the foreground in your container and it will be spawned as PID 1 within the container’s pid namespace. Docker is designed for process isolation, not for OS virtualization, so there are no other OS processes and daemons running inside the container (like systemd, cron, syslog, etc), only your entrypoint or command you run.
If they included systemd commands, you’d find a lot of things not working since your entrypoint replaces init. Systemd also makes use to cgroups which docker restricts inside of containers since the ability to change cgroups could allow a process to escape the container’s isolation. Without systemd running as init inside your container, there’s no daemon to process your start and stop commands.

大意就是:docker 只是提供了進程隔離,不是操作系統的虛擬,所以不能運行 systemd。

如果只想同時運行兩個服務,應該用什麼辦法呢?其實很簡單:在 Dockerfile CMD 內運行 start.sh,然後再用 nohup 掛起 frps 服務就好了:
nohup ./frps -c /frps.ini &
python3 /main.py
順利運行 frps 服務。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。