Prometheus の使用

Prometheus は、Kubernetes でよく使用されるモニタリング ツールです。GKE 用 Cloud Operations を構成して Prometheus サポートを実装すると、Prometheus 表示形式を使用してサービスにより生成される指標をクラスタからエクスポートし、Cloud Monitoring の外部指標として表示できます。

このページでは、GKE 用 Cloud Operations で Prometheus を構成および使用する方法について説明します。この統合のソースコードは一般公開されています。

始める前に

このページの手順を行う前に、GKE から Cloud Monitoring に指標をエクスポートするために GKE ワークロード指標を使用できないことを確認してください。GKE ワークロード指標では、GKE ワークロードから出力された指標を収集して Cloud Monitoring に送信する、高度な構成が可能なフルマネージド パイプラインが提供されます。この場合、GKE ワークロード指標の使用をおすすめします。

ただし、GKE ワークロード指標でまだサポートされていないユースケースがあります。次のいずれかに該当する場合は、ユースケースで GKE ワークロード指標がまだサポートされていません。このページで説明する方法は、GKE から Cloud Monitoring にワークロード指標を送信する場合に適しています。

  • ラベルではなくフィールドに基づいてポッドを選択する必要がある
  • Prometheus を取得するために、HTTP 認証また相互 TLS のいずれかの形式で構成する必要がある
  • Prometheus の構成で metric_relabel_configs を使用する場合に、keepdrop 以外のアクションを使用する。
  • 取得したデータの後処理のために、記録ルールで Prometheus を構成する必要がある。
  • GKE から GKE クラスタがあるプロジェクトとは別の Google Cloud プロジェクトに指標を送信する必要がある。

上のいずれかに該当する場合、GKE ワークロード指標はユースケースに対応していません。このページの手順を行い、Cloud Monitoring に指標を送信する必要があります。

このページには、Prometheus サーバーのインストール手順や、Cloud Operations for GKE を使用した GKE クラスタの作成手順は記載されていません。

Prometheus では、Windows Server 用の組み込みサポートは提供されません。回避策としては、追加の Linux ノードプールに Prometheus サーバーをデプロイして、Windows 指標をキャプチャし、その指標を Linux ノードプールの Stackdriver コレクタに送り返すことができます。

Stackdriver コレクタをインストールする前に、次の要件をよく確認してください。

コレクタのインストール

