GKE クラスタに Datadog Agent を導入する際の注意点まとめ

こんにちは、京セラコミュニケーションシステム 井筒 (@kccs_naoto-izutsu) です。

Google Cloud の Google Kubernetes Engine(以下、GKEと表記) のクラスタに Datadog Agent を導入する機会が増えてきた気がしている今日この頃。
GKE クラスタに Datadog Agent を導入することで可観測性を向上させることができるのですが、導入する際にいくつか注意したほうがよいなと思った点があったので、ざっくりまとめてみます。

## Datadog Agent を導入する際の注意点

GKE クラスタに Datadog Agent を導入する際の注意点がいくつかあります。
また、GKE クラスタの運用モードによっても注意点が異なります。

注意点は、主に以下の5つです。

- 共通
  - 運用モードフラグ
  - スポットインスタンスへのインストール
  - Pod スケジューリングの優先度
- Autopilot モード
  - リソースリクエスト
  - Autodiscovery の調整

順番に見ていきましょう。

なお、各種設定などは、Helm でインストールすることを前提とした内容となっています。
Operator を使う場合でもポイントは変わらないと思いますが、設定方法などは異なると思いますので、注意してください。

### 運用モードフラグ

GKE クラスタには、スタンダード と Autopilot の2つの運用モードがあり、GKE クラスタの運用モードに合わせて Datadog Agent を設定する必要があります。

