最近は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.yamlapiVersion: 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ドル))