Stackdriver コレクタをデプロイするには、次の手順を行います。

  1. 更新するオブジェクトを、名前とコントローラ タイプで識別します。サポートされているコントローラ タイプは、deploymentstatefulset のみです。

  2. 次の環境変数を設定します。

    • KUBE_NAMESPACE: スクリプトを実行する名前空間。
    • KUBE_CLUSTER: サイドカーのクラスタ名パラメータ。
    • GCP_REGION: サイドカーの Google Cloud リージョン パラメータ。
    • GCP_PROJECT: サイドカーの Google Cloud プロジェクト パラメータ。
    • DATA_DIR: サイドカーのデータ ディレクトリ。Prometheus サーバーの書き込み先の共有ボリュームが配置されるディレクトリです。後続の手順では、この変数は /data に設定されます。
    • DATA_VOLUME: Prometheus のデータが格納される、DATA_DIR 内の共有ボリュームの名前。以降の手順では、この変数は data-volume になります。
    • SIDECAR_IMAGE_TAG: Prometheus サイドカーの Docker イメージのバージョン。最新のリリースは、Container Registry にあります。
  3. 次のスクリプトを実行し、最初のステップで特定した 2 つのパラメータを指定します。

    #!/bin/sh
    
    set -e
    set -u
    
    CLEAN_UP_ORPHANED_REPLICA_SETS='--clean-up-orphaned-replica-sets'
    usage() {
      echo -e "Usage: $0 <deployment|statefulset> <name> [${CLEAN_UP_ORPHANED_REPLICA_SETS}]\n"
    }
    
    if [  $# -le 1 ]; then
      usage
      exit 1
    fi
    
    SHOULD_CLEAN_UP=${3:-}
    
    # Override to use a different Docker image name for the sidecar.
    export SIDECAR_IMAGE_NAME=${SIDECAR_IMAGE_NAME:-'gcr.io/stackdriver-prometheus/stackdriver-prometheus-sidecar'}
    
    kubectl -n "${KUBE_NAMESPACE}" patch "$1" "$2" --type strategic --patch "
    spec:
      template:
        spec:
          containers:
          - name: sidecar
            image: ${SIDECAR_IMAGE_NAME}:${SIDECAR_IMAGE_TAG}
            imagePullPolicy: Always
            args:
            - \"--stackdriver.project-id=${GCP_PROJECT}\"
            - \"--prometheus.wal-directory=${DATA_DIR}/wal\"
            - \"--stackdriver.kubernetes.location=${GCP_REGION}\"
            - \"--stackdriver.kubernetes.cluster-name=${KUBE_CLUSTER}\"
            #- \"--stackdriver.generic.location=${GCP_REGION}\"
            #- \"--stackdriver.generic.namespace=${KUBE_CLUSTER}\"
            ports:
            - name: sidecar
              containerPort: 9091
            volumeMounts:
            - name: ${DATA_VOLUME}
              mountPath: ${DATA_DIR}
    "
    if [[ "${SHOULD_CLEAN_UP}" == "${CLEAN_UP_ORPHANED_REPLICA_SETS}" ]]; then
      # Delete the replica sets from the old deployment. If the Prometheus Server is
      # a deployment that does not have `revisionHistoryLimit` set to 0, this is
      # useful to avoid PVC conflicts between the old replica set and the new one
      # that prevents the pod from entering a RUNNING state.
      kubectl -n "${KUBE_NAMESPACE}" get rs | grep "$2-" | awk '{print $1}' | xargs kubectl delete -n "${KUBE_NAMESPACE}" rs
    fi
    

スクリプトが正常に実行されると、ステップ 1 で特定したオブジェクトの Pod に、Stackdriver コレクタがサイドカーとして追加されます。スクリプトからコメントアウトされた 2 行は、GKE クラスタの指標データの収集には関係のない行です。ただし、これらの 2 つの行は、汎用の MonitoredResource を入力する際に必要になります。

構成の変更を永続化するには、追加の手順を行う必要があります。この手順については、以降のセクションで説明します。

インストールの検証

Stackdriver コレクタのインストールを検証するには、次のコマンドを実行します。

kubectl -n "${KUBE_NAMESPACE}" get <deployment|statefulset> <name> -o=go-template='{{$output := "stackdriver-prometheus-sidecar does not exist."}}{{range .spec.template.spec.containers}}{{if eq .name "sidecar"}}{{$output = (print "stackdriver-prometheus-sidecar exists. Image: " .image)}}{{end}}{{end}}{{printf $output}}{{"\n"}}'

  • Prometheus サイドカーが正常にインストールされると、使用された Container Registry イメージの一覧がスクリプトの出力に表示されます。次の例では、イメージのバージョンは 0.4.3 になります。インストールによっては、バージョンが異なる場合があります。

    stackdriver-prometheus-sidecar exists. Image: gcr.io/stackdriver-prometheus/stackdriver-prometheus-sidecar:0.4.3
    
  • インストールが失敗した場合、スクリプトの出力は次のようになります。

    stackdriver-prometheus-sidecar does not exist.
    

ワークロードが最新の状態で、利用可能かどうかを確認するには、次のコマンドを実行します。

kubectl -n "${KUBE_NAMESPACE}" get <deployment|statefulset> <name>

構成の変更の永続化

コレクタが正常にインストールされたことが確認できたら、クラスタの構成を更新して変更を永続化します。

  1. 共有ボリュームへの書き込みが可能となるように Prometheus サーバーを構成します。次の例では、DATA_DIR/data に、DATA_VOLUMEdata-volume にそれぞれ設定されていることが前提となっています。

    1. Prometheus の Pod に共有ボリュームが存在することを確認します。

      volumes:
        - name: data-volume
          emptyDir: {}
      
    2. Prometheus で、/data の下にその共有ボリュームをマウントさせます。

      volumeMounts:
      - name: data-volume
        mountPath: /data
      
    3. コンテナの args に次を追加して、/data の共有ボリュームに書き込みをするように Prometheus サーバーに指示します。

      --storage.tsdb.path=/data
      
  2. ワークロードの構成の管理に使用するツールを使用して、構成をクラスタに再適用し、Stackdriver コレクタ コンテナをサイドカーとして新しい構成に含めます。

    - name: sidecar
      image: gcr.io/stackdriver-prometheus/stackdriver-prometheus-sidecar:[SIDECAR_IMAGE_TAG]
      args:
      - "--stackdriver.project-id=[GCP_PROJECT]"
      - "--prometheus.wal-directory=/data/wal"
      - "--prometheus.api-address=[API_ADDRESS]"
      - "--stackdriver.kubernetes.location=[GCP_REGION]"
      - "--stackdriver.kubernetes.cluster-name=[KUBE_CLUSTER]"
      ports:
      - name: sidecar
        containerPort: 9091
      volumeMounts:
      - name: data-volume
        mountPath: /data
    

    この記述の [API_ADDRESS] は、Prometheus の API アドレスを表します。通常は http://127.0.0.1:9090 とします。

コレクタの詳細については、Stackdriver Prometheus サイドカーのドキュメントをご覧ください。

指標の表示

Prometheus は、指標を外部指標として Google Cloud のオペレーション スイートにエクスポートするように構成されています。

これらの指標を表示するには、次の手順を行います。

  1. Cloud Console で、[Monitoring] を選択します。

    [Monitoring] に移動

  2. [Monitoring] のナビゲーション パネルで、[Metrics Explorer] をクリックします。

  3. [Find resource type and metric] メニューで、次の手順を行います。

    • [Resource type] として [Kubernetes Container](k8s_container)を選択します。
    • [Metric] フィールドには、接頭辞 external/prometheus/ を含む指標を選択します。たとえば、external/prometheus/go_memstats_alloc_bytes を選択します。

    次の例では、特定のクラスタの指標を表示するフィルタが追加されています。複数のクラスタがある場合には、クラスタ名によるフィルタリングが便利です。

    Kubernetes コンテナの Prometheus 指標のサンプル。

Prometheus 由来の指標の費用を管理する

通常、Prometheus はアプリケーションによってエクスポートされたすべての指標を収集し、Stackdriver コレクタはデフォルトで Cloud Monitoring にこれらの指標を送信するように構成されています。このコレクションには、アプリケーションが依存するライブラリによってエクスポートされた指標が含まれます。たとえば、Prometheus クライアント ライブラリはアプリケーション環境に関する多くの指標をエクスポートします。

Stackdriver コレクタにフィルタを構成することにより、Cloud Monitoring に取り込む指標を選択できます。たとえば、kubernetes-podskubernetes-service-endpoints で生成された指標のみをインポートするには、stackdriver-prometheus-sidecar を実行するときに次の --include ステートメントを追加します。

 --include={job=~"kubernetes-pods|kubernetes-service-endpoints"}

詳しくは、Stackdriver Prometheus サイドカーのドキュメントをご覧ください。

また、これらの指標の料金を見積もることもできます。

Prometheus の統合に関する問題

Cloud Monitoring にデータが表示されません。

インストール手順を行った後に Cloud Monitoring にデータが表示されない場合は、コレクタログでエラー メッセージを検索します。

ログに明白なエラー メッセージが含まれていない場合は、--log.level=debug フラグをコレクタに渡してデバッグ ロギングを有効にします。ロギングの変更を有効にするには、コレクタを再起動する必要があります。コレクタを再起動した後に、コレクタログでエラー メッセージを検索します。

Cloud Monitoring に送信されるデータを確認するには、--stackdriver.store-in-files-directory コマンドライン パラメータを使用してファイルにリクエストを送信し、このディレクトリ内でファイルを検査できます。

アクセスの拒否

Monitoring API の権限拒否エラーが表示される場合は、始める前にで説明されている要件を確認してください。サービス アカウントに適切な権限が付与されていることを確認してください。Workload Identity を使用する場合は、KSA と GSA の関係を作成してください。

記録ルールを使用していますが、指標が Cloud Monitoring に表示されません。

記録ルールを使用している場合、可能であれば未加工の指標データを Cloud Monitoring に取り込んで、Cloud Monitoring の機能を使用してグラフやダッシュボードを作成するときにデータを集計するようにしてください。

未加工の指標データを取り込めない場合は、コレクタの構成static_metadata エントリを追加してください。このオプションを使用するには、job ラベルと instance ラベルを保持する必要があります。たとえば、次のような構成が有効です。

  • Prometheus サーバーの構成は、次のように指定します。

    groups:
    - name: my-groups
      rules:
      - record: backlog_avg_10m
        expr: avg_over_time(backlog_k8s[10m])
      - record: backlog_k8s
        expr: sum(total_lag) by (app, job, instance)
    
  • Prometheus のコレクタの構成は、次のように指定します。

    static_metadata:
      - metric: backlog_avg_10m
        type: gauge
    

job ラベル、instance ラベルのいずれかを変更または削除する記録ルールはサポートされていません。

jobinstance といった Prometheus ラベルが指標に表示されません。

Stackdriver Prometheus コレクタは、よく知られている Prometheus ラベルから Kubernetes オブジェクト用の Cloud Monitoring の MonitoredResource を構築します。ラベル記述子を変更した場合、コレクタはその指標を Monitoring に書き込むことができません。

ログに「duplicate time series」エラーや「out-of-order writes」エラーが表示されています。

これらのエラーは、指標データが同じ時系列に 2 回書き込まれると発生します。Prometheus エンドポイントが、Cloud Monitoring の単一のモニタリング対象リソースから出力される同じ指標を 2 回使用すると、このようなエラーが発生します。

たとえば、Kubernetes コンテナが複数のポートを介して Prometheus 指標を送信する場合があります。その際、Monitoring のモニタリング対象リソース k8s_container ではポートごとにリソースが区別されないため、同じ時系列中に 2 点の書き込みが検出されます。このような状況を回避するには、時系列を区別する指標ラベルを Prometheus に追加します。たとえば、コンテナが再起動しても変わらない __meta_kubernetes_pod_annotation_prometheus_io_port というラベルを使用します。

「metric kind must be X, but is Y」エラーがログに記録されています。

これらのエラーは、既存の指標記述子の Prometheus 指標タイプを変更した場合に発生します。Cloud Monitoring では指標の種類が厳密に決められており、ゲージ、カウンタなどの指標の種類の変更はサポートされていません。

指標のタイプを変更するには、対応する指標記述子を削除し、新しい記述子を作成する必要があります。指標記述子を削除すると、既存の時系列データにアクセスできなくなります。

以前は Prometheus の指標データの種類が表示されていましたが、現在は表示されません。

Prometheus では、指標データを外部指標として Cloud Monitoring にエクスポートするよう事前に構成されています。データがエクスポートされると、Monitoring は外部指標に対して適切な指標記述子を作成します。特定の種類の指標のデータが少なくとも 24 か月以上書き込まれていない場合、指標記述子は削除の対象となります。

未使用の指標記述子が 24 か月後に削除される保証はありませんが、Monitoring は過去 24 か月間に使用されなかった Prometheus 指標記述子を削除する権限を有します。

非推奨ポリシー

Prometheus と Cloud Monitoring の統合はエージェントの非推奨ポリシーの対象です。