web-dev-qa-db-ja.com

dockerを備えたマイクロサービスアーキテクチャでログを出荷する方法は?

Herokuは Twelve-Factor App manifest でログを単純なイベントストリームとして記述します。

ログは、実行中のすべてのプロセスとバッキングサービスの出力ストリームから収集された、時間順に並べられた集約イベントのストリームです。生の形式のログは、通常、1行に1つのイベントが含まれるテキスト形式です(例外からのバックトレースは複数行に及ぶ場合があります)。ログには開始または終了の固定はありませんが、アプリが動作している限り継続的に流れます。

さらに、アプリは単にstdoutにログを書き込み、タスクを「環境」に任せる必要があります。

12要素のアプリは、出力ストリームのルーティングやストレージに関係することはありません。ログファイルへの書き込みや管理を試みるべきではありません。代わりに、実行中の各プロセスは、バッファリングされていないイベントストリームをstdoutに書き込みます。ローカルでの開発中、開発者はこのストリームを端末のフォアグラウンドで表示して、アプリの動作を観察します。

ステージングまたは本番デプロイでは、各プロセスのストリームが実行環境によってキャプチャされ、アプリからの他のすべてのストリームと照合され、1つ以上の最終的な宛先にルーティングされて、表示および長期的なアーカイブが行われます。これらのアーカイブ先は、アプリからは見えず、構成もできません。代わりに、実行環境によって完全に管理されます。この目的のために、オープンソースのログルーター(LogplexやFluentなど)を使用できます。

では、信頼性、効率、使いやすさの観点から、Docker環境でこれを実現するための最良の方法は何でしょうか。次の質問が頭に浮かぶと思います。

  • Docker独自のログ機能(docker logs)?
  • Dockerを切り離さずに実行し、その出力をロギングストリームと見なしても安全ですか?
  • stdoutを直接ファイル(ディスク領域)にリダイレクトできますか?
  • ファイルを使用する場合は、Dockerイメージまたはバインドされたボリューム(docker run --volume=[])?
  • ログローテーションは必要ですか?
  • Stdoutを直接logshipper(およびどのlogshipper)にリダイレクトしても安全ですか?
  • 名前付きパイプ(別名FIFO)はオプションですか?
  • (さらに質問を?)
29
sfussenegger

Docker 1.6 導入ロギングドライバー の概念により、ログ出力をより詳細に制御できます。 --log-driverフラグは、コンテナーで実行されているプロセスからのstdoutstderrをどこに送信するかを構成します。 ロギングドライバの設定 も参照してください。

いくつかのドライバーが利用可能です。 json-fileを除くこれらすべては、コンテナログを収集するためのdocker logsの使用を無効にすることに注意してください。

  • none-コンテナーログを無効にします。
  • json-file-以前と同じように動作し、/var/lib/docker/containers/<containerid>/<containerid>-json.logでjson形式のstdoutを使用できます
  • syslog-メッセージをsyslogに書き込みます。 --log-optも受け入れて、ログメッセージをTCP、UDP、またはUnixドメインソケット経由で指定されたsyslogに送信します。 docker logsも無効にします
  • journald-systemdジャーナルに書き込みます。
  • * gelf-Graylog拡張ログ形式(GELF)。ログメッセージをGraylogやLogstashなどのGELFエンドポイントに書き込みます。
  • * fluentd- fluentd にコンテナーログを送信します。 fluentdのアドレスをカスタマイズし、ログメッセージでタグを送信するためのいくつかのオプションを受け入れます。
  • ** awslogs-ログメッセージをAWS CloudWatch Logsに書き込みます

*Docker 1.8の新機能

**Docker 1.9の新機能

例えば:

docker run --log-driver=syslog --log-opt syslog-address=tcp://10.0.0.10:1514 ...

