GKEでDatadogを使う方法

  • このエントリーをはてなブックマークに追加

最近はAWSだけでなくGCPも使っています。

GCPのMonitoringにはStackdriverがあり、k8sのMonitoringはPrometheus+Grafanaが定番です。

とはいえアラートを含めたシステムのモニタリングツールは何種類も運用したくありません。出来れば1つにまとめたいところです。いまの会社ではDatadogを使っているので、GKE(1.8)+Datadogをやってみます。
またアプリケーションからcustom metricsを送りたいので、その対応も行います。

Datadogのセットアップ

  • Datadogのアカウントを取得します。
  • GCPのサービスアカウントを作成します(権限はProject/閲覧者あたり)
  • 連携させます

これで主要なSystem Metricsは連携され、いくつかのダッシュボードも見れるようになります。
これはAWSでいうところのRDS等のMetricsを見れるようにするのと同じ感じで、まだAgentは入れていません。

GKEのクラスタにAgentを入れる

ここにManualがあります

Agentはノード(GCE Instance)単位で入れるため、DaemonSetとして扱います。ただ、↑のマニュアルに書いてある記述は今時点では1.7の方法なので、1.8向けに書き直します。またAPIキーはManifestに直書きする事はせずに、Secretから取得するように直します。

修正前(マニュアルのまま) APIキーは伏せてます

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: datadog-agent
spec:
template:
metadata:
labels:
app: datadog-agent
name: datadog-agent
spec:
containers:
- image: datadog/agent:latest
imagePullPolicy: Always
name: datadog-agent
ports:
- containerPort: 8125
name: dogstatsdport
protocol: UDP
env:
- name: DD_API_KEY
value: ****
- name: KUBERNETES
value: "yes"
- name: DD_KUBERNETES_KUBELET_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "250m"
volumeMounts:
- name: dockersocket
mountPath: /var/run/docker.sock
- name: procdir
mountPath: /host/proc
readOnly: true
- name: cgroups
mountPath: /host/sys/fs/cgroup
readOnly: true
livenessProbe:
exec:
command:
- ./probe.sh
initialDelaySeconds: 15
periodSeconds: 5
volumes:
- hostPath:
path: /var/run/docker.sock
name: dockersocket
- hostPath:
path: /proc
name: procdir
- hostPath:
path: /sys/fs/cgroup
name: cgroups

修正版

  • k8s1.8ではDaemonSetはapps/v1beta2になってました
    • apps/v1beta2ではspec.selectorが必須です
    • spec.selectorで指定するやつはspec.template.metadata.labelsと完全一致させないと怒られました..
  • 他のpodからcustom metricsをdogstats経由で送信したいため、8125/UDPをHost(ノード)に公開します
  • Traceの機能も同様に他のpodから使いたいため8126/TCPをHost(ノード)に公開します
  • API_KEYはSecretから取得します。作成コマンドは以下参照。
    • kubectl create secret generic datadog --from-literal=api_key=*****
datadog-agent.yaml
apiVersion: apps/v1beta2
kind: DaemonSet
metadata:
name: dd-agent
spec:
selector:
matchLabels:
app: dd-agent
template:
metadata:
labels:
app: dd-agent
name: dd-agent
spec:
containers:
- image: datadog/docker-dd-agent:latest
imagePullPolicy: Always
name: dd-agent
ports:
- containerPort: 8125
hostPort: 8125
name: dogstatsdport
protocol: UDP
- containerPort: 8126
hostPort: 8126
name: ddtracedport
protocol: TCP
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: datadog
key: api_key
- name: KUBERNETES
value: "yes"
- name: SD_BACKEND
value: docker
- name: KUBERNETES_KUBELET_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "250m"
volumeMounts:
- name: dockersocket
mountPath: /var/run/docker.sock
- name: procdir
mountPath: /host/proc
readOnly: true
- name: cgroups
mountPath: /host/sys/fs/cgroup
readOnly: true
livenessProbe:
exec:
command:
- ./probe.sh
initialDelaySeconds: 15
periodSeconds: 5
volumes:
- hostPath:
path: /var/run/docker.sock
name: dockersocket
- hostPath:
path: /proc
name: procdir
- hostPath:
path: /sys/fs/cgroup
name: cgroups

これをdeployします。

kubectl create -f datadog-agent.yaml

他のPODからCustom Metricsを送る場合

上図のようにPOD間通信になりますが、アプリが起動しているノード上のdd-agentと起動したいので、ノードのIP:Portで通信する必要があります。**※localhost:8125**ではないです。

status.hostIPでノードのIPを取得して環境変数に設定できるので、アプリのManifestに次の記述を入れます。これで環境変数_DD_NODE_HOSTにノードのIPが入ります。

env:
- name: _DD_NODE_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP

公式のJava Clientであれば次のように環境変数からIPを取得し、Clientを初期化します。

statsd = new NonBlockingStatsDClient(
null,
StringUtils.defaultIfEmpty(System.getenv("_DD_NODE_HOST"), "localhost"),
8125,
null);

これでCustom Metricsを送信できるようになりました。

課金

Datadogは5ノードまで無料、コンテナの場合は1ノードあたり10コンテナまで無料で超過分は1コンテナあたり1ドル/月です。(1ノードあたりは18ドル(年間契約だと15ドル))