カスタム指標でのデプロイの自動スケーリング

このチュートリアルでは、Kubernetes Pod によって Stackdriver にエクスポートされたカスタム指標に基づいて、GKE ワークロードを自動スケーリングする方法を紹介します。 Stackdriver で使用可能な他の指標に基づいてワークロードを自動スケーリングする方法については、外部指標を使用した Deployment の自動スケーリングをご覧ください。

目標

GKE でカスタム指標による自動スケーリングを設定するには、次の操作を行う必要があります。

  1. カスタム指標 Stackdriver アダプタをデプロイします。
  2. カスタム指標を Stackdriver にエクスポートします。
  3. HorizontalPodAutoscaler(HPA)リソースをデプロイして、カスタム指標に基づいて Deployment をスケーリングします。

始める前に

次の手順で Kubernetes Engine API を有効にします。
  1. Google Cloud Console で Kubernetes Engine ページにアクセスします。
  2. プロジェクトを作成または選択します。
  3. API と関連サービスが有効になるのを待ちます。 これには数分かかることがあります。
  4. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。 プロジェクトに対して課金が有効になっていることを確認する方法を学習する

このチュートリアルで使用されている以下のコマンドライン ツールをインストールします。

  • gcloud は、Kubernetes Engine クラスタの作成と削除に使用されます。gcloud は、Google Cloud SDK に含まれています。
  • kubectl は、Kubernetes Engine で使用されるクラスタ オーケストレーション システムである Kubernetes の管理に使用されます。gcloud を使用して kubectl をインストールできます。
    gcloud components install kubectl

gcloud コマンドライン ツールのデフォルトの設定

次のようにしてデフォルト値を設定しておくと、gcloud コマンドライン ツールでプロジェクト ID および Compute Engine ゾーン オプションを入力する時間が節約されます。
    gcloud config set project [PROJECT_ID]
    gcloud config set compute/zone [COMPUTE_ENGINE_ZONE]

クラスタの作成とモニタリングの設定

カスタム指標の選択

カスタム指標による自動スケーリングには、次の 2 つの方法があります。

  • Deployment の中のすべての Pod からカスタム指標をエクスポートし、Pod あたりの平均値を目標にすることが可能です。
  • Deployment の外部の単一の Pod からカスタム指標をエクスポートし、合計値を目標にすることができます。

1 つの Deployment では、指定された制限内で、指標値に基づいて複製 Pod をスケーリングできます。合計目標値を伴う指標は、常に、スケーリングによって指標値が目標値に近づくように定義される必要があります。

たとえば、1 秒あたりのクエリ数の指標に基づいてフロントエンド アプリケーションをスケーリングする場合を考えみましょう。指標値が増加したとき、各 Pod で処理するトラフィック量は以前とほぼ同じままで、Pod 数を増やす必要があります。各 Pod の秒間クエリ数をエクスポートし、適切な目標平均値を設定することにより、望ましい動作が得られます。しかし、秒間クエリ数の合計をエクスポートしてこの指標の合計目標値を設定しても、この場合は望ましい動作が得られません。Pod の数を増やしてもトラフィックの総量は減少しないためです。

ユースケースに応じて、平均リクエスト レイテンシなどの他の指標を合計目標値とともに直接使用して Deployment をスケーリングできます。

ステップ 1: カスタム指標 Stackdriver アダプタをデプロイする

Stackdriver に格納されている指標へのアクセスを GKE オブジェクトに許可するには、カスタム指標 Stackdriver アダプタをデプロイする必要があります。カスタム指標アダプタを実行するには、次のコマンドを実行して、必要な承認の役割を作成する権限をユーザーに付与する必要があります。

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin --user "$(gcloud config get-value account)"
    

クラスタでアダプタをデプロイするには、次のコマンドを実行します。

    kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter.yaml
    

ステップ 2: 指標を Stackdriver にエクスポートする

指標を Stackdriver にエクスポートするには、アプリケーションから直接エクスポートするか、Prometheus 形式で指標を公開して Pod のコンテナに Prometheus-to-Stackdriver アダプタを追加します。

Metrics Explorer で custom/[METRIC_NAME]custom/foo など)を検索すると、エクスポートした指標を確認できます。

