Dockerコンテナ(Ubuntu 16.04 xenial)へのtd-agentの導入


(注意)当時の知識不足に伴いログドライバについての記述が欠落しています。

Dockerコンテナで課題となることの一つにログの収集があります。
ログの収集方法としては以下の3つの方法があります。

1. syslogの利用
2. td-agent/logstashなどのログ集約ソフトウェアの利用
3. ホストOSボリュームへのログ出力

今回は2のログ集約ソフトウェアを利用した場合について整理します。
なお、今回はtd-agentを対象とします。

# td-agentのインストール(失敗版)
公式ページのインストール手順を参照します。
http://docs.fluentd.org/articles/install-by-deb#step-1--install-from-apt-repository

```Bash:公式ページのインストール手順
curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh | sh
```

上記コマンドのみでインストールできるようです。
実際にホストOS側はこれだけでインストールできました。

## Dockerfileの準備
Ubuntu 16.04のコンテナにtd-agentをインストールするためのDockerfileを準備します。

```Text:Dockerfile(失敗版)
FROM ubuntu:xenial-20160706
MAINTAINER Ryoma Fujiwara<e238058r@hotmail.co.jp>
LABEL OBJECT="td-agent latest package install"

ENTRYPOINT ["/sbin/init"]
RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get -y install curl
RUN curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh | sh
```

docker buildをDockerfileの入っているディレクトリで実行します。

```Bash:dockerイメージのビルド
docker build -t ubuntu-16.04-td-agent:latest `pwd`
```

結果は **失敗。** 端的に述べると **sudoがないからです。** 

# td-agentのインストール(成功版)

## インストール失敗の原因の確認

インストール失敗の原因はsudoがインストールされていないからでした。
そこでsudoをインストールしても良いのですが、ここはあえて原因を探った上でsudoなしでのインストールを検討します。

まずはインストールスクリプトをチェックします。

```Bash:インストールスクリプトのチェック
curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh
echo "This script requires superuser access to install apt packages."
echo "You will be prompted for your password by sudo."

# clear any previous sudo permission
sudo -k

# run inside sudo
sudo sh <<SCRIPT
  curl https://packages.treasuredata.com/GPG-KEY-td-agent | apt-key add -

  # add treasure data repository to apt
  echo "deb http://packages.treasuredata.com/2/ubuntu/xenial/ xenial contrib" > /etc/apt/sources.list.d/treasure-data.list

  # update your sources
  apt-get update

  # install the toolbelt
  apt-get install -y --force-yes td-agent

SCRIPT
```

...みたところ原因は冒頭のsudo -kのようです。
Dockerコンテナでは基本的にrootでの操作がデフォルト
(それが良いか悪いかはさておき)なので、
このsudoは不要そうです。

## Dockerfile(成功版)の作成

それでは、先ほどのスクリプトからsudo -kを取り除いたものを導入しましょう。

```Text:Dockerfile(成功版)
FROM ubuntu:xenial-20160706
MAINTAINER Ryoma Fujiwara<e238058r@hotmail.co.jp>
LABEL OBJECT="td-agent latest package install"

ENTRYPOINT ["/sbin/init"]
RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get -y install curl
RUN curl https://packages.treasuredata.com/GPG-KEY-td-agent | apt-key add -
RUN echo "deb http://packages.treasuredata.com/2/ubuntu/xenial/ xenial contrib" > /etc/apt/sources.list.d/treasure-data.list
RUN apt-get -y update
RUN apt-get install -y --force-yes td-agent
```

それではこれをビルド。

```Bash:Dockerイメージのビルド
docker build -t ubuntu-16.04-td-agent:latest `pwd`

docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
ubuntu-16.04-td-agent   latest              46ecadc7c7cc        11 minutes ago      429.9 MB
```

一応ビルドできたみたい。


## td-agentの設定
### ホストOS側設定

一旦はホスト側で受けるので、
ホスト側の設定を実施します。

```Bash:ホストOSの設定
sudo mkdir /etc/td-agent/conf.d
sudo vim /etc/td-agent/conf.d/test.conf
```

```XML:/etc/td-agent/conf.d/test.conf内容
<source>
	type forward
	port 24224
	bind 0.0.0.0
</source>

<match test.*>
	type file
	path /tmp/test
	time_slice_format
	time_slice_wait 1m
	time_format %Y%m%dT%H%M%S%z
</match>
```

```XML:/etc/td-agent/td-agent.conf内容
include conf.d/*.conf
```

まあ、ひたすら送られてきたログを
/tmp/testに出力するだけの簡単なお仕事です。

```Bash:td-agentの起動
sudo systemctl restart td-agent
```

特に考えずにtd-agentを起動します。

### コンテナ側設定

```Bash:コンテナ起動
docker run -d --name td_agent001 --hostname td001 -v /home/ubuntu/conf/:/mnt/conf -t ubuntu-16.04-td-agent:latest
```

```Bash:コンテナ接続
docker exec -it td_agent001 /bin/bash
```

```Bash:/etc/td-agent/td-agent.conf内容
include conf.d/*.conf
```

```XML:/mnt/conf/test/confの内容
<source>
  type tail
  path /tmp/test.log
  pos_file /tmp/test.log.pos
  tag test.log
  format none
</source>

<match test.*>
  type forward
  <server>
    name docker-host
    host 172.17.0.1
    port 24224
  </server>
</match>
```

172.17.0.1はホストOS側のdocker0(Docker用のブリッジインタフェース?)を指定します。

```Bash:td-agent起動
service td-agent restart
```

黙ってtd-agentを起動する。

## 動作確認

### コンテナ側

```Bash:echoする
echo "test" >> /tmp/test.log
```

実際はスクリプト使って大量のログを出力させました。

### ホストOS側

```Bash:lsする(中間ファイルの生成確認)
ls /tmp
test..b53807e2589984d89
```

testログの中間ファイルが出力されているのでOK

# まとめ

コンテナからホストOS側にtd-agentを用いてログを出力することができました。