ArgoCD を使用した DatadogPodAutoscaler の管理

概要

DatadogPodAutoscaler (DPA) は、Datadog Kubernetes Autoscaling (DKA) を使用して Kubernetes ワークロードのオートスケーリングを可能にする Kubernetes カスタムリソース定義 (CRD) です。このガイドでは、ArgoCD と GitOps の原則を使用して DatadogPodAutoscaler リソースを管理し、オートスケーリング構成をデプロイする方法を説明します。

ArgoCD は、Kubernetes の宣言型 GitOps 継続的デリバリーツールです。Kubernetes マニフェストを含む Git リポジトリをモニターし、Git で定義された望ましい状態とクラスターを同期させます。このアプローチは、バージョン管理、監査証跡、およびオートスケーリングインフラストラクチャーの自動デプロイを提供します。

大規模なオートスケーリングの有効化: 共有ポリシーで多くのワークロードやネームスペースにオートスケーリングを展開するには、ワークロードごとに 1 つの DatadogPodAutoscaler を作成するのではなく、autoscaling.datadoghq.com/profile でワークロードやネームスペースにラベルを付けます。Kubernetes Autoscaling の概要にあるクラスタープロファイルを参照してください。

前提条件

始める前に、以下があることを確認します。

  • Kubernetes クラスター: kubectl を使用してアクセスできる稼働中の Kubernetes クラスター (1.20 以降)
  • ArgoCD インストール済み: クラスターにデプロイされ、CLI または UI 経由でアクセスできる ArgoCD
  • Datadog API 資格情報: 有効な Datadog API キーおよびアプリケーションキー
  • Git リポジトリ: マニフェストを保存するための Git リポジトリ

プロジェクト構造

このガイドでは、適切な依存関係の作成とデプロイメントの順序を確実にするため、ArgoCD 同期ウェーブで App of Apps パターンを使用します。

.
├── argocd/
   ├── root-app.yaml              # App of Apps controller
   └── apps/
       ├── datadog-operator.yaml  # ArgoCD Application for Operator
       ├── datadog-agent.yaml     # ArgoCD Application for Agent
       └── nginx-dka-demo.yaml    # ArgoCD Application for workload
├── manifests/
   └── stage2-agent/
       └── datadog-agent.yaml     # DatadogAgent custom resource
└── charts/
    └── nginx-dka-demo/
        ├── Chart.yaml
        ├── values.yaml
        └── templates/
            ├── deployment.yaml
            └── pod-autoscaler.yaml

デプロイメントステージ

Kubernetes カスタムリソース定義 (CRD) および ArgoCD を使用する際には、マルチステージデプロイメントアプローチが不可欠です。この順序付けられたアプローチは、プロセスの各ステージに必要な依存関係を確実に作成およびインストールするために必要です。

Kubernetes CRD を使用するカスタムリソースを作成するには、まずクラスターに Kubernetes CRD をインストールする必要があります。DatadogPodAutoscaler CRD は、ステージ 1 で Datadog Operator をインストールすると作成されます。ArgoCD は、これらの CRD が存在していなければそれらに依存するリソースを正常に同期できません。

ArgoCD は、アノテーションを通じてデプロイメントの順序を制御するために同期ウェーブを使用します。同期ウェーブは昇順 (低い番号が先) で実行され、ArgoCD は次のウェーブに進む前にウェーブ内のすべてのリソースが正常であることを確認します。

  1. ステージ 1 (ウェーブ 0): Helm を使用した Datadog Operator (CRD を作成)
  2. ステージ 2 (ウェーブ 1): Datadog Kubernetes Autoscaling 用に構成された Datadog Agent
    • オートスケーリング要件が有効な DatadogAgent カスタムリソース
  3. ステージ 3 (ウェーブ 2): DatadogPodAutoscaler を使用したアプリケーションワークロード
    • デモネームスペース内の NGINX デプロイメント
    • NGINX のデプロイメントのオートスケーリング用 DatadogPodAutoscaler リソース

