サービスメッシュを実現するIstioをEKS上で動かす - その6 Datadogと連携する

山崎 雅斗
12

サービス監視によく用いられているDatadogは、公式でIstioとの連携がサポートされています。
しかし、IstioとDatadogの連携を取り上げた記事の数はまだ少なかったので、ここではそれらの連携について試していきたいと思います。

シリーズ一覧

環境

今回の検証で使用したのは以下の環境です。

  • EKS(Kubernetes v1.11)
  • Istio v1.0.5

Datadog agentのインストール

Datadogによる監視を行うためには、Kubernetesクラスタの各WorkerノードにDatadog agentをインストールしておく必要があります。
Datadog公式のインストール手順を参考に、DaemonSetリソースを使ってインストールしていきます。

今回適用したmanifestは次のとおりです。 <Your Datadog API Key> の部分は各自のAPI Keyに置き換えてください。

 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
           - containerPort: 8126
             name: traceport
             protocol: TCP
         env:
           - name: DD_API_KEY
             value: <Your Datadog API Key>  # replace this with your API key
           - name: KUBERNETES
             value: "true"
           - name: DD_KUBERNETES_KUBELET_HOST
             valueFrom:
               fieldRef:
                 fieldPath: status.hostIP
         resources:
           requests:
             memory: "256Mi"
             cpu: "200m"
           limits:
             memory: "256Mi"
             cpu: "200m"
         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

このmanifestを datadog-agent.yml という名前で保存し、 kubectl コマンドを使って適用します。また、EKSクラスタではRBACが有効になっているため、それで必要な設定を上のmanifestと同時に適用しておきます。

 $ kubectl apply -f datadog-agent.yml
 $ kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/rbac/clusterrole.yaml"
 $ kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/rbac/serviceaccount.yaml"
 $ kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/rbac/clusterrolebinding.yaml"

適用したら、Datadog agentがインストールされているか確認しておきます。

$ kubectl get daemonsets
NAME            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
datadog-agent   2         2         2       2            2           <none>          4m

IstioとDatadogの連携設定

Datadogコンテナの /conf.d/istio.d/config.yaml に、Istioと連携するための設定ファイルを置きます。
Istioとの連携設定と合わせて、ログも収集できるような設定も入れておきます。
ここでは、ConfigMapを使って設定ファイルをPodにマウントする形でファイルを配置していきます。

先程の datadog-agent.yml に、ConfigMapの設定を追記します。

...
(省略)
...
         - hostPath:
             path: /sys/fs/cgroup
           name: cgroups
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: dd-agent-config
  namespace: default
data:
  conf.yaml: |
    init_config:

    instances:
      - istio_mesh_endpoint: http://istio-telemetry.istio-system:42422/metrics
        mixer_endpoint: http://istio-telemetry.istio-system:9093/metrics
        send_histograms_buckets: true

次に、Datadog agentのPodがこのConfigMapをマウントするように、DaemonSetを少し修正します。
まず、 spec.template.volumes に次の2つを追加します。

      volumes:
        - hostPath:
            path: /opt/datadog-agent/run
          name: pointerdir
        - name: confd-istiod-config
          configMap:
            name: dd-agent-config
            items:
              - key: conf.yaml
                path: conf.yaml

上で追加したVolumeをマウントするように、 spec.template.containers.volumeMounts を修正します。

        volumeMounts:
          - name: pointerdir
            mountPath: /opt/datadog-agent/run
          - name: confd-istiod-config
            mountPath: /conf.d/istio.d

ログの収集もできるように、 spec.template.containers.env へ環境変数を2つ追加しておきます。

        env:
          - name: DD_LOGS_ENABLED
            value: "true"
          - name: DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL
            value: "true"

datadog-agent.yml にこれらの修正を入れたら、再度 kubectl コマンドで適用します。

$ kubectl apply -f datadog-agent.yml

Istio

Datadog agentがDatadogに接続するための設定

ここまでの手順で、Datadog agentのインストールとIstioとの連携設定は完了です。
しかし、このままだとDatadog agentがDatadogに接続することができずに下のようなログが吐き出されている状態となっています。

$ kubectl logs -f datadog-agent-4jf24 -c datadog-agent
...
[ AGENT ] 2019-03-25 13:34:49 UTC | ERROR | (pkg/forwarder/worker.go:138 in process) | Too many errors for endpoint 'https://6-10-2-app.agent.datadoghq.com/api/v1/series?api_key=*************************22a63': retrying later
[ AGENT ] 2019-03-25 13:34:49 UTC | ERROR | (pkg/forwarder/worker.go:138 in process) | Too many errors for endpoint 'https://6-10-2-app.agent.datadoghq.com/api/v1/series?api_key=*************************22a63': retrying later
[ AGENT ] 2019-03-25 13:34:49 UTC | ERROR | (pkg/forwarder/worker.go:138 in process) | Too many errors for endpoint 'https://6-10-2-app.agent.datadoghq.com/api/v1/series?api_key=*************************22a63': retrying later
[ AGENT ] 2019-03-25 13:34:49 UTC | ERROR | (pkg/forwarder/worker.go:138 in process) | Too many errors for endpoint 'https://6-10-2-app.agent.datadoghq.com/api/v1/series?api_key=*************************22a63': retrying later
...

Istioでは、サービスから出るすべての通信がSidecar Proxy経由となり、そのルーティングはPilotによって管理されています。そのため、サービスメッシュ外にあるサービスへ接続したい場合はその都度設定をしてあげる必要があります。
Datadog agentがDatadogのエンドポイントに接続できるようにするため、ServiceEntryリソースの定義を datadog-agent.yml に追加します。

...
(省略)
...
        - istio_mesh_endpoint: http://istio-telemetry.istio-system:42422/metrics
          mixer_endpoint: http://istio-telemetry.istio-system:9093/metrics
          send_histograms_buckets: true

---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: datadog
spec:
  hosts:
    - "*.agent.datadoghq.com"
  location: MESH_EXTERNAL
  ports:
    - number: 443
      name: https
      protocol: HTTPS
  resolution: NONE

datadog-agent.yml を修正したら、再度適用します。

$ kubectl apply -f datadog-agent.yml

これで先程のエラーログが出なくなり、下のようにDatadogのダッシュボードにagentが認識されていれば連携は完了です。

datadog
Datadog