2015-10-30 23 views
16

複数のサーバーに散在している一連のドッキングされたアプリケーションがあり、ELKでプロダクションレベルの集中​​型ログをセットアップしようとしています。私はELKの部分自体は大丈夫ですが、私はログをログに転送する方法についてちょっと混乱しています。 ロードバランサ機能のためにFilebeatを使用しようとしています。 私は、Filebeat(または何か他のもの)をすべてのドッカーに詰め込むことを避け、それを分離したり、ドッキングしたりしないようにしたいと思います。FilebeatとLogstashでロギングするDockerアプリケーション

どうすればいいですか?

私は以下のことを試しています。私のドッカーはstdoutにログオンします。ドッキングできないFilebeatをstdinから読み込むように設定しています。

ドッカーログ-f mycontainer | ./filebeat -e -c filebeat.yml

これは最初からうまくいくようです。最初のログは私のlogstashに転送されます。私が推測するキャッシュされたもの。しかし、いつの間にか止まって同じイベントを送信し続けます

これは単なるバグですか、間違った方向に向いていますか?どのようなソリューションをセットアップしましたか?

+0

私は古いlogstash-forwarderで同じことを試みました: ドッカーログ-f mycontainer | ./logstash-forwarder_linux_amd64 -config forwarder.conf それは動作します。私はFilebeatの不具合を疑う。 唯一の問題は、ロードバランシングのないログ・スタッシュへのランダムな接続が残っていることです。 – Gianluca

+0