構成ファイルをセットアップする

まず、Git リポジトリを作成します。ArgoCD は Git からマニフェストを取得するため、ArgoCD Application のすべての repoURL 参照をリポジトリを指すように更新する必要があります。

プロセスの各ステージに対して以下の構成ファイルをセットアップします。

ステージ 1: ルートアプリケーション (App of Apps)

ルートアプリケーションは、すべての子アプリケーションを管理する App of Apps コントローラーです。

argocd/root-app.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: dka-root
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://example.com/YOUR-USERNAME/dka-argocd-example
    targetRevision: HEAD
    path: argocd/apps
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

ステージ 2: Datadog Operator アプリケーション

この ArgoCD アプリケーションは、Helm を使用して Datadog Operator をデプロイします。これにより、必要な CRD が作成されます。

argocd/apps/datadog-operator.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: datadog-operator
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "0"
spec:
  project: default
  source:
    repoURL: https://helm.datadoghq.com
    targetRevision: 2.18.1
    chart: datadog-operator
  destination:
    server: https://kubernetes.default.svc
    namespace: datadog
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true

ステージ 3: Datadog Agent アプリケーション

この ArgoCD アプリケーションは、DatadogAgent カスタムリソースをデプロイします。

argocd/apps/datadog-agent.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: datadog-agent
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "1"
spec:
  project: default
  source:
    repoURL: https://example.com/YOUR-USERNAME/dka-argocd-example
    targetRevision: HEAD
    path: manifests/stage2-agent
  destination:
    server: https://kubernetes.default.svc
    namespace: datadog
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

DatadogAgent カスタムリソースマニフェストを作成します。

manifests/stage2-agent/datadog-agent.yaml

apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
  name: datadog
  namespace: datadog
spec:
  features:
    autoscaling:
      workload:
        enabled: true
    eventCollection:
      unbundleEvents: true
  global:
    site: datadoghq.com
    credentials:
      apiSecret:
        secretName: datadog-secret
        keyName: api-key
      appSecret:
        secretName: datadog-secret
        keyName: app-key
    clusterName: minikube-dka-demo
    kubelet:
      tlsVerify: false
  override:
    clusterAgent:
      env:
        - name: DD_AUTOSCALING_FAILOVER_ENABLED
          value: "true"
    nodeAgent:
      env:
        - name: DD_AUTOSCALING_FAILOVER_ENABLED
          value: "true"

ステージ 4: DatadogPodAutoscaler を使用した NGINX アプリケーション

この ArgoCD アプリケーションは、Helm チャートを使用して DatadogPodAutoscaler を持つ NGINX ワークロードをデプロイします。

argocd/apps/nginx-dka-demo.yaml

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-dka-demo
  namespace: argocd
  annotations:
    argocd.argoproj.io/sync-wave: "2"
spec:
  project: default
  source:
    repoURL: https:/example.com/YOUR-USERNAME/dka-argocd-example
    targetRevision: HEAD
    path: charts/nginx-dka-demo
  destination:
    server: https://kubernetes.default.svc
    namespace: nginx-dka-demo
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - RespectIgnoreDifferences=true
  ignoreDifferences:
    - group: apps
      kind: Deployment
      name: nginx
      namespace: nginx-dka-demo
      managedFieldsManagers:
        - datadog-cluster-agent

ignoreDifferences エントリは RespectIgnoreDifferences=true とペアになり、ArgoCD に Datadog Cluster Agent がオートスケールされたワークロードに適用する変更を元に戻さないよう指示します。managedFieldsManagers フォームは Kubernetes のサーバーサイド適用フィールド所有権を活用するため、Datadog Cluster Agent が所有する任意のフィールド (レプリカ、autoscaling.datadoghq.com/ のアノテーション、コンテナリソース) は自動的に保持されます。詳しい理由やグローバル構成の代替案については、Datadog Cluster Agent がオートスケールされたワークロードを更新することを許可するを参照してください。

