zsx

zsx

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

Dockerコンテナ内でサービスを実行する

サービスを Docker コンテナ内で実行する#

最近書いているあるコンテナがアーキテクチャをアップグレードし、コンテナを起動する際に frps サービスを同時に実行する必要があります。私の習慣に従い、最初は systemctl を使用して frps サービスを追加し、enable して自動起動を実現しようとしました。しかし、実際に使用してみると、サービスが起動しませんでした。ログを調べたところ、次のエラーメッセージが表示されました:

ERROR:systemctl: frps.service: Executable path is not absolute, ignoring: ./frps -c /frps.ini
ERROR:systemctl: Exec is not an absolute path: ExecStart=./frps -c /frps.ini
ERROR:systemctl: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR:systemctl: Found 1 problems in /etc/systemd/system/frps.service
ERROR:systemctl: The SystemD commands must always be absolute paths by definition.
ERROR:systemctl: Earlier versions of systemctl.py did use a subshell thus using $PATH
ERROR:systemctl: however newer versions use execve just like the real SystemD daemon
ERROR:systemctl: so that your docker-only service scripts may start to fail suddenly.
ERROR:systemctl: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

公式サイトで少し調べたところ、次のような説明がありました:

これは設計によるものです。Docker はコンテナ内でフォアグラウンドでプロセスを実行する必要があり、コンテナの pid 名前空間内で PID 1 として生成されます。Docker はプロセスの隔離のために設計されており、OS の仮想化のためではないため、コンテナ内で実行される他の OS プロセスやデーモン(systemd、cron、syslog など)は存在せず、あなたのエントリポイントまたは実行するコマンドのみが存在します。
もし systemd コマンドが含まれていた場合、エントリポイントが init を置き換えるため、動作しないことが多くなるでしょう。systemd は cgroups を利用しますが、Docker はコンテナ内で制限しているため、cgroups を変更する能力がプロセスにコンテナの隔離を逃れることを許可する可能性があります。コンテナ内で init として systemd が実行されていない場合、スタートおよびストップコマンドを処理するデーモンは存在しません。

要するに:Docker はプロセスの隔離を提供するだけで、OS の仮想化ではないため、systemd を実行することはできません。

もし二つのサービスを同時に実行したい場合、どのような方法を使えばよいのでしょうか?実はとても簡単です:Dockerfile の CMD 内で start.sh を実行し、その後 nohup で frps サービスをバックグラウンドにするだけです:
nohup ./frps -c /frps.ini &
python3 /main.py
無事に frps サービスが実行されます。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。