Datadog Agent の Helm Chart に含まれる [values.yaml](https://github.com/DataDog/helm-charts/blob/main/charts/datadog/values.yaml) ファイルの最後のほうに以下のようなパラメータがありますので、GKE クラスタの運用モードに合わせて設定します。

```yaml
providers:
  gke:
    # providers.gke.autopilot -- Enables Datadog Agent deployment on GKE Autopilot
    autopilot: false

    # providers.gke.cos -- Enables Datadog Agent deployment on GKE with Container-Optimized OS (COS)
    cos: false
```

**GKE クラスタの運用モードを Autopilot で構成する場合**は、`autopilot: true` としておく必要があります。
また、ノードの OS は COS(Container-Optimized OS)を使うケースが多いと思いますので、`cos: true` としておきましょう。

#### 参考ドキュメント

- [GKE Autopilot と GKE Standard の比較](https://cloud.google.com/kubernetes-engine/docs/resources/autopilot-standard-feature-comparison?hl=ja)
- [values.yaml](https://github.com/DataDog/helm-charts/blob/main/charts/datadog/values.yaml#L2255)

### スポットインスタンスへのスケジューリング

GKE クラスタノードにスポットインスタンスを使用している場合は、注意が必要です。
Datadog Agent を素直にインストールすると、スポットインスタンスにスケジューリングされず、Datadog Agent が起動しません。

values.yaml に以下の設定を入れることで、スポットインスタンスにもスケジューリングされるようになります。
スポットインスタンスを使用する予定がなくても、設定しておくといいと思います。

```yaml
agents:
  #(...)
  # agents.tolerations -- Allow the DaemonSet to schedule on tainted nodes (requires Kubernetes >= 1.6)
  tolerations:
  - effect: NoSchedule
    key: cloud.google.com/gke-spot
    operator: Equal
    value: "true"
```

#### 参考ドキュメント

- [Spot VM でのワークロードのスケジューリング](https://cloud.google.com/kubernetes-engine/docs/concepts/spot-vms?hl=ja#scheduling-workloads)
- [Kubernetes ディストリビューション - Spot ポッドとインスタンス](https://docs.datadoghq.com/ja/containers/kubernetes/distributions/?tab=helm#spot-%E3%83%9D%E3%83%83%E3%83%89%E3%81%A8%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9)

### Pod スケジューリングの優先度

Kubernetes の挙動として、ノードの CPU 負荷が高かったりすると、そのノードに対して Pod をスケジューリングしない場合があります。
Datadog Agent がスケジューリングされない(起動しない)とモニタリングに支障をきたしてしますので、確実に起動できるように Pod の優先度を高くしておきましょう。

values.yaml に以下の設定を入れることで、自動的に PriorityClass `datadog-agent` が作成され、値 `1000000000` がセットされます。
これにより、Datadog Agent の Pod は通常の Pod よりも優先的にスケジューリングされるようになります。

```yaml
agents:
  priorityClassCreate: true
```

個別に設定した PriorityClass を使用することもできますので、GKE の運用スタイルに合わせて設定しておきましょう。

#### 参考ドキュメント

- [Podの優先度とプリエンプション](https://kubernetes.io/ja/docs/concepts/scheduling-eviction/pod-priority-preemption/)
- [values.yaml](https://github.com/DataDog/helm-charts/blob/main/charts/datadog/values.yaml#L1924)

### リソースリクエスト

GKE の Autopilot モードは、リソースリクエストの挙動に特徴があります。
Autopilot モードの GKE クラスタに Datadog Agent をリソース指定なしでインストールすると、Pod に割り当てられるメモリが少なく OOM Kill されてしまいます(感覚的には、まず起動しません)。

どれだけのリソースを割り当てるべきかは環境によってことなると思いますが、少なくとも values.yaml のコメントに記載されているくらいは割り当てたほうが良いと思います。

```yaml
      # agents.containers.agent.resources -- Resource requests and limits for the agent container.
      resources: {}
      #  requests:
      #    cpu: 200m
      #    memory: 256Mi
      #  limits:
      #    cpu: 200m
      #    memory: 256Mi
```

#### 参考ドキュメント

- [Autopilot でのリソース リクエスト](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-resource-requests?hl=ja)
- [Kubernetes distributions - Google Kubernetes Engine (GKE)](https://docs.datadoghq.com/containers/kubernetes/distributions/?tab=helm#GKE)
- [values.yaml](https://github.com/DataDog/helm-charts/blob/main/charts/datadog/values.yaml#L1633)

### Autodiscovery の調整

GKE の Autopilot の Dataplane V2 には、cilium がインクルードされています。

[GKE Dataplane V2 and NetworkPolicy](https://cloud.google.com/kubernetes-engine/docs/concepts/dataplane-v2#network-policy)

そのため、Datadog Agent のオートディスカバリ機能で cilium の Integration が自動的にセットアップされます。
が、[オートディスカバリのデフォルトコンフィグ](https://github.com/DataDog/integrations-core/blob/master/cilium/datadog_checks/cilium/data/auto_conf.yaml)では cilium の Listen ポートが `9962` に設定されていますが、GKE の Cilium が Listen するポートと異なるので、以下のようなエラーログが出力され続けてしまいます。

```text
$ kubectl logs <POD NAME> -n datadog
2024-08-17 07:30:42 UTC | CORE | ERROR | (pkg/collector/worker/check_logger.go:71 in Error) | check:cilium | Error running check: [{"message": "HTTPConnectionPool(host='10.128.0.29', port=9962): Max retries exceeded with url: /metrics (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7a1821728e10>: Failed to establish a new connection: [Errno 111] Connection refused'))
```

GKE の Autopilot では、cilium はコンテナイメージ `image_name:gke.gcr.io/cilium/cilium` が使用され、Namespace `kube-system` の Daemon Set  `anetd` で起動されます。
設定ファイルを保持している ConfigMap `cilium-config` を見てみると、Listen ポートは `prometheus-serve-addr:9990` となっています。

`values.yaml` に以下のように設定を追加して Listen ポートを変更することで、接続エラーを回避できます。

```yaml
datadog:
  confd:
    cilium.yaml: |-
      ad_identifiers:
        - cilium
      init_config:
      instances:
        - agent_endpoint: http://%%host%%:9990/metrics
          use_openmetrics: true
  ignoreAutoConfig:
    - cilium
```

#### 参考ドキュメント

- [Basic Agent Autodiscovery](https://docs.datadoghq.com/getting_started/containers/autodiscovery/)
- [Kubernetes and Integrations](https://docs.datadoghq.com/containers/kubernetes/integrations/)
- [Autodiscovery Auto-Configuration](https://docs.datadoghq.com/containers/guide/auto_conf/?tab=datadogoperator)

## 最後に

GKE に Datadog Agent をインストールする際の注意点をまとめてみました。
GKE に新しい機能が追加されたり、Kubernetes のバージョンが上がったりすることで、新たな注意点が出てくるかもしれませんが、2024年9月時点の内容として誰かのお役に立てたら嬉しく思います。

## 免責事項

記事の内容を筆者の理解をベースに作成したものとなり、実際の内容とは異なる可能性があります。
正確な情報は必ず Google Cloud や Datadog の公式ドキュメントを参照してください。