NGINX アプリケーションの Helm チャートを作成します。

charts/nginx-dka-demo/Chart.yaml

apiVersion: v2
name: nginx-dka-demo
description: NGINX demo application with DatadogPodAutoscaler
type: application
version: 0.1.0
appVersion: "1.0"

charts/nginx-dka-demo/values.yaml

replicaCount: 3

image:
  repository: nginx
  tag: latest
  pullPolicy: IfNotPresent

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

service:
  type: ClusterIP
  port: 80

autoscaler:
  enabled: true
  minReplicas: 3
  maxReplicas: 100
  targetCPUUtilization: 70
  scaleUp:
    rules:
      - type: Percent
        value: 50
        periodSeconds: 120
    stabilizationWindowSeconds: 600
    strategy: Max
  scaleDown:
    rules:
      - type: Percent
        value: 20
        periodSeconds: 1200
    stabilizationWindowSeconds: 600
    strategy: Max

charts/nginx-dka-demo/templates/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: nginx-dka-demo
  labels:
    app: nginx
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: 80
        resources:
          {{- toYaml .Values.resources | nindent 10 }}
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: nginx-dka-demo
spec:
  selector:
    app: nginx
  ports:
  - port: {{ .Values.service.port }}
    targetPort: 80
  type: {{ .Values.service.type }}

charts/nginx-dka-demo/templates/pod-autoscaler.yaml

{{- if .Values.autoscaler.enabled }}
apiVersion: datadoghq.com/v1alpha2
kind: DatadogPodAutoscaler
metadata:
  name: nginx
  namespace: nginx-dka-demo
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  owner: Local
  constraints:
    minReplicas: {{ .Values.autoscaler.minReplicas }}
    maxReplicas: {{ .Values.autoscaler.maxReplicas }}
    containers:
    - name: nginx
      enabled: true
  objectives:
  - type: PodResource
    podResource:
      name: cpu
      value:
        type: Utilization
        utilization: {{ .Values.autoscaler.targetCPUUtilization }}
  applyPolicy:
    mode: Apply
    update:
      strategy: Auto
    scaleUp:
      strategy: {{ .Values.autoscaler.scaleUp.strategy }}
      stabilizationWindowSeconds: {{ .Values.autoscaler.scaleUp.stabilizationWindowSeconds }}
      rules:
      {{- toYaml .Values.autoscaler.scaleUp.rules | nindent 6 }}
    scaleDown:
      strategy: {{ .Values.autoscaler.scaleDown.strategy }}
      stabilizationWindowSeconds: {{ .Values.autoscaler.scaleDown.stabilizationWindowSeconds }}
      rules:
      {{- toYaml .Values.autoscaler.scaleDown.rules | nindent 6 }}
{{- end }}

Datadog Cluster Agent がオートスケールされたワークロードを更新することを許可する

applyPolicy.mode: ApplyDatadogPodAutoscaler に設定されている場合、Datadog Cluster Agent はターゲットワークロードを直接変更します。spec.replicas、コンテナリソースを更新し、autoscaling.datadoghq.com/ プレフィックスの下にアノテーションを書き込み、その推奨事項と適用状態を追跡します。追加の ArgoCD 構成がない場合、ArgoCD はこれらの変更をドリフトと解釈し、selfHeal: true が有効な場合、毎回の同期でそれらを元に戻します。これにより、ArgoCD とオートスケーラーの間に競合が発生します。

この競合を防ぐ方法は 2 つあります。

  • アプリケーションごと: オートスケールされたワークロードを含む各 ArgoCD ApplicationignoreDifferencesRespectIgnoreDifferences=true を追加します。これは上記の ステージ 4 に示されています。
  • グローバル:argocd-cm を一度構成すれば ignoreDifferences ルールがインスタンス内のすべてのアプリケーションに適用されます。

