Datadog メトリクスまたはカスタムクエリを使用して Kubernetes のワークロードをオートスケーリングする | Datadog

Datadog メトリクスまたはカスタムクエリを使用して Kubernetes のワークロードをオートスケーリングする

Author Charly Fontaine

Last updated: 11月 12, 2020

編集者メモ: この投稿は 2020 年 11 月 12 日に更新されました。新しい DatadogMetric CRD を用いて、カスタム Datadog クエリに基づいて Kubernetes ワークロードのオートスケーリングを行う方法が追加されました。

別の記事 で詳しくご紹介している Datadog Cluster Agent のリリースにより、Datadog で収集されたメトリクスのリアルタイムの変化に伴って Kubernetes で実行中のアプリケーションのオートスケーリングができるようになりました。また、関数と算術演算でメトリクスクエリのカスタマイズが可能な新しい CRD もリリースされました。これにより、クラスター内でのオートスケーリングの内容をより正確に制御できるようになります。

Kubernetes での水平ポッドオートスケーリング

Kubernetes v1.2 で導入された Horizontal Pod Autoscaling (HPA) 機能を利用して、ユーザーは metrics-server というリソースからアクセスできる CPU などの基本メトリクスでアプリケーションのオートスケーリングを行うことができます。Kubernetes v1.6 では、クラスターから収集したユーザー定義型のカスタムメトリクス によるオートスケーリングが可能となりました。Kubernetes v1.10 では外部メトリクスのサポートも追加され、クラスター外のあらゆるメトリクスからのオートスケーリングに対応しています (現在は Datadog で監視しているすべてのメトリクスに対応) 。

この投稿では Datadog のメトリクスによる Kubernetes のオートスケーリングを行う方法について、NGINX により報告されたメトリクスに基づいてワークロードをスケーリングする例を交えてご紹介します。また、DatadogMetric CRD を使用して、カスタマイズされた Datadog のメトリクスクエリに基づくワークロードのオートスケーリングを行う方法についても説明しています。

前提条件

はじめる前に、Kubernetes クラスターが v1.10+ (External Metrics Provider のリソースを Kubernetes の API サーバーに対して登録するため) を実行していることを確認してください。また、集計レイヤーの有効化も必要です。詳しい方法については Kubernetes のドキュメントを参照してください。

操作を続ける場合は、以下のことをご確認ください。

  • Datadog アカウントをお持ちであること (まだの場合はをお試しください)
  • Datadog Cluster Agent をお持ちであり、デプロイのマニフェストDD_EXTERNAL_METRICS_PROVIDER_ENABLED および DD_EXTERNAL_METRICS_PROVIDER_USE_DATADOGMETRIC_CRD の両方が true に設定されていること
  • 実行中 (DaemonSet の使用が理想的) のノードベースの Datadog Agents をお持ちで、オートディスカバリーが有効化および実行されていること。このステップで、本投稿で例として使用する NGINX メトリクスの収集を有効化します。
  • ノードベースの Agents が Cluster Agent と安全に通信するよう構成されていること (詳細はドキュメントをご覧ください)

4 つ目のポイントは必須ではありませんが、この操作により Datadog でノードベースの Agent により収集されたメタデータを使って Kubernetes メトリクスの加工を行う機能が有効化されます。Datadog メトリクスとクエリで Kubernetes のワークロードのオートスケーリングを行う方法の詳細は、本文で使用しているマニフェストおよびドキュメントを参照してください。

Datadog メトリクスでのオートスケーリング

External Metrics Provider の登録

上記の前提条件をすべて満たしていることを確認したら、いよいよ datadog-custom-metrics-server サービスを作成します。これにより Cluster Agent のデプロイの指定とポート 443 の公開を行います。

kubectl apply -f https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/hpa-example/cluster-agent-hpa-svc.yaml

このサービスを使用して以下の RBAC ルールを含むファイルを作成・適用し、高可用性 (HA) クラスターで Cluster Agent を External Metrics Provider として登録することができるようになりました。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:auth-delegator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: datadog-cluster-agent
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: datadog-cluster-agent
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
  name: datadog-cluster-agent
  namespace: default
