Docker 1.6がリリースされたのでLogging driversを試してみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Docker 1.6がリリースされました!

様々な新機能が取り入れられています。Changelogを引用すると...

1.6.0 (2015-04-07)

Builder

  • Building images from an image ID
  • build containers with resource constraints, ie docker build --cpu-shares=100 --memory=1024m...
  • commit --change to apply specified Dockerfile instructions while committing the image
  • import --change to apply specified Dockerfile instructions while importing the image
  • basic build cancellation

Client

  • Windows Support

Runtime

  • Container and image Labels
  • --cgroup-parent for specifying a parent cgroup to place container cgroup within
  • Logging drivers, json-file, syslog, or none
  • Pulling images by ID
  • --ulimit to set the ulimit on a container
  • --default-ulimit option on the daemon which applies to all created containers (and overwritten by --ulimit on run)

で、僕が一番気になったのはLogging driversです。これまでDockerコンテナのログはJSON形式で出力されていましたが、今回SyslogとNoneという二つのログ出力オプションが追加されました。なので早速試してみました!

やってみた

試した環境はCentOS7(CentOS Linux release 7.1.1503) on EC2です。

Docker 1.6のインストール

このCentOS7環境では、既にyumでDockerがインストールされています。

$ docker --version
Docker version 1.5.0-dev, build fc0329b/1.5.0

最新のDockerバイナリをダウンロードして入れ替えます。

$ sudo systemctl stop docker
$ cd /usr/bin
$ mv docker docker.org
$ sudo wget https://get.docker.io/builds/Linux/x86_64/docker-latest -O docker
$ sudo chmod 755 docker
$ sudo systemctl start docker

この通り、Docker 1.6になりました。

$ docker --version
Docker version 1.6.0, build 4749651

json-fileでログ出力する

まずはこれまでのDockerでのログ出力形式であり、かつLogging driversのデフォルトとなる、JSON形式でのログ出力を確認します。

以下のように、busyboxでDockerコンテナを立ち上げます。

$ CID=$(sudo docker run -d busybox /bin/sh -c "while true; do echo hello; sleep 2; done")
$ echo $CID
2b40c88c24f7ca6fd6c099c8a2f0a19c567bdb2ad0c44ffbdc9531cae1e02f85

$ sudo docker ps -a -n 1 --no-trunc
CONTAINER ID                                                       IMAGE               COMMAND                                                   CREATED             STATUS              PORTS               NAMES
2b40c88c24f7ca6fd6c099c8a2f0a19c567bdb2ad0c44ffbdc9531cae1e02f85   busybox:latest      "/bin/sh -c 'while true; do echo hello; sleep 2; done'"   16 seconds ago      Up 16 seconds                           hungry_pare

docker logsを実行すると、Dockerコンテナのログが出力されます。

$ sudo docker logs $CID
hello
hello
hello

実際のDockerコンテナのログファイルは、以下のようにJSON形式で出力されています。

$ sudo cat /var/lib/docker/containers/$CID/$CID-json.log
{"log":"hello\n","stream":"stdout","time":"2015-04-17T05:51:24.396093029Z"}
{"log":"hello\n","stream":"stdout","time":"2015-04-17T05:51:26.396877724Z"}
{"log":"hello\n","stream":"stdout","time":"2015-04-17T05:51:28.397564592Z"}

Syslogにログ出力する

次にSyslog出力を試してみます。先ほどと同じようにbusyboxでDockerコンテナを立ち上げますが、--log-driver=syslogというオプションを付与します。

$ CID=$(sudo docker run --log-driver=syslog -d busybox /bin/sh -c "while true; do echo hello; sleep 2; done")
$ echo $CID
85e7f6049e9a91977bfb8eeea45853618aae1d7ed821be792f6136652737724e

$ sudo docker ps -a -n 1 --no-trunc
CONTAINER ID                                                       IMAGE               COMMAND                                                   CREATED             STATUS              PORTS               NAMES
85e7f6049e9a91977bfb8eeea45853618aae1d7ed821be792f6136652737724e   busybox:latest      "/bin/sh -c 'while true; do echo hello; sleep 2; done'"   17 seconds ago      Up 17 seconds                           stupefied_babbage

docker logsを実行すると...エラーになります。docker logsコマンドはjson-file形式のみをサポートしています。

$ sudo docker logs $CID
FATA[0000] "logs" command is supported only for "json-file" logging driver

なぜdocker logsコマンドでログが出力されないかというと、以下のようにDockerコンテナとしてのログが存在しないからです。

$ sudo ls /var/lib/docker/containers/$CID/
config.json  hostconfig.json  hostname	hosts  resolv.conf  resolv.conf.hash

Syslog出力の場合は、DockerホストのSyslogにログが出力されます。かっこいい!

$ sudo tail -3 /var/log/messages
Apr 17 05:54:50 ip-172-31-15-187 docker/85e7f6049e9a[21079]: hello
Apr 17 05:54:52 ip-172-31-15-187 docker/85e7f6049e9a[21079]: hello
Apr 17 05:54:54 ip-172-31-15-187 docker/85e7f6049e9a[21079]: hello

None=ログ出力しない

次にNoneオプションを試してみます。Dockerコンテナを立ち上げるときに--log-driver=noneというオプションを付与します。

$ CID=$(sudo docker run --log-driver=none -d busybox /bin/sh -c "while true; do echo hello; sleep 2; done")
$ echo $CID
41ed5f93d12537af8a3a75b4d1b15568adc7252ce45cc306745b37aec4c5c2f2

$ sudo docker ps -a -n 1 --no-trunc
CONTAINER ID                                                       IMAGE               COMMAND                                                   CREATED             STATUS              PORTS               NAMES
41ed5f93d12537af8a3a75b4d1b15568adc7252ce45cc306745b37aec4c5c2f2   busybox:latest      "/bin/sh -c 'while true; do echo hello; sleep 2; done'"   32 seconds ago      Up 31 seconds                           sharp_torvalds

docker logsは当然エラーになります。ログが出力されていませんので。

$ sudo docker logs $CID
FATA[0000] "logs" command is supported only for "json-file" logging driver

$ sudo ls /var/lib/docker/containers/$CID/
config.json  hostconfig.json  hostname	hosts  resolv.conf  resolv.conf.hash

ちょっとお試しでDockerコンテナを立ち上げたいだけなのに、ログがガンガン出力されてしまうと、 Dockerホストのストレージ領域がすぐに圧迫されてしまいますので、Noneオプションはとても便利ですね!

さいごに

個人的にはSyslog出力が素敵だなと思いました。Dockerホスト側のSyslogをZabbixあたりで監視するだけで、コンテナの異常検知ができます。かっこいいですね!