はじめに
CoreOS 上で dd-agent を動かそうとした場合、 yum や apt といった通常のパッケージ管理ツールを使って CoreOS マシンにインストールすることはできない。アプリケーションや各種サービスを全てコンテナで扱う、いわゆる "docker way" で行う必要がある(そうした方が良いとも思う)。なので、dd-agent もそれ専用のコンテナを起動し、 --privileged
オプションを付けホスト情報へアクセス可能にしてあげることで CoreOS をモニタリングする。
CoreOS 上に Datadog をインストールする
コマンドラインからインストールする
CoreOS クラスタ全体で Datadog の API キーを共有するため、etcd にセットしておく
$ etcdctl set /ddapikey c0re0s070120131499294110c0re0sdd
c0re0s070120131499294110c0re0sdd
dd-agent コンテナを run
$ docker run \
-d \
--privileged \
--name dd-agent \
-h `hostname` \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /proc/mounts:/host/proc/mounts:ro \
-v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \
-e API_KEY=`etcdctl get /ddapikey` \
datadog/docker-dd-agent
しばらくすると、Datadog の方で CoreOS マシンが認識され、
しばらくすると、各種メトリクスを見る事ができるようになる
systemd からインストールする
CoreOS クラスタ全体で Datadog の API キーを共有するため、etcd にセットしておく(
$ etcdctl set /ddapikey c0re0s070120131499294110c0re0sdd
c0re0s070120131499294110c0re0sdd
/etc/systemd/system/dd-agent.service
として dd-agent Unit を作成。
$ sudo vi /etc/systemd/system/dd-agent.service
[Unit]
Description=Datadog Agent
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill dd-agent
ExecStartPre=-/usr/bin/docker rm dd-agent
ExecStartPre=/usr/bin/docker pull datadog/docker-dd-agent
ExecStartPre=/bin/sh -c "export DATADOG_API_KEY=$(/usr/bin/etcdctl get /ddapikey)"
ExecStart=/usr/bin/docker run --privileged --name dd-agent -h %H -v /var/run/docker.sock:/var/run/docker.sock -v /proc/mounts:/host/proc/mounts:ro -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro -e API_KEY=$DATADOG_API_KEY datadog/docker-dd-agent
[Install]
WantedBy=multi-user.target
ポイントとしては ExecStart
は -e API_KEY=$(/usr/bin/etcdctl get /ddapikey)
のようにコマンドを埋め込めないので、一度 etcd から値を環境変数に入れ、それを使って docker run
している。さらに環境変数に入れる ExecStart
でも同じく DATADOG_API_KEY=$(/usr/bin/etcdctl get /ddapikey)
のようには書けないので、
ExecStartPre=/bin/sh -c "export DATADOG_API_KEY=$(/usr/bin/etcdctl get /ddapikey)"
としている(ただ、ExecStart
が $(command)
のできないようにしてるのには意図があるだろうからこの方法は良くないのかもしれない)
Unit を enable にして
$ sudo systemctl enable /etc/systemd/system/dd-agent.service
Created symlink from /etc/systemd/system/multi-user.target.wants/dd-agent.service to /etc/systemd/system/dd-agent.service.
dd-agent 起動
$ sudo systemctl start dd-agent.service
起動を確認
$ docker ps | grep dd-agent
5289f15b79ae datadog/docker-dd-agent:latest /usr/local/bin/run-d 10 minutes ago Up 10 minutes 8125/udp dd-agent
$ systemctl status dd-agent.service
● dd-agent.service - Datadog Agent
Loaded: loaded (/etc/systemd/system/dd-agent.service; enabled)
Active: inactive (dead) since Thu 2014-09-04 18:06:30 JST; 11min ago
Process: 2315 ExecStart=/usr/bin/docker run -d --privileged --name dd-agent -h %H -v /var/run/docker.sock:/var/run/docker.sock -v /proc/mounts:/host/proc/mounts:ro -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro -e API_KEY=$DATADOG_API_KEY datadog/docker-dd-agent (code=exited, status=0/SUCCESS)
Process: 2305 ExecStartPre=/bin/sh -c export DATADOG_API_KEY=$(/usr/bin/etcdctl get /ddapikey) (code=exited, status=0/SUCCESS)
Process: 2294 ExecStartPre=/usr/bin/docker pull datadog/docker-dd-agent (code=exited, status=0/SUCCESS)
Process: 2283 ExecStartPre=/usr/bin/docker rm dd-agent (code=exited, status=1/FAILURE)
Process: 2275 ExecStartPre=/usr/bin/docker kill dd-agent (code=exited, status=1/FAILURE)
Main PID: 2315 (code=exited, status=0/SUCCESS)
Sep 04 18:06:26 core-01 docker[2275]: Error response from daemon: No such container: dd-agent
Sep 04 18:06:26 core-01 docker[2275]: 2014/09/04 18:06:26 Error: failed to kill one or more containers
Sep 04 18:06:26 core-01 docker[2283]: Error response from daemon: No such container: dd-agent
Sep 04 18:06:26 core-01 docker[2283]: 2014/09/04 18:06:26 Error: failed to remove one or more containers
Sep 04 18:06:26 core-01 docker[2294]: Pulling repository datadog/docker-dd-agent
Sep 04 18:06:30 core-01 systemd[1]: Started Datadog Agent.
Sep 04 18:06:30 core-01 docker[2315]: 5289f15b79aebe76d1a623c5464b19811606cb72c714949d4357c99535fbb1d1
Cloud-Config からインストールする
cloud-config の dd-agent に関連する部分だけ記載
#cloud-config
coreos:
units:
- name: docker-tcp.socket
command: start
enable: true
content: |
[Unit]
Description=Docker Socket for the API
[Socket]
ListenStream=2375
Service=docker.service
BindIPv6Only=both
[Install]
WantedBy=sockets.target
- name: dd-agent.service
command: start
enable: true
content: |
[Unit]
Description=Datadog Agent
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill dd-agent
ExecStartPre=-/usr/bin/docker rm dd-agent
ExecStartPre=/usr/bin/docker pull datadog/docker-dd-agent
ExecStart=/usr/bin/docker run --privileged --name dd-agent -h %H -v /var/run/docker.sock:/var/run/docker.sock -v /proc/mounts:/host/proc/mounts:ro -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro -e API_KEY=c0re0s070120131499294110c0re0sdd datadog/docker-dd-agent
[Install]
WantedBy=multi-user.target
dd-agent は docker が利用可能になってから起動させるように書いてある。
この cloud-init を用いて provisioning すると自動で dd-agent コンテナが起動する。
しかし、マシン起動直後に $ docker ps
しても dd-agent は確認出来ない、これは systemd が全 unit の dependency を解決して順番に service を実行しているためで少しまてば dd-agent コンテナが起動してくる。systemctl
を使えば pull 中とか経過も確認できる。
$ systemctl status dd-agent.service
● dd-agent.service - Datadog Agent
Loaded: loaded (/etc/systemd/system/dd-agent.service; enabled)
Active: activating (start-pre) since Fri 2014-09-05 14:06:11 UTC; 44s ago
Process: 914 ExecStartPre=/usr/bin/docker rm dd-agent (code=exited, status=1/FAILURE)
Process: 857 ExecStartPre=/usr/bin/docker kill dd-agent (code=exited, status=1/FAILURE)
Control: 923 (docker)
CGroup: /system.slice/dd-agent.service
└─control
└─923 /usr/bin/docker pull datadog/docker-dd-agent
Sep 05 14:06:11 core-02 systemd[1]: Starting Datadog Agent...
Sep 05 14:06:12 core-02 docker[857]: Error response from daemon: No such container: dd-agent
Sep 05 14:06:12 core-02 docker[857]: 2014/09/05 14:06:12 Error: failed to kill one or more containers
Sep 05 14:06:12 core-02 docker[914]: Error response from daemon: No such container: dd-agent
Sep 05 14:06:12 core-02 docker[914]: 2014/09/05 14:06:12 Error: failed to remove one or more containers
Sep 05 14:06:12 core-02 docker[923]: Pulling repository datadog/docker-dd-agent
スクリーンショット
このダッシュボードは予め用意されたものではなくてカスタムダッシュボードでこういうのが作れる。特に Top Lists ウィジェットが便利
メモと感想
有料の Datadog を使う事に関して
パッケージを直接インストールできない、CoreOS 上の Docker コンテナの監視をどうするかという事に関して Datadog は非常に良い選択肢だと思っている。お金はかかるけれど、OSS のモニタリングツールと可視化ツールを組み合わせてもここまでのものは用意できない...と思ったのが正直なところ。Docker コンテナについても datadog で非常に気持ちよくモニタリングできているので、合わせて別の記事を投稿しようと思う。
unifile 内での etcd の値の取得方法はどうしたらいいか
この記事の本筋とは反れるかもだけど、etcd に set しておいた value を systemd の unitfile で受け取る正しい(またはスマートな)やり方ないのかな。EnvironmentFile
を使うって手もある、etcd から環境変数ファイルを作成するための unit を作って、それを依存関係で指定しておくとか。
systemd を使って dd-agent を自動起動する場合予め pull した CoreOS イメージを使うかどうか
CoreOS クラスタの増強時に dd-agent コンテナの pull の時間を省こうと思うと、既に pull 済みの CoreOS イメージ (AMI とか)を用いる方法がある。しかし、CoreOS マシンをステートレス(という言い方がこの場合にふさわしいかわからないが)な状態にしておこうと思うとカスタマイズしたイメージは作らない方がいい。12Factor App のようにインフラ側もステートレスに出来るならしていおいた方が後でとにかく色々と使い回しやすいんじゃないかと思っている。実際に本番環境には dd-agent を入れるけどお金節約のためステージング環境には入れない、みたいな場合に CoreOS AMI に dd-agent を入れてしまうとステージング環境で使えなくなる、ということがあった。初期起動を犠牲に使い回しやすさを取る場合、S3 に置いたイメージを EC2 上の CoreOS から pull すると 1GB のイメージで 40 秒程度で終わるが、複数のイメージを自動起動する場合に 40s * 3 = 120s 。X-ConditionMachineMetadata
を使って環境によって dd-agent 起動しないっていう方法もありそう。
コンテナ名は dd-agent でいいのか、クラスタ全体で一意にしなくていいか
わかりやすさでいうと dd-agent がシンプルでいいよなー。同じコンテナ名だけど特定のコンテナにだけ負荷がかかったりで異常が出たりとかの場合に一意にしておくとよい。どちらがいいのか。