Chatwork Creator's Note

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

読者になる

Prometheus形式で公開されたmetricsを、Datadog Prometheus Checkを利用して取得する

SRE部のcw-sakamotoです。

nginx-ingress on AWS で gRPC をロードバランスさせる検証 - ChatWork Creator's Noteにおいて、少しだけ言及しました、Datadog Prometheus Checkに関する内容です。

Kubernetesの監視と言えば、Prometheusのイメージが強い?ですが、ChatWorkでは、もともと非Kubernetes環境においてDatadogで監視していることから、KubernetesもDatadogで監視しています。

そこで、本記事では、DatadogによるKubernetes監視自体に関して軽く触れてから、実際の設定ファイルを示しながら、Datadog Prometheus Checkの設定や、確認方法について記載します。

Datadog Prometheus Checkとは、Prometheus形式で公開されているmetricsを、Datadogが収集して、Datadogのmetricsとして扱う、というものです。 Chartsでいろいろなアプリケーションが公開されていますが、そのほとんどはPrometheusのcustom metricsのみに対応していることが多いです。この機能を利用することで、 Prometheus形式のmetricsをDatadogが収集し、表示することが可能になります。

設定に関しては、基本的には下記の通りですが、これをnginx-ingressで試したいと思います。 docs.datadoghq.com

なお、本記事で触れているDatadogはすべてのversion 6(6.1以降)に関するものです。version 5では対応していない内容ですので、お気をつけください*1

ちなみにv6になってから、パフォーマンスが向上したので、v6の利用をオススメします。v5には、隠れlimitがあって、メトリクス欠損がかなり発生していました*2

アジェンダ

Kubernetesの監視をDatadogで行う

Kubernetes監視において、Datadogで取得できるmetricsはたくさんあります。jobの成否やpodの生死などのeventも取得できるので、それをチャットに流したりしています。

下記はpodごとのCPU使用率のグラフで、ChatWorkでは他にも必要なmetricsをdashboardにまとめてKubernetes監視を行っています。 f:id:cw-sakamoto:20180626125922p:plain

Datadog agentのインストール

公式のChartsを利用します。

charts/stable/datadog at master · kubernetes/charts · GitHub

検証時の各versionです。

  • datadog image version 6.2.1
  • charts version 0.11.3

設定ファイルは下記の内容です。

$ cat setting-datadog.yaml
image:
  repository: "datadog/agent"
  tag: "6.2.1"

# kube-state-metricsのroleも作成されるようになったので、true
# https://github.com/kubernetes/charts/pull/2969
kubeStateMetrics:
  enabled: true

datadog:
  # 複数環境(test, staging, production等)からのメトリクスを分類できるように(Datadog APMトレースのタグにはならない)
  tags: "kubernetes:test-k8s"

  # apmはとりあえず使わない
  apmEnabled: false

  # event収集のleader
  leaderElection: true
  leaderLeaseDuration: "60"

  # 一時的にdebugに設定
  #logLevel: "DEBUG"

  # v6対応 https://github.com/DataDog/datadog-agent/tree/master/Dockerfiles/agent
  nonLocalTraffic: true

  env:
    # process agent 有効に
  - name: DD_PROCESS_AGENT_ENABLED
    value: "false"

    # logは使用しない
  - name: DD_LOGS_ENABLED
    value: "false"

  # process agentのため
  volumeMounts:
  - name: passwd
    mountPath: /etc/passwd
    readOnly: true
  volumes:
  - hostPath:
      path: /etc/passwd
    name: passwd

  resources:
    requests:
      cpu: 256m
      memory: 512Mi
    limits:
      cpu: 512m
      memory: 512Mi

# Masterノードのメトリクスも収集できるようにtolerationを入れる
daemonset:
  useHostPort: false
  useHostNetwork: true
  updateStrategy: RollingUpdate
  tolerations:
    - operator: Exists
      effect: NoSchedule
    - operator: Exists
      effect: NoExecute
    - operator: Exists
      key: CriticalAddonsOnly

daemonsetで動かし、pod ipを固定するために、useHostNetwork: trueで動かします。これによって、Datadog agentのpod ipがhost ipになるので、それをDownward APIのstatus.hostIPで取得し、アプリでは環境変数で設定しています。

この設定内容で、下記のようにinstallします。secrets.yamlには、datadog api keyを記載しています。

