Edited at

Dockerコンテナ内のログをSplunkに入れてみた

More than 1 year has passed since last update.


はじめに

通常Dockerコンテナ内で稼働しているプロセスのログはコンテナの中にそのまま残ります。

結果、集中管理が難しくなるところですが、Splunkを使ってあらゆるコンテナのログを集約して管理できるようにします。

ということで、Dockerのコンテナ内に吐き出されるログをSplunkに流してみました。

コンテナ内のログを外に出してSplunkに送る方法はLogging Driverを使います。

https://docs.docker.com/engine/admin/logging/splunk/

また、Splunkでログを受け取る仕組みは、HTTP Event Collectorを使います。

http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector


設定方法

この2つを使ってログを送信する設定について記載します。

今回使用したバージョンは以下

Splunk: 6.5.3

Docker: 17.03.1


Splunkの設定

まずはSplunkでHTTP Event Collector(通称HEC)をセットアップします。

[設定] > データ入力 > HTTPイベントコレクタ

Screen Shot 2017-07-08 12.32.12 PM.png

Screen Shot 2017-07-08 12.41.17 PM.png

HEC設定画面右上の [グローバル設定] をクリック

Screen Shot 2017-07-08 12.42.44 PM_1.png

[全トークン] を「有効」にする

Screen Shot 2017-07-08 12.42.59 PM.png

続けて、 [新規トークン作成] をクリック

Screen Shot 2017-07-08 12.42.44 PM_2.png

名前を適当につける

Screen Shot 2017-07-08 12.48.47 PM.png

次の画面に進んで、インデックスを設定

Screen Shot 2017-07-08 12.50.49 PM.png

今回はDockerのnginxイメージから作ったコンテナを利用するので、webインデックスを許可します。

一応mainインデックスも許可しておきます。

デフォルトはmainインデックスにしていますが、webインデックスに入れるよう後のステップでDocker側で設定します。

次の画面に進んで、設定内容を確認して [実行] します。

Screen Shot 2017-07-08 12.54.55 PM.png

トークンが発行されるので、それをメモ帳等に保存しておきましょう。

Screen Shot 2017-07-08 12.55.55 PM_mosaic.png

これでSplunkの設定は終了。


Dockerの設定

続いてDockerの設定です。


Splunk証明書の配置

SplunkにHTTPSでデータを投げるので、証明書の認証が必要になります。

Splunkに自己署名の認証局(CN=SplunkCommonCA) $SPLUNK_HOME/etc/auth/cacert.pem をコピーして、Dockerが入っているサーバーの任意の場所に配置します。

$ openssl x509 -in cacert.pem -subject -noout

subject= /C=US/ST=CA/L=San Francisco/O=Splunk/CN=SplunkCommonCA/emailAddress=support@splunk.com

ちなみに、Splunkサーバー証明書は CN=SplunkServerDefaultCert です。

これは後でコンテナ起動時に使用します。

$ openssl x509 -in server.pem -subject -noout

subject= /CN=SplunkServerDefaultCert/O=SplunkUser


コンテナ起動

あとはコンテナ起動時のオプション指定だけでSplunkにログが飛んでいきます。

docker run --name splunk-nginx -p 80:80 -d \

--log-driver=splunk \
--log-opt splunk-token=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX \
--log-opt splunk-url=https://splunk.example.com:8088 \
--log-opt splunk-capath=/etc/docker/cacert.pem \
--log-opt splunk-caname=SplunkServerDefaultCert \
--log-opt splunk-index="web" \
--log-opt splunk-sourcetype=access_combined \
--log-opt splunk-format=raw \
nginx

--log-driver=splunk でSplunk用Logging Driverを指定しています。

その他の設定を --log-opt で指定しています。

splunk-token --> HECのトークン

splunk-url --> SplunkサーバーのURL(ポートはHEC設定に従う)

splunk-capath --> Splunkからとってきたcacert.pemのパス

splunk-caname --> サーバー証明書のCN(なぜ"ca"name?)

splunk-index --> Splunkのインデックス(HEC設定で指定したwebインデックスを使用)

splunk-sourcetype --> Splunkのソースタイプ(nginxなのでaccess_combinedを使用)

splunk-format --> ログのフォーマット