サポートされているターゲットワークロードの種類

ignoreDifferences 構成は、DatadogPodAutoscalerspec.targetRef を通じてターゲットにできるすべてのワークロードの種類をカバーする必要があります。

ワークロードの種類API グループ
Deploymentapps
StatefulSetapps
Rolloutargoproj.ioArgo Rollouts も実行している場合にのみ適用

アプリケーションごとの構成

クラスター内でサーバー側の適用がアクティブかどうかに応じて、次のバリアントのいずれかを選択します。

managedFieldsManagers アプローチは、Datadog Cluster Agent が所有するすべてのフィールド (spec.replicas、コンテナリソース、およびすべてのアノテーション) を個別に列挙することなくカバーします。

syncPolicy:
  automated:
    prune: true
    selfHeal: true
  syncOptions:
    - RespectIgnoreDifferences=true
ignoreDifferences:
  - group: apps
    kind: Deployment
    managedFieldsManagers:
      - datadog-cluster-agent
  - group: apps
    kind: StatefulSet
    managedFieldsManagers:
      - datadog-cluster-agent
  - group: argoproj.io
    kind: Rollout
    managedFieldsManagers:
      - datadog-cluster-agent

これは、上記のステージ 4 の例で使用されるアプローチです。各アプリケーションに存在するワークロードタイプの kind エントリのみを含めます。

バリアント 2: jqPathExpressions (クライアント側の適用で動作)

jqPathExpressions アプローチは、autoscaling.datadoghq.com/ で始まるアノテーションのみを明示的にターゲットにし、クライアント側の適用と互換性があります。ServerSideApply=true が現在の環境で利用できない場合は、このバリアントを使用します。

syncPolicy:
  automated:
    prune: true
    selfHeal: true
  syncOptions:
    - RespectIgnoreDifferences=true
ignoreDifferences:
  - group: apps
    kind: Deployment
    jqPathExpressions:
      - .metadata.annotations | to_entries[] | select(.key | startswith("autoscaling.datadoghq.com")) | .key
      - .spec.template.metadata.annotations | to_entries[] | select(.key | startswith("autoscaling.datadoghq.com")) | .key
  - group: apps
    kind: StatefulSet
    jqPathExpressions:
      - .metadata.annotations | to_entries[] | select(.key | startswith("autoscaling.datadoghq.com")) | .key
      - .spec.template.metadata.annotations | to_entries[] | select(.key | startswith("autoscaling.datadoghq.com")) | .key
  - group: argoproj.io
    kind: Rollout
    jqPathExpressions:
      - .metadata.annotations | to_entries[] | select(.key | startswith("autoscaling.datadoghq.com")) | .key
      - .spec.template.metadata.annotations | to_entries[] | select(.key | startswith("autoscaling.datadoghq.com")) | .key

**制限:**このバリアントは autoscaling.datadoghq.com/ アノテーションのみをカバーします。オートスケーラーが spec.replicas またはコンテナリソースリクエストを変更する場合は、それらのフィールドに対して別々の jqPathExpressions エントリを追加します。バリアント 1 (managedFieldsManagers) は、Cluster Agent が所有するすべてのフィールドを自動的にカバーすることでこのギャップを回避します。

グローバルコンフィギュレーション

ArgoCD インスタンス内のすべてのアプリケーションに ignoreDifferences を一度適用するには、resource.customizations.ignoreDifferences.<group>_<kind> キーを使用して argocd-cm ConfigMap を構成します。

ConfigMap (kubectl または Kustomize インストール)

argocd-cm patch

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  resource.customizations.ignoreDifferences.apps_Deployment: |
    managedFieldsManagers:
      - datadog-cluster-agent
  resource.customizations.ignoreDifferences.apps_StatefulSet: |
    managedFieldsManagers:
      - datadog-cluster-agent
  resource.customizations.ignoreDifferences.argoproj.io_Rollout: |
    managedFieldsManagers:
      - datadog-cluster-agent