使用しているファイルビートのバージョンは?これは潜在的なバグのようです。問題をより深く理解するために、[ここ](https://github.com/elastic/filebeat/issues)の問題を自由に開いてください。参考:ドッカーの実装についてのいくつかの追加の議論は、ここにあります:https://github.com/elastic/libbeat/issues/37 – ruflin

答えて

5

Dockerでは、logDriverを使用中に指定することができます。この答えは、Filebeatまたは負荷分散については気にしません。

docker run -t -d --log-driver=syslog --log-opt syslog-address=tcp://127.0.0.1:5000 ubuntu /bin/bash -c 'while true; do echo "Hello $(date)"; sleep 1; done' 
+0

私はlogDriverを見ましたが、ハイアベイラビリティはどうですか?リクエストをログスタッシュクラスタにルーティングするためにTCPロードバランサが必要ですか? – Gianluca

+0

あなたのシステムの規模についてはわかりません。 〜200ログプロデューサ(私の答えのコマンド)を使用して、私は何の問題に気付かなかった。しかし、高可用性やロードバランシング/クラスタリングについては考えていませんでした。 – michaelbahr

+0

私はログの量が心配ではありません、それはlogstashの可用性です。優れたフォールトトレランスを確保するために、少なくとも2つまたは3つが必要です。次に、一方から他方に切り替えるためのメカニズムが必要です。 – Gianluca

16

ここで転送する一つの方法だ:ポート5000 で次のコマンドをリスニングLogstash(ELK)インスタンスは常にLogstashへのsyslogを介してメッセージを送信し、私はログを転送するためのsyslogを使用したプレゼンテーションで

  1. にはElasticsearcにGELF出力から読み取りgelf input pluginとLogstashコンテナを起動:ELKスタックにdocker logsは(GELFログドライバのドッカー> = 1.8が必要) Hホスト(ES_HOST:ポート):

    docker run --rm -p 12201:12201/udp logstash \ 
        logstash -e 'input { gelf { } } output { elasticsearch { hosts => ["ES_HOST:PORT"] } }' 
    
  2. 今ドッカーコンテナを起動しgelf Docker logging driverを使用します。ここではダム例を示します。

    docker run --log-driver=gelf --log-opt gelf-address=udp://localhost:12201 busybox \ 
        /bin/sh -c 'while true; do echo "Hello $(date)"; sleep 1; done' 
    
  3. ロードアップKibanaとdocker logsに上陸しただろう事が表示されるようになりました。 (:Christophe Labouisse帽子・チップ):gelf source codeはいくつかの便利なフィールドが自動的に生成されていることを示して_container_id_container_name_image_id_image_name_command_tag_created

あなたは(ドッカ-コン> = 1.5を使用してください)ドッカ - コンを使用してlogstashコンテナを起動した後docker-compose.ymlで適切な設定を追加する場合:

filebeatあなただけのことができます使用
log_driver: "gelf" 
log_opt: 
    gelf-address: "udp://localhost:12201" 
+3

gelfの問題は、udpを使用しているためにログイベントをサイレントにドロップする可能性があると思います。 – urso

+3

良い点、@ルーソー。 'syslog'ロギングドライバは、TCPを介してログを配信するのと同様の方法で使用できます(例:https://github.com/edefaria/docker-logstash)。 [Graylog Extended Format(GELF)docs](https://www.graylog.org/resources/gelf/)は、TCPを使用した潜在的な問題について、UDPとは対照的に、黙ってロギングイベントをドロップしています。 – Pete

7

あなたが説明したようにパイプdocker logs出力。あなたが見ている動作は間違いなくバグのように聞こえるかもしれませんが、改行記号が見つかるまで部分的な行を読んで部分的な行読み設定にすることもできます。

ログシュートがない場合に配管で見える問題があります。 filebeatがイベントを送信できない場合、内部的にイベントをバッファリングし、ある時点でstdinからの読み取りを停止します。ドッカーが標準出力から反応しなくなるのをどのように/保護するかは考えられません。 docker-composeを使用している場合、配管に関するもう1つの問題は、filebeat + dockerの再起動動作です。ドッカーはデフォルトで画像と画像の状態を再利用します。そのため、再起動すると、元のログファイルはまだローテーションされていないため、すべての古いログが再度配信されます。

パイピングの代わりに、ドッカーによって書かれたログファイルをホストシステムに読み込もうとすることができます。デフォルトのドッカーログドライバはjson log driverです。 jsonログドライバを設定して、ログのローテーション+古いファイルをいくつか保持する(ディスク上でバッファリングする)ことができます。 max-sizeとmax-fileオプションを参照してください。 jsonドライバは、すべての行を記録するための1行の 'json'データを記録します。ドッカーホストシステムでは、ログファイルは/var/lib/docker/containers/container_id/container_id-json.logに書き込まれます。これらのファイルはfilebeatによってlogstashに転送されます。 logstashまたはネットワークが使用不能になったり、ファイルの再起動が行われた場合は、ログが残っている場所(指定されたファイルはログのローテーションによって削除されていない)に転送されます。イベントは失われません。ログスタッシュでは、json_linesコーデックまたはフィルタを使用してjson行とgrokフィルタを解析し、ログからさらに情報を得ることができます。

dockerに新しいログドライバを追加するために、libbeat(ログファイルの配送にfilebeatが使用する)を使用することについては、some discussionがありました。おそらく、ドッカーのログapiを使用して、将来、dockerbeat経由でログを収集することは可能です(ただし、ログapiを利用する計画はありません)。

syslogの使用もオプションです。おそらく、ドッカーホストのロードバランシングログイベントでsyslogリレーを取得することができます。または、syslogにログファイルを書き込ませ、filebeatを使用してそれらを転送させることもできます。私はrsyslogが少なくともいくつかのフェールオーバーモードを持っていると思います。アクティブなlogstashインスタンスが使用できなくなった場合に備えて、logstash syslog input pluginとrsyslogを使用して、ログをフェイルオーバーサポートとともにlogstashに転送できます。

+0

Re json-file、https://github.com/moby/moby/issues/17763は、ドッカーのjsonファイルが内部データとみなされ、他のプロセスによって消費されることを意味しないことを示します。 –

7

Docker APIを使用して独自のドッカーイメージを作成し、マシン上で実行されているコンテナのログを収集し、FilebeatのおかげでLogstashに発送しました。ホスト上に何かをインストールしたり設定したりする必要はありません。

あなたのニーズに合っているかどうかチェックしてください:https://hub.docker.com/r/bargenson/filebeat/

コードはここにあります:https://github.com/bargenson/docker-filebeat

0

ただ、これを実行する必要が他人を助けるために、あなたは、単にログを出荷するFilebeatを使用することができます。 @ brice-argensonでコンテナを使用しますが、SSLサポートが必要なため、ローカルにインストールされたFilebeatインスタンスを使用しました。

- input_type: log 
    paths: 
    - /var/lib/docker/containers/<guid>/*.log 
    document_type: docker_log 
    fields: 
    dockercontainer: container_name 

それは、彼らが更新に変更する可能性があるので、あなたがGUIDを知っておく必要があるビットを吸う:

filebeatからプロスペクターは、(それ以上の容器の繰り返し)です。

logstashサーバーで

、セットアップlogstashための通常のfilebeat入力ソース、およびこのように、フィルタを使用します。これは、ドッカーログからJSONを解析し、報告されたものにタイムスタンプを設定します

filter { 
    if [type] == "docker_log" { 
    json { 
     source => "message" 
     add_field => [ "received_at", "%{@timestamp}" ] 
     add_field => [ "received_from", "%{host}" ] 
    } 
    mutate { 
     rename => { "log" => "message" } 
    } 
    date { 
     match => [ "time", "ISO8601" ] 
    } 
    } 
} 

ドッカーによって。あなたはnginxのドッカーイメージからログを読んでいるなら、あなたにもこのフィルタを追加することができます

filter { 
    if [fields][dockercontainer] == "nginx" { 
    grok { 
     match => { "message" => "(?m)%{IPORHOST:targethost} %{COMBINEDAPACHELOG}" } 
    } 
    mutate { 
     convert => { "[bytes]" => "integer" } 
     convert => { "[response]" => "integer" } 
    } 
    mutate { 
     rename => { "bytes" => "http_streamlen" } 
     rename => { "response" => "http_statuscode" } 
    } 
    } 
} 

変換/リネームはオプションですが、それはキャストしないCOMBINEDAPACHELOG式の見落としを修正これらの値は整数になり、木場の集計に使用できなくなります。

+0

ありがとう! GUIDについてのヒントについては、私は同意します。しかし、おそらくこのような設定は手動で行うのではなく、むしろAnsibleのようなものを使用したいと思うでしょう。次に、 "docker ps | grep container_name | awk '(print $ 1)'"と入力し、結果をconfigにテンプレート化してfilebeatを再起動します。 –

+0

ドキュメントによれば、あなたのprospectors.pathsでこのようなパターンを使用できるはずです: '/ var/lib/docker/containers/*/* .log' – erewok

0

私は何erewokコメントして上に書いた検証:

ドキュメントによると、あなたはprospectors.pathsにこの のようなパターンを使用することができるはずです:の/ var/libに/ドッキングウィンドウ/コンテナ/*/*.log - filebeatの起動時に最初に「*」のように表さドッキングウィンドウコンテナのGUIDは、正しく解決されている21時03

でerewok 4月18日。私はコンテナが追加されるとどうなるのか分かりません。

関連する問題