(補足)ログのフォーマットについて

splunk-format には json inline raw の3種類が指定できます。

デフォルトはinlineですが、その場合、Splunkではこのように見えます。

Screen Shot 2017-07-08 1.22.23 PM_mosaic.png

JSON形式となってlineにログが記録されています。

ただ、この場合フィールドが自動抽出されずに後々ダッシュボード作成等でメンドいので、あえてsplunk-format=rawを指定します。

ちなみに splunk-format=json を選択してもnginxの場合は inline と変わりません。

json はJSON形式のログをちゃんとJSONとしてパースしてくれるだけです。


Splunkで検索してみる

Screen Shot 2017-07-08 1.15.07 PM_mosaic.png

ん?

Screen Shot 2017-07-08 1.33.49 PM_mosaic.png

あれ?

ログ先頭にコンテナIDが入ってしまてますね。

Screen Shot 2017-07-08 1.35.42 PM_mosaic.png

そのせいで、せっかく access_combined を指定したのに、フィールドが自動抽出されていないようです。


再びSplunk設定

強引にコンテナIDをソースに上書きして、ログから除去します。

Splunkの props.conftransforms.conf を使います。


props.conf

[source::http:docker_logging_driver]

TRANSFORMS-1_docker_source = replace_docker_source
TRANSFORMS-2_docker_raw = drop_docker_id


transforms.conf

[replace_docker_source]

REGEX = ^([0-9a-f]{12})\s
DEST_KEY = MetaData:Source
FORMAT = source::$1

[drop_docker_id]
REGEX = ^([0-9a-f]{12})\s([\s\S]+$)
DEST_KEY = _raw
FORMAT = $2


この設定でソースをコンテナIDに上書きしつつ、ログから先頭のコンテナIDを消し去っています。

(参考)

props.confマニュアル

transforms.confマニュアル


もっかいSplunkで検索

Screen Shot 2017-07-08 1.47.36 PM_mosaic.png

いけたかな?

Screen Shot 2017-07-08 1.48.19 PM_mosaic.png

うん、いけてますね。

フィールド抽出できてます。


最後に

けっこう簡単な設定でコンテナ内のログをSplunkに入れることができますね。

他にも docker stats でコンテナの統計情報をとるスクリプト作ってSplunkに入れたり、 /var/log/docker をSplunkからモニターして入れたりしても良さそうです。


おまけ

Docker設定していて気づいたことを少々。


daemon.jsonではSplunk Logging Driverの設定できないっぽい

↓のように作ってみて --log-driver--log-opt の指定なしでコンテナ起動してみたのですが、ログはSplunkに入ってきませんでした。


daemon.json

{

"log-driver": "splunk",
"log-opts": {
"splunk-token": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"splunk-url": "https://splunk.example.com:8088",
"splunk-capath": "/etc/docker/cacert.pem",
"splunk-caname": "SplunkServerDefaultCert",
}
}

正確には --log-opts で諸々のSplunk設定することがサポートしていないらしく、こんなログが出てきました。


/var/log/docker

time="2017-06-29T17:09:59.886826680Z" level=error msg="the following directives don't match any configuration option: splunk-token, splunk-url, splunk-capath, splunk-caname"



コンテナIDについて

Splunkで props.conftransforms.conf を設定して強引にコンテナIDをソースに指定していますが、そもそも↓みたいなオプション指定できれば楽なのになぁ。

docker run --name splunk-nginx -p 80:80 -d \

--log-driver=splunk \
...
--log-opt splunk-source="{{.ID}}" \
nginx

どうやら {{.ID}} とか {{.Name}}tag でのみ利用可能のようです。

https://docs.docker.com/engine/admin/logging/log_tags/


Splunk証明書の認証を無効化

コンテナ起動時のオプションで↓を指定すると証明書の認証を無効にするようです。

--log-opt splunk-insecureskipverify=true

これを使えば、Splunkから証明書をとってきてオプションで指定して、、、というメンドくさいことが省略できますね。

ただし、中間者攻撃のリスクは出てくるので正直オススメはできないですね。

(追記 2017/08/23)

証明書の無効化オプションを --log-opt splunk-verify-connection=false と記載しましたが、正しくは --log-opt splunk-insecureskipverify=true でした。修正しました。