web-dev-qa-db-ja.com

Docker:異なるコンテナーに対してCronjobを実行する

私のphp fpmコンテナーのcronjobsの実行に関するベストプラクティスを探しています。

現在実行中:

  • NGINXコンテナ
  • PHP FPMコンテナー
  • MySQLコンテナ

私は今、「Cronjob Container」と呼ばれる別のコンテナを実行して、私のPHP FPM Container内でスクリプトを実行することを望んでいます(PHP)のいくつかの依存関係が必要です) 。

したがって、3つの可能な解決策:

1。)独自のコンテナを実行する

このソリューションを使用したいです。

私のphp fpmコンテナーでdocker execを(どういうわけか)呼び出すことができるCRONを実行しているコンテナーがあるとよいでしょう...または別の方法があります。

2。)PHP Container内でCRONを実行する

これは問題ありませんが、ベストプラクティスではありません。 cronを実行しているphp fpmコンテナー内で2番目のプロセスを開始できます。これはうまくいくでしょうが、これがあなたがdockerで働くべきかどうかはわかりません。

。)実行中のホストcron

これは残酷です。特定のパスのprocessIDとcontainerIDを見つけて、docker execを実行する必要があります。しかし、これが多かれ少なかれ私の最後の方法です...そして、私は展開せずにcronjobsを管理するのが嫌いです。

では、ここでの最良のアプローチは何ですか?

ごきげんよう、

バスティアン

4

コンテナーを監視し、メタデータで定義されたジョブをスケジュールするデーモンを作成しました。これは1)ソリューションに最も近いものです。例:

version: '2'

services:
  wordpress:
    image: wordpress
  mysql:
    image: mariadb
    volumes:
      - ./database_dumps:/dumps
    labels:
      deck-chores.dump.command: sh -c "mysqldump --all-databases > /dumps/dump-$$(date -Idate)"
      deck-chores.dump.interval: daily

「クラシック」のcronのような構成も可能です。

こちらが docs で、こちらが image repository です。

4
funky-future

Cron自体をインストールしてフォアグラウンドで実行できます(cron -f)コンテナへのインストールを非常に簡単にします。他のコンテナーにアクセスするには、おそらくクライアントCLIの同じコンテナーにDockerをインストールします(デーモンを実行するためではありません)。次に、ホストDocker環境にアクセスするための最も一般的なソリューションは、Dockerソケットをバインドマウントすることです(-v /var/run/docker.sock:/var/run/docker.sock)。唯一の問題は、ホストgidと一致するようにコンテナー内のdocker gidをセットアップし、コンテナー内のユーザーをdockerグループに追加する必要があることです。

これは、これらのユーザーがホスト上の任意のDockerユーザーと同じアクセス権を持つことを意味します。 rootレベルのアクセス。したがって、それらを送信するユーザーを完全に信頼するか、Sudoの同等のもので実行できるコマンドを制限する必要があります。もう1つの欠点は、これは移植性が低く、セキュリティを意識した管理者がシステムでのコンテナの実行を承認する可能性が低いことです。

オプションBへのフォールバックは、supervisordなどのツールを使用すると非常に簡単です。理想的な「コンテナごとに1つのプロセス」とは言えませんが、コンテナ全体と依存関係をまとめて保持し、ホストに対するセキュリティリスクを排除するため、これはまったくアンチパターンではありません。

最初のオプションと2番目のオプションのどちらを使用するかに関係なく、ジョブを送信するユーザー、ジョブを送信する必要のあるコンテナーの数などが環境に影響します。多くのコンテナーに対してジョブを送信する管理者の場合、cronコンテナーはセンス。ただし、アプリにパッケージとしてスケジュールされたジョブを含める必要があるアプリケーション開発者は、2番目のオプションを選択してください。

3
BMitch

別のコンテナまたはホストでcronを実行しますが、php-fpmを介してスクリプトを実行します(例:cronは "curl"または何かPHPスクリプト)。

セキュリティトークンやネットワークの制限などを使用して、このような設定を保護するようにしてください。最大1つのプロセスを生成できる動的プロセスを備えた独立したphp-fpmプールを使用することもできます。このプールにはcronのみがアクセスできます。また、実行時間の増大、メモリの多かれ少なかれなど、それ自身の個別の設定にもメリットがあります。

PS: this のようなものを使用して、スクリプトをFPMコンテナーで直接呼び出し、nginxを経由しないでください。

理由:おそらく、同じライブラリ、同じ構成などにアクセスする必要があります。Dockerでシグナルマネージャーによって制御されずにランダムに生成されたプロセスを実行することは、非常に悪い考えです。

3

私は同じようなことを達成しようとしていました。

私の最初のアイデアは、独立したcronコンテナーからcronジョブを開始し、実際に別のコンテナー(php)内で実行することでした。 crontabコンテナ内で異なるスクリプトを実行するdocker run -i t $containerName $scriptName ...コマンドごとに1つのphpレコードを持つ

@ BMitch についても言及しているため、このアプローチはあまりよくありません。また、私はdockerをコンテナにインストールしたくないのです。

あなたの#1カテゴリに適合する別のソリューションを提供したいと思います。php-fpmを直接実行できます。これは世界で最もエレガントなソリューションではありませんが、次のような利点があります。

  1. セキュリティ-特別なアクセスや特権アクセスはありません。Docker仮想ネットワーク内からnginxに対してすでに開いているホストとポート(php-Host:9000など)を使用するだけです
  2. cron管理をphpコンテナーから分離することで、スケーリングが損なわれない
  3. 実際にcronをクロニッシュタスクに使用する-crontabを植えて、他のさまざまなライブラリを介してcronを再実装する代わりに実行する
  4. スクリプトの実行はnginxを経由しないため、誰もWebサーバー経由で直接実行することはできず、認証やそのようなメカニズムを実装する必要はありません。
  5. アクセス許可に関する問題はさらに少なくなります。以前のcronドッキングは、cronを別のphpコンテナー内にインストールし、ボリュームを使用してコードベースを共有することでした。これは効率的でしたが、キャッシュ、DI、ログなどがWebサーバーとcronユーザーの両方からアクセスおよび書き込み可能である必要があるため、権限は慎重に処理する必要がありました。このアプローチは問題を排除します

これまでに遭遇した唯一の欠点は、ハッシュバング付きの最初の行(#!/usr/local/bin/php)が実際の出力と見なされ、すでに送信されたヘッダーに関するPHP警告が出力されることです(Cannot modify header information - headers already sent by ...)-ハッシュバングを削除するとこれが修正されます。

実際にそれを行う方法は?

  1. Alpine:3.7などのクリーンなコンテナを用意してください
  2. apk-cronfcgiをインストールします( パッケージ情報
  3. 次のようなものを実行します:
SCRIPT_FILENAME=/docroot/scripts/cron/example-script.php \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect php-fpm:9000

crontab内から。

トピックの詳細: PHP-FPMに直接接続

1
helvete