ArgoCD Helm チャートの値

公式の argo/argo-cd Helm チャートを使用して ArgoCD をデプロイするユーザーについては、configs.cmの下に同じキーを追加します。

values.yaml

configs:
  cm:
    resource.customizations.ignoreDifferences.apps_Deployment: |
      managedFieldsManagers:
        - datadog-cluster-agent
    resource.customizations.ignoreDifferences.apps_StatefulSet: |
      managedFieldsManagers:
        - datadog-cluster-agent
    resource.customizations.ignoreDifferences.argoproj.io_Rollout: |
      managedFieldsManagers:
        - datadog-cluster-agent

以下で値を適用します。

helm upgrade --install argocd argo/argo-cd -f values.yaml -n argocd

重要: RespectIgnoreDifferences はアプリケーションごとに引き続き必要

グローバル ignoreDifferences 構成は ArgoCD UI での diff 表示を抑制するだけです。ArgoCD が同期中にそれらのフィールドを上書きするのを防ぐことはありません。オートスケールされたワークロードを含む各アプリケーションは、RespectIgnoreDifferences=truesyncOptionsで設定する必要があります。この同期オプションのグローバルな同等物はありません。

各アプリケーションに個別に RespectIgnoreDifferences=true を設定するのを避けるため、プロジェクト内のすべてのアプリケーションがそれを継承するように AppProject レベルで定義します。

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: default
  namespace: argocd
spec:
  syncPolicy:
    syncOptions:
      - RespectIgnoreDifferences=true

または、ApplicationSet テンプレートを使用して、すべての生成されたアプリケーションに自動的に同期オプションを追加します。

使用するオプション

  • いくつかのオートスケールされたワークロード: アプリケーションごとの構成を使用します。構成はワークロードと同じ場所に保持されます。
  • 多くのワークロードまたは ArgoCD 全体の標準化: グローバル構成をプロジェクトレベルまたは ApplicationSet レベルの RespectIgnoreDifferences=true と組み合わせて使用します。
  • 混合環境 (すべてのワークロードがオートスケールされているわけではない): グローバル構成はインスタンス全体に適用するのが安全です。managedFieldsManagers ルールは、Datadog Cluster Agent フィールドの所有権がないワークロードに対しては動作しません。

デプロイメント手順

構成ファイルを設定して Git リポジトリにプッシュした後、ArgoCD を使用してコンポーネントをデプロイするための手順に従います。

Datadog シークレットを作成する

datadog ネームスペースに Datadog API キーとアプリケーションキーを含む Kubernetes シークレットを作成します。

kubectl create namespace datadog
kubectl create secret generic datadog-secret \
  --from-literal=api-key=YOUR_API_KEY \
  --from-literal=app-key=YOUR_APP_KEY \
  -n datadog

ルートアプリケーションをデプロイする

App of Apps パターンを使用してすべての子アプリケーションを管理するルートアプリケーションをデプロイします。

kubectl apply -f argocd/root-app.yaml

ArgoCD は現在、Git リポジトリをモニターし、同期ウェーブに基づいてすべてのアプリケーションを正しい順序で自動的にデプロイします。

Datadog のクラスターでオートスケーリングを有効にする

Datadog UI の オートスケーリング設定ページに移動して、クラスターのオートスケーリングを有効にします。

同期ウェーブの進行状況を確認する

ArgoCD アプリケーションが順番に同期することを確認します。

kubectl get applications -n argocd

すべてのアプリケーションが表示され、ウェーブ順に同期することを確認できるはずです。datadog-operator (ウェーブ 0)、次に datadog-agent (ウェーブ 1)、その後 nginx-dka-demo (ウェーブ 2)。

デプロイメントを検証する

Datadog Operator と CRD がデプロイされていることを確認します。

kubectl get crd | grep datadoghq
kubectl get pods -n datadog