---
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  name: v1beta1.external.metrics.k8s.io
spec:
  insecureSkipTLSVerify: true
  group: external.metrics.k8s.io
  groupPriorityMinimum: 100
  versionPriority: 100
  service:
    name: datadog-custom-metrics-server
    namespace: default
  version: v1beta1
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-metrics-reader
rules:
- apiGroups:
  - "external.metrics.k8s.io"
  resources:
  - "*"
  verbs:
  - list
  - get
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-metrics-reader
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-metrics-reader
subjects:
- kind: ServiceAccount
  name: horizontal-pod-autoscaler
  namespace: kube-system

以下の出力データに似た内容が画面に表示されるはずです。

clusterrolebinding.rbac.authorization.k8s.io/system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/datadog-cluster-agent created
apiservice.apiregistration.k8s.io/v1beta1.external.metrics.k8s.io created
clusterrole.rbac.authorization.k8s.io/external-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/external-metrics-reader created

実行中のポッドとサービスのリストを作成すると、次の結果が表示されます。

kubectl get pods,svc

PODS

NAMESPACE     NAME                                     READY     STATUS    RESTARTS   AGE
default       datadog-agent-7txxj                     4/4     Running             0          14m
default       datadog-cluster-agent-7b7f6d5547-cmdtc   1/1       Running   0          16m

SVCS:

NAMESPACE     NAME                            TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)         AGE
default       datadog-custom-metrics-server   ClusterIP   192.168.254.87    <none>        443/TCP         28m
default       datadog-cluster-agent           ClusterIP   192.168.254.197   <none>        5005/TCP        28m
default       datadog-cluster-agent-metrics-api   ClusterIP   10.96.248.49     <none>        8443/TCP   28m

水平ポッドオートスケーラーの作成

ここから、水平ポッドオートスケーラーのマニフェストを作成し、Datadog から Datadog Cluster Agent のメトリクスをクエリできるようにします。hpa-manifest.yaml のサンプルファイル を開くと、次の内容が表示されます。

  • HPA は nginx デプロイのオートスケーリングを行うように構成されています
  • 作成されるレプリカの最大数は 5 で、最小数は 1 です
  • HPA はスコープ kube_container_name: nginx に対してメトリクス nginx.net.request_per_s によるオートスケーリングを行います。この形式は Datadog のメトリクス名に対応しています

Kubernetes は 30 秒ごとに Datadog Cluster Agent に対して、毎秒リクエストされる NGINX メトリクスの値をクエリし、必要に応じて nginx デプロイのオートスケーリングを行います。高度なユースケースの場合は、複数のメトリクスに基づいて Kubernetes のオートスケーリングを行うことも可能です。この場合、オートスケーラーは最大数のレプリカを作成するメトリクスを選択します。Kubernetes が外部メトリクスの値をチェックする頻度も同じく構成することができます。

Datadog Cluster Agent で Kubernetes の負荷をリアルタイムでオートスケール。

オートスケーリング用の Kubernetes デプロイの作成

それでは、Kubernetes がオートスケーリングを行う NGINX デプロイを作成しましょう。

kubectl apply -f https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/hpa-example/nginx.yaml

次に、HPA マニフェストを適用します。

kubectl apply -f https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/hpa-example/hpa-manifest.yaml

NGINX ポッドが対応するサービスで実行されていることがわかるはずです。

kubectl get pods,svc,hpa

POD:

default       nginx-6757dd8769-5xzp2                   1/1       Running   0          3m

SVC:

NAMESPACE     NAME                  TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)         AGE
default       nginx                 ClusterIP   192.168.251.36    none          8090/TCP        3m


HPAS:

NAMESPACE   NAME       REFERENCE          TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
default     nginxext   Deployment/nginx   0/9 (avg)       1         5         1        3m

お使いの NGINX サービスの CLUSTER-IP をメモしておいてください。次のステップで必要となります。

サービスに負荷をかけて実行中の Kubernetes オートスケーリングを確認する

ここまでで、設定に負荷をかけ、Datadog Cluster Agent からの外部メトリクスに基づいて Kubernetes がどのように NGINX ポッドのオートスケーリングを行うのかを確認するための準備が整いました。