$ helm upgrade -f setting-datadog.yaml -f secrets.yaml stable/datadog --namespace kube-system --install

Datadog Prometheus Checkの利用

dd-agent v5でも利用可能でしたが、v6の6.1から、デフォルトで利用可能になりました。

設定の例が上記にありますが、ここではnginx-ingressで設定してみます。

nginx-ingressでは、podAnnotationsで、podにannotationを付与することができるので、そこに、Prometheus Check用のannotationを記載します。

これは、datadog-agentのservice discoveryのannotationの書き方でもあります。

書き方のハマりポイントですが、

  • namespace、metricsは必須項目
    • ここに気が付かなくて、ハマりました
  • namespaceは、kubernetesのnamespaceではなく、datadogのnamespace
    • metricsの分類に使われます(datadogでは、namespace.metricsとして扱われます)
  • 設定エラーは、logファイルにしか出ないものがある
    • namespaceなどが必須項目であることはdadog-agentのlogにしか出ませんでした
  • nginx-ingressは、service経由でPrometheusのmetricsを公開しているが、annotationに記載するのは、podの公開URL
    • serviceのportとpodのportが異なり、annotationにはpodのportを書く必要がある
    • nginx-ingressにおいて、Prometheus用ポートはserviceは9913だが、podは10254

Datadog Prometheus Checkがうまく動作しているかどうかを確認する

起動しているかどうかの確認は下記のいずれかで確認します。

  • logファイルを確認する
    • 起動している場合は何も出ないが、エラーはここに出る
  • agent configcheckコマンド
    • 設定内容が正しいかどうかの確認
  • agent statusコマンド
    • 現状の設定でのステータス確認

ということで、それらをまとめてまるっと見るために下記のワンライナーを実行します。

node=$(kubectl get po -o wide | grep grpc-controller | awk '{print $7}');  ddpod=$(kubectl -n kube-system get po -o wide |grep datadog | grep $node | awk '{print $1}') ; kubectl -n kube-system exec -it $ddpod -- sh -c 'tail -n 100 /var/log/datadog/agent.log | grep prometheus; agent configcheck; agent status'

今回はnginx-ingressに対するDatadog Prometheus Checkを確認したいので、上記のコマンドでは、nginx-ingressが動いているnodeで動いているdatadog-agentに対して、kubectl execでコマンドを実行しています。

agent configcheckには下記のように表示され、

=== prometheus check ===
Source: Kubernetes pod annotation
Instance 1:
metrics:
- go_*
- nginx_*
- process_*
- read_bytes_total
- resident_memory_bytes
- virtual_memory_bytes
- write_bytes_total
- num_procs
- ingress_
- process_open_fds
namespace: test
prometheus_url: http://11.2.27.38:10254/metrics
tags:
- image_name:quay.io/kubernetes-ingress-controller/nginx-ingress-controller
- short_image:nginx-ingress-controller
- image_tag:0.15.0
- docker_image:quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.15.0
- kube_namespace:test
- kube_deployment:nginx-ingress-grpc-controller
- kube_container_name:nginx-ingress-controller
~
Init Config:
{}
Auto-discovery IDs:
* docker://d316d5733eda00f9271a....

agent statusには下記のように表示されます。

    prometheus
    ----------
      Total Runs: 23257
      Metrics: 210, Total Metrics: over 1M
      Events: 0, Total Events: 0
      Service Checks: 1, Total Service Checks: 23257
      Average Execution Time : 40ms

Datadogでmetricsを確認する

では実際にmetricsが送られているかどうかをDatadog側で確認します。 今回設定したメトリクスは下記で、そのうちのいくつかを見てみます。

            "metrics": [
              "go_*",
              "nginx_*",
              "process_*",
              "read_bytes_total",
              "resident_memory_bytes",
              "virtual_memory_bytes",
              "write_bytes_total",
              "num_procs",
              "ingress_",
              "process_open_fds"]

f:id:cw-sakamoto:20180625164606p:plain f:id:cw-sakamoto:20180625164629p:plain

たしかにDatadog側でmetricsが確認できました。

まとめ

Datadogで、Prometheus形式で公開されているmetricsを取得する手順を、nginx-ingressを例にして、試してみました。 Datadogで見たいけど(見るところは統一したいけど)、Prometheus形式のmetricsが...という場合に使えそうです。