Datadog CRD が作成され、datadog-operator Pod が実行されていることを確認できるはずです。

Datadog Agent がデプロイされていることを確認します。

kubectl get datadogagent -n datadog

Running 状態で Datadog Agent のカスタムリソースが作成されていることが確認できるはずです。また、Datadog Agent と datadog-cluster-agent ポッドが実行中であることも確認します。

kubectl get pods -n datadog

DatadogPodAutoscaler のステータスをチェックします。

kubectl get datadogpodautoscaler -n nginx-dka-demo
kubectl describe datadogpodautoscaler nginx -n nginx-dka-demo

おめでとうございます。GitOps を使用して Datadog Kubernetes Autoscaler によって管理されているワークロードがあります。

クリーンアップ

すべてのリソースを削除するには、ルートアプリケーションを削除します。この削除はすべての子アプリケーションに連鎖します。

kubectl delete application dka-root -n argocd

または、アプリケーションを逆の順序で個別に削除します。

kubectl delete application nginx-dka-demo -n argocd
kubectl delete application datadog-agent -n argocd
kubectl delete application datadog-operator -n argocd

Datadog シークレットを削除します。

kubectl delete secret datadog-secret -n datadog

トラブルシューティング

ArgoCD の同期障害

アプリケーションステータスと同期エラーをチェックします。

kubectl describe application datadog-operator -n argocd
kubectl describe application datadog-agent -n argocd
kubectl describe application nginx-dka-demo -n argocd

ArgoCD アプリケーションコントローラーのログを表示します。

kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller

CRD の可用性の問題

ArgoCD が CRD を認識できずに同期に失敗した場合、ウェーブ 0で Datadog Operator が正常にデプロイされていることを確認します。

kubectl get crd | grep datadoghq
kubectl get pods -n datadog

同期ウェーブのアノテーションは適切な順序を保証しますが、アプリケーションを手動で更新することもできます。

argocd app sync datadog-agent

シークレットの構成に関する問題

Datadog のシークレットが存在し、正しいキーを含んでいることを確認します。

kubectl get secret datadog-secret -n datadog
kubectl describe secret datadog-secret -n datadog

シークレットには api-keyapp-key のフィールドが含まれている必要があります。

DatadogPodAutoscaler イベント

スケーリングの決定やエラーについては DatadogPodAutoscaler イベントをチェックします。

kubectl get events -n nginx-dka-demo --sort-by='.lastTimestamp'

オートスケールされたワークロードが繰り返し元に戻す

selfHeal: true が有効な場合、ArgoCD は約 3 分ごとに同期します。オートスケールされたワークロードの spec.replicas または autoscaling.datadoghq.com/ のアノテーションが繰り返しリセットされる場合、次のいずれかを確認します。

  1. RespectIgnoreDifferences=true はアプリケーションの syncOptions から欠落しています。このフラグがないと、ArgoCD は UI でのドリフトを隠すだけで、適用中にフィールドを上書きします。
  2. この ignoreDifferences エントリはワークロードと一致しません。groupkindname、および namespace がエントリ内でターゲットワークロードと正確に一致していることを確認します。
  3. ServerSideApply=trueは、managedFieldsManagers を使用している場合には設定されていません。サーバー側の適用がない場合、Kubernetes はフィールド所有権データベースを更新しないため、マネージャー名を一致させることができません。

サーバー側の適用がアクティブかどうか、また特定のフィールドを所有しているマネージャーを確認するには、次のコマンドを実行します。

kubectl get deployment <name> -n <namespace> -o yaml --show-managed-fields

manager: datadog-cluster-agentoperation: Apply があるエントリを探します。そのリソースに対してそのようなエントリが存在しない場合、サーバー側の適用はアクティブではありません。

Cluster Agent のログ

Cluster Agent のログでオートスケーリングに関連するメッセージをチェックします。

kubectl logs -n datadog -l agent.datadoghq.com/component=cluster-agent

参考資料