Blog
Datadog のライブコンテナモニタリングとアラートを使って賢く監視問題を解決する
こんにちは。
CIA の青山真也です。
今回は先日実装された Datadog によるコンテナのライブモニタリングを Kubernetes 上で実行する際のお話をさせて頂ければと思います。
百聞は一見にしかず。ということで、まずはライブコンテナモニタリングを確認してみましょう。
コンテナ毎に2秒周期でメトリクスが更新され、リソースの状況が非常に分かりやすくなっています。
コンテナに対する絞り込みは、Deployment に紐づく Pod、Service に紐づく Pod 、Namespace や Image など様々な条件でフィルタリングすることが可能です。
Docker からのメトリクスの取得
Kubernetes クラスタ上で Datadog を使ってメトリクスを取る話をする前に、単体の Docker の場合のお話をします。
Datadog でコンテナモニタリングを行なうには下記の 2 つの方法があります。
特段の事情がない限りはコンテナを使った方式のほうがアップデートなどが楽であったり、ホスト上への設定が最小限となりポータビリティ性が上がるため、おすすめです。
また、コンテナを使った場合でも、ホストのプロセスなどを監視する事が可能です。
- コンテナホストで datadog-agent プロセスを起動する
- ただし、/etc/dd-agent/conf.d/docker*.yaml を設定する必要があります
- コンテナホスト上に datadog/docker-dd-agent コンテナを起動する
Datadog のコンテナモニタリングでは /var/run/docker.sock、/proc/*、/sys/fs/cgroup から情報を吸い出すことでコンテナおよびホストのモニタリングを行っています。
そのため、コンテナホストからは各領域をマウントする必要があります。
また、コンテナを起動する際に、追加の tag を設定することも可能です。
1 2 3 4 5 6 7 8 |
# docker run -d --name dd-agent \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /proc/:/host/proc/:ro \ -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro \ -e API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXX \ -e SD_BACKEND=docker \ -e TAGS=env:dev,project:sample datadog/docker-dd-agent:latest |
Docker のメトリクスとタグ
各コンテナ毎に CPU、Memory、Disk I/O、Network I/O などの基本的なメトリクスがとれます。
その他にも、ホスト上で稼働しているコンテナ数、イメージ数などのメトリクスも取得することが可能です。
Docker に関するメトリクスは docker.* で登録されています。
また、コンテナのメトリクスに対してデフォルトで下記のタグが埋め込まれています。
#container_name:sample-container
#container_id:57786a376934
#host:dockerhost01
#docker_version:17.06.0.ce
Docker Swarm の場合には Swarm クラスタノードとしての状態もタグとして埋め込まれています。
このタグを利用すれば、active な swarm ノードのみ監視するといった Datadog の Monitor も作成できるため、Downtime にわざわざ入れる必要もなくなります。
#docker_swarm:active
#swarm_service:sample-service
Datadog の Kubernetes Integration の導入
いよいよ本題です。
Kubernetes のメトリクスを Datadog で取得する場合、上記の Docker コンテナを起動する DaemonSets を作り、一部環境変数を追加したものになります。
基本的には Datadog 公式から提供されているものを利用してください。
また、Kubernetes add-on の kube-state-metrics を別途コンテナとして起動し、連携を行うことにより、クラスタレベルのメトリクスを取得することが可能です。
最も簡単な方法は Helm を利用することです。
Helm を利用すると、kube-state-metrics を含め、全てを連携した状態でデプロイしてくれます。
また、values.yaml を書き換えることで追加の config (その他の Integration の yaml config など) を簡単に設定することができます。
1 2 3 |
# helm install --name dd-helming \ --set datadog.apiKey=XXXXXXXXXXXXXXXXXXXXXXXX,datadog.tags="project:sample\,env:dev" stable/datadog |
Kubernetes のメトリクス
Kubernetes のメトリクスは kubernetes.* で登録されています。
また、クラスタレベルのメトリクスは kubernetes_state.* で登録されています。
自動的に複数のタグが付与されており、コンテナの絞り込みは Pod 名やDeployment 名の他にも、Service 名でも行なうことが可能です。
Kubernetes Service の作り方にもよりますが、複数の Deployment に対して Service を流している場合には Service 名で絞り込みを行なうことが可能です。
#kube_service:service-sample
#kube_deployment:dep-sample
#kube_replica_set:
#kube_namespace:default
#kube_pod: #kube_pod_ip:10.100.76.12
#kube_master_version:1.7.8
#kubelet_version:1.7.8
kube-state-metrics から取得可能なクラスタレベルのメトリクスでは、Deployments のレプリカ数なども取得可能です。
他にも Job の成功数・失敗数や、ローリングアップデート時のコンテナ数推移を監視することも可能です。
また、下記の例では特定の Deployment を対象にして Pod の数をカウントしています。
A/B テストの監視例
少し実践的な監視の例をご紹介します。
アドテク領域では、よく A/B テストが実施されます。
A/B テストとは、新しいアルゴリズムや施策などを導入する際に、既存グループに対して一部混ぜ込んでいくことで効果を測定するテスト方法です。
コンテナで実現することを考えると、ロールバックや管理の問題から、アルゴリズム毎にコンテナイメージ自体が異なることが望ましいと考えられます。
つまり、コンテナイメージが違うため Deployment は 2 種類用意する形になります
ちなみに、Deployment の Rolling Update を上手く使えば Deployment が 1 つでもイメージを混在させた状態で保つことができますが、A/B テストと Rolling Update の目的が異なるため、あまり推奨できない使い方だと思います。
また、管理が複雑になる点や 3 つ以上のイメージが混在する場合は難しい点からも、Deployment を複数用意する形が望ましいと思います。
まず、初期時点では下記のように Deployment 1 つ(Replica: 3)、 Service 1 つの状態で起動されていると仮定します。
(Image は例のため、zembutsu さんの nginx を題材とします。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
--- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: dp1 spec: replicas: 3 selector: matchLabels: app: abtest ab: test1 template: metadata: labels: app: abtest ab: test1 spec: containers: - name: nginx-container image: zembutsu/docker-sample-nginx:1.0 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: ab-endpoint spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 selector: app: abtest |
次に別のアルゴリズムを使った Deployment を作成します。
この時、既にあるアルゴリズムよりも影響範囲を少なくするため、コンテナ数を調整しておいたりします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: dp2 spec: replicas: 2 selector: matchLabels: app: abtest ab: test2 template: metadata: labels: app: abtest ab: test2 spec: containers: - name: nginx-container image: zembutsu/docker-sample-nginx:1.0 ports: - containerPort: 80 |
この時点で、
Deployment dp1 の Pod は Label として app:abtest, ab:test1、
Deployment dp2 の Pod は Label として app:abtest, ab:test2
をそれぞれ持っています。
また、Service ab-endpoint は Label として app:abtest を持つ Pod に対してトラフィックを転送するため、A/B 両方のアルゴリズムに対してトラフィックがを割り当てることができるようになります。
この状態でこのシステムの監視を行う場合、Deployment dp1, dp2 それぞれの Pod 数を合計しても良いのですが、このままだと dp3 を追加する場合や名称に変更があった場合などに変更範囲が大きくなってしまいます。
しかし、Service タグで絞込を行なうことで柔軟に合計 Pod 数を監視することが可能になります。
また、この方法を使えば A/B テストに限らず、カナリアリリースなども同様の方法で監視することが可能です。
なお、実際にエンドポイントが必要ない場合に Service を作っても特段問題がないケースが多いと思います。
Datadog を使った Kubernetes の監視はいかがでしょうか。
Helm で一発で展開、タグも通常の用途としては十分についており、使いやすいと感じて頂けましたでしょうか。
Datadog のコンテナ監視は常に変化しており、より使いやすくなってきています。
今回はバージョンは 5.18.1 を利用しましたが、バージョンが上がるにつれて新機能が増えることもあるかと思うので、この先も要 Watch したいと思います。
Author