NGINX サービスの IP に cURL リクエストを送信します (NGINX_SVC を前のステップの CLUSTER-IP で置き換えます) 。

curl <NGINX_SVC>:8090/nginx_status

NGINX サーバーの統計を報告する簡単な応答を受信するはずです。

Active connections: 1 
server accepts handled requests
 1 1 1 
Reading: 0 Writing: 1 Waiting: 0 

バックエンドでは 1 秒あたりの NGINX リクエストの数も同じく増加しています。オートディスカバリーのおかげで、ノードベースの Agent は既にポッドで実行中の NGINX を検知しており、ポッドのアノテーションを使用して Agent のチェックを構成し、NGINX メトリクスの収集を開始します。

ポッドに負荷をかけると、Datadog アカウント内の 1 秒あたりのNGINX リクエストの割合が上昇することがわかります。HPA マニフェスト (hpa-manifest.yaml) でこのメトリクスを参照し、Datadog Cluster Agent を External Metrics Provider として登録しているため、Kubernetes は定期的に Cluster Agent にクエリを送信して nginx.net.request_per_s メトリクスの値を取得します。平均値が HPA マニフェスト内の targetAverageValue しきい値を超過した場合は、それに応じて NGINX ポッドのオートスケーリングが行われます。 実際の動きを見てみましょう。

以下のコマンドを実行します。

while true; do curl <NGINX_SVC>:8090/nginx_status; sleep 0.1; done

お使いの Datadog アカウント内で、1 秒あたりのリクエスト数が急上昇し、結果的に HPA マニフェストに羅列されているしきい値である 9 を超過することがわかります。Kubernetes でこのメトリクスがしきい値を超過したことが検知されると、NGINX ポッドのオートスケーリングが開始されます。ここで新しい NGINX ポッドの作成も行われます。

kubectl get pods,hpa

PODS:

NAMESPACE     NAME                                     READY     STATUS    RESTARTS   AGE
default       datadog-cluster-agent-7b7f6d5547-cmdtc   1/1       Running   0          9m
default       nginx-6757dd8769-5xzp2                   1/1       Running   0          2m
default       nginx-6757dd8769-k6h6x                   1/1       Running   0          2m
default       nginx-6757dd8769-xzhfq                   1/1     Running             0       2m
default       nginx-6757dd8769-j5zpx                   1/1     Running             0       2m
default       nginx-6757dd8769-vzd5b                   1/1       Running   0          29m

HPAS:

NAMESPACE   NAME       REFERENCE          TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
default     nginxext   Deployment/nginx   30/9 (avg)     1         5         5         29m

Datadog ダッシュボードとアラートを使用して Kubernetes のオートスケーリング アクティビティをリアルタイムで追跡することができます。ワークロードを適切に反映した形でしきい値が構成されているかも確認してください。1 秒あたりの NGINX リクエストの平均レートがオートスケーリングのしきい値を超えたら、Kubernetes はポッドの数を HPA マニフェストで指定した希望するレプリカの数 (maxReplicas: 5) に合わせてスケーリングを行います。

Datadog Cluster Agent による Kubernetes のオートスケーリング、水平ポッドオートスケーリング、および外部メトリクスプロバイダー

カスタム Datadog クエリに基づくオートスケーリング

Cluster Agent バージョン 1.7.0 のリリースにより、カスタマイズされたメトリクスクエリに基づいて Kubernetes のワークロードのオートスケーリングができるようになりました。カスタムクエリに基づくオートスケーリングの前提条件は、この投稿で先述した前提条件と同じです。また、datadog-custom-metrics-server をインストールして Cluster Agent を External Metrics Provider として登録したことも確認してください。

算術演算と関数を使用してメトリクスクエリをカスタマイズすることで、ある一定のユースケースに向けたシステムの柔軟性を高めることができます。たとえば、以下のクエリを使用して、ポッドがあとどれぐらいで CPU の制限を超過するかを決定することもできます。

avg:kubernetes.cpu.usage.total{app:foo}.rollup(avg,30)/(avg:kubernetes.cpu.limits{app:foo}.rollup(avg,30)*1000000000)

