2015-01-05 12 views
21

最近、リンクドッカーコンテナ内でcronジョブを実行して問題が発生しました。私の主なドッカーコンテナはpostgresコンテナにリンクされていて、そのポート番号はコンテナの作成時にドッカーによって環境変数として設定されます。この環境変数は、〜/ .profileまたはcronジョブの実行時にロードできる他のソースファイルには設定されていません。私はどのように私のcronジョブからこれらの環境変数にアクセスできますか?CockジョブからDocker環境変数にアクセスするにはどうすればいいですか

ありがとう!

+1

この投稿は質問http://stackoverflow.com/questions/26822067/running-cron-python-jobs-within-dockerに答えるように見えます – user2915097

答えて

3

ラッパーシェルスクリプトを使用してcronデーモンを実行することで、crontabファイルの先頭にシステム環境変数を追加することができます。次の例では、Dockerfile

COPY my_cron /tmp/my_cron 
COPY bin/run-crond.sh run-crond.sh 
RUN chmod -v +x /run-crond.sh 
CMD ["/run-crond.sh"] 

ではCentOSの7、

からですrun_cron.sh:

#!/bin/bash 

# prepend application environment variables to crontab 
env | egrep '^MY_VAR' | cat - /tmp/my_cron > /etc/cron.d/my_cron 

# Run cron deamon 
# -m off : sending mail is off 
# tail makes the output to cron.log viewable with the $(docker logs container_id) command 
/usr/sbin/crond -m off && tail -f /var/log/cron.log 

これはどこかの偉大なブログ記事に基づいていますが、私は、リンクを失っています。

2

環境は設定されていますが、cronジョブでは使用できません。それを修正するには、これらの2つの簡単な事

1を行うことができます)ファイルへのenvを保存しますENTRYPOINTまたはCMD

CMD env > /tmp/.MyApp.env && /bin/MyApp 

2)次に、このようなあなたのcronコマンドにそのENVをお読みください。

0 5 * * * . /tmp/.MyApp.env; /bin/MyApp 
+3

envの値に空白やパイプなどの文字が含まれていると、これは機能しません –

+0

envの行を空白やパイプで正しくエスケープする必要があります。 – GDorn

19

この同じ問題が発生しました。私は定期的にいくつかのシェルスクリプトを実行するcronを実行するドッカーコンテナを持っています。私も、コンテナの中で手動でスクリプトを実行したときにスクリプトがうまく動作する理由を知るのは苦労しました。私は環境を設定するために最初に実行されるシェルスクリプトを作成するすべてのトリックを試みましたが、私のために働いたことはありませんでした(おそらく私は間違っていました)。しかし、私は探し続けてこれを発見し、それは動作します。あなたのcronコンテナ

  • の開始またはエントリポイントのシェルスクリプトは、この最初の行はprintenv | grep -v "no_proxy" >> /etc/environment
  • ここでのトリックを実行するようにしてください

    1. セットアップは/etc/environmentファイルです。コンテナがビルドされたときにそのファイルが空の場合、私は意図的に思っています。このファイルの参照は、マニュアルページのcron(8)にあります。 cronのすべてのバージョンを調べた後、それらはすべて/etc/?ファイルにあります。このファイルを使用して、環境変数を子プロセスに送ることができます。

      また、フォアグラウンドでcronを実行するためのドッキング・コンテナを作成しました。cron -f。これは、コンテナを維持するために実行中のtailで他のトリックを避けるのに役立ちました。

      参考のために私のentrypoint.shファイルがあり、私のコンテナはdebian:jessieベースイメージです。

      printenv | grep -v "no_proxy" >> /etc/environment 
      
      cron -f 
      

      また、このトリックはdocker runコマンド、中に設定されている環境変数でさえ働いていました。

    +1

    printenv>/etc/environmentは、4日間で様々なオプションを試してみた後、私のために働いた唯一のものでした!ありがとう! – Deko

    +0

    "/ etc/environment"を使用してくれましたが、このファイルを読むことはcronの標準的な動作ではありません.pam cronモジュールをインストールしている場合のみ動作します。https://askubuntu.com/a/を参照してください。 700126 – llmora

    +0

    コメント記号 '#'をエスケープする可能性がないので、 '/ etc/environment'ファイルの使用制限に気をつけて、そこの変数の値には使用できません。 – AuHau

    0

    スクリプトを破る可能性の変な文字をエスケープし、推論によるMark's answerから、あなたのentrypoint.shに次の行を追加するには:

    env | sed -r "s/'/\\\'/gm" | sed -r "s/^([^=]+=)(.*)\$/\1'\2'/gm" \ > /etc/environment 
    

    この方法は、あなたがaffinity:container==My container's friendのような任意の変数を持っている場合、それはなりますaffinity:container='=My container\'s friendに変換されます。

    2

    私は自分の環境をエクスポートし、(それらのいずれかで呼ばれるかもしれないラッパースクリプトに直接CMDまたはENTRYPOINTを使用するか)の問題をエスケープを避けるためにdeclareを使用することをお勧めします:

    declare -p | grep -Ev 'BASHOPTS|BASH_VERSINFO|EUID|PPID|SHELLOPTS|UID' > /container.env

    をGrep -v読み取り専用変数を除外します。

    あなたは、後で簡単にこのようにこの環境をロードすることができます。

    SHELL=/bin/bash 
    BASH_ENV=/container.env 
    * * * * * root /test-cron.sh