はじめに
通常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イベントコレクタ
今回はDockerのnginxイメージから作ったコンテナを利用するので、web
インデックスを許可します。
一応main
インデックスも許可しておきます。
デフォルトはmain
インデックスにしていますが、web
インデックスに入れるよう後のステップでDocker側で設定します。
トークンが発行されるので、それをメモ帳等に保存しておきましょう。
これで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ではこのように見えます。
JSON形式となってline
にログが記録されています。
ただ、この場合フィールドが自動抽出されずに後々ダッシュボード作成等でメンドいので、あえてsplunk-format=raw
を指定します。
ちなみに splunk-format=json
を選択してもnginxの場合は inline
と変わりません。
json
はJSON形式のログをちゃんとJSONとしてパースしてくれるだけです。
Splunkで検索してみる
ん?
あれ?
ログ先頭にコンテナIDが入ってしまてますね。
そのせいで、せっかく access_combined
を指定したのに、フィールドが自動抽出されていないようです。
再びSplunk設定
強引にコンテナIDをソースに上書きして、ログから除去します。
Splunkの props.conf
と transforms.conf
を使います。
[source::http:docker_logging_driver]
TRANSFORMS-1_docker_source = replace_docker_source
TRANSFORMS-2_docker_raw = drop_docker_id
[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で検索
いけたかな?
うん、いけてますね。
フィールド抽出できてます。
最後に
けっこう簡単な設定でコンテナ内のログをSplunkに入れることができますね。
他にも docker stats
でコンテナの統計情報をとるスクリプト作ってSplunkに入れたり、 /var/log/docker
をSplunkからモニターして入れたりしても良さそうです。
おまけ
Docker設定していて気づいたことを少々。
daemon.jsonではSplunk Logging Driverの設定できないっぽい
↓のように作ってみて --log-driver
や --log-opt
の指定なしでコンテナ起動してみたのですが、ログはSplunkに入ってきませんでした。
{
"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設定することがサポートしていないらしく、こんなログが出てきました。
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.conf
と transforms.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
でした。修正しました。