このクエリに応答したスケーリングを行うことで、パフォーマンスの悪化につながる CPU のスロットリングを回避することができます。(kubernetes.cpu.usage.total はナノコアで測定されるため、1,000,000,000 掛けしていることにご注意ください。kubernetes.cpu.limits ではコアが使用されます。)

このセクションでは、上記のステップで作成したのと同じ NGINX デプロイのオートスケーリング方法を用いた、DatadogMetric CRD 向けの別のユースケースをご紹介します。毎秒リクエストされる NGINX メトリクスの最大値に対してデプロイのオートスケーリングを行い、トラフィックが予期せず急上昇していないことを確認します。

DatadogMetric CRD を使用する場合の Cluster Agent の構成

Datadog のクエリに応答する形で Cluster Agent のスケーリングを構成するために、クラスターに DatadogMetric CRD をインストールする必要があります。

kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-operator/master/deploy/crds/datadoghq.com_datadogmetrics_crd.yaml"

Datadog Cluster Agent RBAC マニフェストを更新し、DatadogMetric CRD の使用を許可します。

kubectl apply -f "https://raw.githubusercontent.com/DataDog/datadog-agent/master/Dockerfiles/manifests/cluster-agent-datadogmetrics/cluster-agent-rbac.yaml"

次に進む前に、cluster-agent-deployment.yaml ファイル内の DD_EXTERNAL_METRICS_PROVIDER_USE_DATADOGMETRIC_CRD 変数が true に設定されていることをご確認ください。値が異なる場合は調整し、ファイルを再度適用する必要があります。

HPA への DatadogMetric の追加

準備が整ったところで、DatadogMetric リソースを作成して HPA に追加します。DatadogMetric はネームスペース規則のリソースです。HPA はあらゆる DatadogMetric を参照できますが、HPA と同じネームスペースで作成することをおすすめします。これを行うには、以下のコードでマニフェストを作成して適用します。

apiVersion: datadoghq.com/v1alpha1
kind: DatadogMetric
metadata:
  name: nginx-requests
spec:
  query: max:nginx.net.request_per_s{kube_container_name:nginx}.rollup(60)

マニフェスト内のこのクエリ (max:nginx.net.request_per_s{kube_container_name:nginx}.rollup(60)) は 1 秒あたりに受信した NGINX リクエストの最大数をチェックします ( .rollup() function を使用して、60 秒間隔を超えたメトリクスの最大値を収集) 。

それでは、更新版の hpa-manifest.yaml ファイルを作成・適用して、前回の例で使用した NGINX メトリクスの代わりに新しく作成した DatadogMetric リソースを参照します。metricName の値は datadogmetric@default:nginx-requests に設定する必要があります (default はネームスペースを表します) 。metricSelector は削除することもできます。新しい hpa-manifest.yaml ファイルは以下のようになります。

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: nginxext
spec:
  minReplicas: 1
  maxReplicas: 5
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  metrics:
  - type: External
    external:
      metricName: datadogmetric@default:nginx-requests
      targetAverageValue: 9

DatadogMetric リソースを HPA に接続したら、Datadog Cluster Agent がカスタムクエリを使用して適宜 NGINX デプロイのスケーリングを開始します。

Datadog による Kubernetes のオートスケーリング

この投稿では Datadog Cluster Agent を利用して、リアルタイムのワークロードに基づき Kubernetes アプリケーションのオートスケーリングを手軽に行う方法についてご紹介してきました。クラスターのどこからでもメトリクスに基づくスケーリングを行えるだけでなく、クラウドサービス (Amazon RDS や AWS ELB など) からのメトリクスを使用してデータベース、キャッシュ、ロードバランサーのオートスケーリングが可能となるなど、大きな可能性を秘めた注目の機能です。

Datadog で既に Kubernetes の監視を行っている場合は、(こちらの説明に従って) すぐに Cluster Agent をデプロイし、Datadog アカウントで利用可能なあらゆるメトリクスやカスタム Datadog メトリクスクエリに基づくアプリケーションのオートスケーリングを行うことができます。Datadog をまだご利用でない場合は、をお試しください。