Metrics Explorer を使用してモニタリング対象リソースの指標を表示する方法は次のとおりです。

  1. Google Cloud Console で [モニタリング] を選択するか、次のボタンを使用します。
    [モニタリング] に移動
  2. [Monitoring] のナビゲーション パネルで、 [Metrics Explorer] をクリックします。
  3. モニタリング対象リソースの名前を [Find resource type and metric] テキスト ボックスに入力します。

アプリケーションからの指標のエクスポート

カスタム指標を作成し、それらをアプリケーション コードから Stackdriver に直接エクスポートできます。詳細については、Stackdriver Monitoring のドキュメントのカスタム指標の作成をご覧ください。また、Stackdriver のカスタム指標の自動作成機能を利用することもできます。

指標は、次の要件を満たす必要があります。

  • 指標の種類は GAUGE でなければなりません。
  • 指標の型は、DOUBLE または INT64 のいずれかです。
  • 指標名は、接頭部 custom.googleapis.com/ の後に単純な名前を付けたものでなければなりません。
  • リソースタイプは "gke_container" にする必要があります。
  • リソースラベルには、次のものが含まれていなければなりません。
    • pod_id。Pod UID に設定します。Pod UID は Downward API で取得できます。
    • container_name = ""
    • project_idzonecluster_name。アプリケーションでメタデータ サーバーから取得できます。値を取得するには、Google Cloud のコンピューティング メタデータ クライアントを使用できます。
    • namespace_idinstance_id。任意の値に設定できます。

次のマニフェスト ファイルで記述される Deployment は、Stackdriver クライアント ライブラリを使って指標をエクスポートする Go アプリケーションの単一インスタンスを実行します。

apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: custom-metric-sd
      name: custom-metric-sd
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: custom-metric-sd
      template:
        metadata:
          labels:
            run: custom-metric-sd
        spec:
          containers:
          - command: ["./direct-to-sd"]
            args: ["--metric-name=foo", "--metric-value=40", "--pod-id=$(POD_ID)"]
            image: gcr.io/google-samples/sd-dummy-exporter:latest
            name: sd-dummy-exporter
            resources:
              requests:
                cpu: 100m
            env:
              - name: POD_ID
                valueFrom:
                  fieldRef:
                    apiVersion: v1
                    fieldPath: metadata.uid

Prometheus を使用したエクスポート

アプリケーションの指標を Prometheus 形式で公開し、Prometheus-to-Stackdriver アダプタをデプロイできます。これにより、指標が収集されて Stackdriver にエクスポートされます。Prometheus 形式で指標を公開する例については、Kubernetes インストゥルメンテーション ガイドをご覧ください。

指標は、次の要件を満たす必要があります。

  • 指標タイプは Gauge でなければなりません
  • 指標名に接頭部 custom.googleapis.com を含めないでください

指標のエクスポート元の Pod 内に Prometheus-to-Stackdriver アダプタをコンテナとしてデプロイし、次のフラグをコンテナに渡します。

  • pod-idnamespace-id: Pod UID と名前空間 UID にそれぞれ設定します。これらの UID は Downward API で取得できます。
  • source=http://localhost:[PORT][PORT] は指標が公開されるポートです。
  • stackdriver-prefix=custom.googleapis.com

次のマニフェスト ファイルで記述される Pod には、Prometheus クライアント ライブラリとアダプタ コンテナを使用して指標を公開する Go アプリケーションが含まれます。

apiVersion: v1
    kind: Pod
    metadata:
      name: custom-metric-prometheus-sd
    spec:
      containers:
      - command:
        - /bin/sh
        - -c
        - ./prometheus-dummy-exporter --metric-name=foo --metric-value=40 --port=8080
        image: gcr.io/google-samples/prometheus-dummy-exporter:latest
        imagePullPolicy: Always
        name: prometheus-dummy-exporter
        resources:
          requests:
            cpu: 100m
      - name: prometheus-to-sd
        image: gcr.io/google-containers/prometheus-to-sd:v0.5.0
        command:
        - /monitor
        - --source=:http://localhost:8080
        - --stackdriver-prefix=custom.googleapis.com
        - --pod-id=$(POD_ID)
        - --namespace-id=$(POD_NAMESPACE)
        env:
        - name: POD_ID
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.uid
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace

ステップ 3: HorizontalPodAutoscaler オブジェクトを作成する