これは、ログメッセージをstdoutstderrに書き込むソフトウェアのDocker推奨ソリューションです。ただし、一部のソフトウェアはstdout/stderrにログメッセージを書き込みません。代わりに、ログファイルやsyslogなどに書き込みます。これらの場合、以下の元の回答の詳細の一部が引き続き適用されます。要点をまとめると:

アプリがローカルログファイルに書き込む場合は、ホストからボリュームをマウントします(または データ専用コンテナー を使用してコンテナーに移動し、ログメッセージをその場所に書き込みます)。

アプリがsyslogに書き込む場合、いくつかのオプションがあります。

  • /dev/logを使用してコンテナにホストのsyslogソケット(-v /dev/log:/dev/log)をマウントすることにより、ホストのsyslogに送信します。
  • アプリが構成でsyslogエンドポイントを受け入れる場合は、DockerブリッジネットワークでTCPおよび/またはUDPをリッスンするようにホストのsyslogデーモンを構成し、そのエンドポイントを使用します。または、リモートに送信するだけです。 syslogホスト。
  • コンテナーでsyslogデーモンを実行し、Dockerリンクを使用して、実行中の他のコンテナーからそれにアクセスします。
  • logspout を使用して、コンテナーログをUDP経由でリモートSyslogに自動的にルーティングします

コンテナー内のログは、ホストOSの場合と同じようにローテーションする必要があることを忘れないでください。


Docker 1.6より前の元の回答

Docker自体のログ機能(dockerログ)に依存しても安全ですか?

docker logsは、新しいログだけでなく、毎回ストリーム全体を出力するため、適切ではありません。 docker logs --followtail -fに似た機能を提供しますが、その後は常にdocker CLIコマンドが実行されます。したがって、docker logsを実行するのは安全ですが、最適ではありません。

Dockerを切り離さずに実行し、その出力をロギングストリームと見なしても安全ですか?

デーモン化せずにsystemdでコンテナーを開始できるため、systemdジャーナル内のすべてのstdoutをキャプチャできます。これは、ホストで管理できます。

Stdoutを直接ファイル(ディスク領域)にリダイレクトできますか?

もちろん、これをdocker run ... > logfileで行うこともできますが、自動化と管理が不安定で難しくなります。

ファイルを使用する場合、それはDockerイメージまたはバインドされたボリューム内にある必要がありますか(Docker run --volume = [])?

コンテナー内に書き込む場合、ログファイルを管理するためにコンテナー内でlogrotateまたは何かを実行する必要があります。ホストからボリュームをマウントし、ホストのログローテーションデーモンを使用してボリュームを制御することをお勧めします。

ログローテーションは必要ですか?

もちろん、アプリがログを書き込む場合は、ネイティブOS環境と同じようにログをローテーションする必要があります。ただし、ログファイルの場所は予測できないため、コンテナー内に書き込む場合は困難です。ホストでローテーションする場合、ログファイルは、たとえばデバイスマッパーをストレージドライバー/var/lib/docker/devicemapper/mnt/<containerid>/rootfs/...として使用します。 logrotateがそのパスの下にあるログを見つけるには、醜いラッパーが必要になります。

Stdoutを直接logshipper(およびどのlogshipper)にリダイレクトしても安全ですか?

Syslogを使用し、ログコレクターにsyslogを処理させることをお勧めします。

名前付きパイプ(別名FIFO)はオプションですか?

名前付きパイプは、パイプの読み取り側が終了するとライター(コンテナー)が壊れたパイプになるため、理想的ではありません。そのイベントがアプリで処理された場合でも、再度リーダーが存在するまでブロックされます。さらに、docker logsを回避します。

これも参照してください dockerを使用したfluentdへの投稿

実行中のコンテナーからログを収集し、必要に応じてルーティングするJeff Lindsayのツール logspout を参照してください。

最後に、コンテナからのstdoutが/var/lib/docker/containers/<containerid>/<containerid>-json.logのホスト上のファイルにログを記録することに注意してください。

28
Ben Whaley