指標を Stackdriver にエクスポートしたら、次に HPA をデプロイすることで、指標に基づいて Deployment をスケーリングできます。

指標を収集してエクスポートするためにどんな方法を選んだかによって、以下の手順は異なります。

すべての Pod の指標に基づく自動スケーリング

HPA は、指標を使用して平均値を計算し、それを目標平均値と比較します。

アプリケーションから Stackdriver へのエクスポートの例では、指標をエクスポートする Pod が Deployment に含まれています。次のマニフェスト ファイルは、指標の平均目標値に基づいて Deployment をスケーリングする HorizontalPodAutoscaler オブジェクトを記述しています。

apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    metadata:
      name: custom-metric-sd
      namespace: default
    spec:
      scaleTargetRef:
        apiVersion: apps/v1beta1
        kind: Deployment
        name: custom-metric-sd
      minReplicas: 1
      maxReplicas: 5
      metrics:
      - type: Pods
        pods:
          metricName: foo
          targetAverageValue: 20

単一 Pod の指標に基づく自動スケーリング

HPA は、単一 Pod によって公開された値を、指定された目標値と直接比較します。この Pod を、スケーリングされるワークフローにバインドする必要はありません。

Prometheus から Stackdriver へのエクスポートの例では、単一の Pod が指標をエクスポートします。次のマニフェスト ファイルは、Deployment、および指標の目標値に基づいて Deployment をスケーリングする HPA を記述しています。

apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dummy-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          k8s-app: dummy-deployment
      template:
        metadata:
          labels:
            k8s-app: dummy-deployment
        spec:
          containers:
          - name: long
            image: busybox
            command: ["/bin/sh",  "-c", "sleep 180000000"]
    ---
    apiVersion: autoscaling/v2beta1
    kind: HorizontalPodAutoscaler
    metadata:
      name: dummy-deployment-hpa
      namespace: default
    spec:
      scaleTargetRef:
        apiVersion: apps/v1beta1
        kind: Deployment
        name: dummy-deployment
      minReplicas: 1
      maxReplicas: 5
      metrics:
      - type: Object
        object:
          target:
            kind: Pod
            name: custom-metric-prometheus-sd
          metricName: foo
          targetValue: 20

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

次のコマンドを実行して、GKE クラスタを削除します。

gcloud container clusters delete [CLUSTER_NAME]

トラブルシューティング

このチュートリアルで問題が発生した場合は、次のデバッグ手順をお試しください。

  1. kubectl api-versions を実行して、custom.metrics.k8s.io/v1beta1 API が登録されていることを確認します。この API がリストに表示されない場合は、カスタム指標アダプタ(ステップ 1 でデプロイしたもの)がクラスタ内で実行されていることを確認します。
  2. Metrics Explorer に移動し、カスタム指標が Stackdriver にエクスポートされていることを確認します。custom.googleapis.com/[NAME] で始まる指標を探します。指標が表示されない場合は、次のようにします。

    • エクスポータの Deployment(ステップ 2 でデプロイしたもの)が実行されていることを確認します。
    • --service-account を使用してノードのサービス アカウントをカスタマイズした場合は、モニタリング指標の書き込みの Cloud Identity and Access Management(Cloud IAM)役割(roles/monitoring.metricWriter)があることを確認します。
    • --scopes を使用してノードのスコープをカスタマイズした場合は、ノードに monitoring スコープがあることを確認します。

    Metrics Explorer を使用してモニタリング対象リソースの指標を表示する方法は次のとおりです。

    1. Google Cloud Console で [モニタリング] を選択するか、次のボタンを使用します。
      [モニタリング] に移動
    2. [Monitoring] のナビゲーション パネルで、 [Metrics Explorer] をクリックします。
    3. モニタリング対象リソースの名前を [Find resource type and metric] テキスト ボックスに入力します。
  3. kubectl describe hpa [DEPLOYMENT_NAME] を実行して、HPA によってカスタム指標が読み取られていることを確認します。エラーが発生した場合は次のようにします。

    • スケーリングされた Deployment(ステップ 2 でデプロイしたもの)が実行されていることを確認します。
    • --service-account を使用してノードのサービス アカウントをカスタマイズした場合は、モニタリング閲覧者の Cloud IAM 役割(roles/monitoring.viewer)があることを確認します。

次のステップ