すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Prometheusクライアントを使用してアプリケーションを監視する

最終更新日:Dec 06, 2024

Prometheusを使用してアプリケーションを監視するには、インストルメンテーションを追加してアプリケーションデータを公開し、Prometheusクライアントを使用して収集したデータを表示します。 このトピックでは、Prometheusクライアントを使用してアプリケーションを監視する方法について説明します。 このトピックでは、Container Service for Kubernetes (ACK) クラスターとContainer Registryを使用します。

前提条件

ステップ1: アプリケーションを作成する

Prometheusの顧客はほとんどのプログラミング言語を支えます。 詳細については、「CLIENTライブラリ」をご参照ください。 次の例は、Goアプリケーションをインストルメントしてモニタリングデータを公開する方法を示しています。

package main
import (
    "flag"
    "fmt"
    "log"
    "math"
    "math/rand"
    "net/http"
    "time"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    addr              = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
    uniformDomain     = flag.Float64("uniform.domain", 0.0002, "The domain for the uniform distribution.")
    normDomain        = flag.Float64("normal.domain", 0.0002, "The domain for the normal distribution.")
    normMean          = flag.Float64("normal.mean", 0.00001, "The mean for the normal distribution.")
    oscillationPeriod = flag.Duration("oscillation-period", 10*time.Minute, "The duration of the rate oscillation period.")
)

var (
    // Create a summary to track fictional interservice RPC latencies for three distinct services with different latency distributions. 
    // These services are differentiated via a "service" label.
    rpcDurations = prometheus.NewSummaryVec(
        prometheus.SummaryOpts{
            Name:       "rpc_durations_seconds",
            Help:       "RPC latency distributions.",
            Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
        },
        []string{"service"},
    )
    // The same as above, but now as a histogram, and only for the normal
    // distribution. The buckets are targeted to the parameters of the
    // normal distribution, with 20 buckets centered on the mean, each
    // half-sigma wide.
    rpcDurationsHistogram = prometheus.NewHistogram(prometheus.HistogramOpts{
        Name:    "rpc_durations_histogram_seconds",
        Help:    "RPC latency distributions.",
        Buckets: prometheus.LinearBuckets(*normMean-5**normDomain, .5**normDomain, 20),
    })
)

func init() {
    // Register the summary and the histogram with Prometheus's default registry.
    prometheus.MustRegister(rpcDurations)
    prometheus.MustRegister(rpcDurationsHistogram)
    // Add Go module build info.
    prometheus.MustRegister(prometheus.NewBuildInfoCollector())
}

func main() {
    flag.Parse()
    start := time.Now()
    oscillationFactor := func() float64 {
        return 2 + math.Sin(math.Sin(2*math.Pi*float64(time.Since(start))/float64(*oscillationPeriod)))
    }
    // Periodically record some sample latencies for the three services.
    go func() {
        for {
            v := rand.Float64() * *uniformDomain
            rpcDurations.WithLabelValues("uniform").Observe(v)
            time.Sleep(time.Duration(100*oscillationFactor()) * time.Millisecond)
        }
    }()
    go func() {
        for {
            v := (rand.NormFloat64() * *normDomain) + *normMean
            rpcDurations.WithLabelValues("normal").Observe(v)
            // Demonstrate exemplar support with a dummy ID. This
            // would be something like a trace ID in a real
            // application.  Note the necessary type assertion. We
            // already know that rpcDurationsHistogram implements
            // the ExemplarObserver interface and thus don't need to
            // check the outcome of the type assertion.
            rpcDurationsHistogram.(prometheus.ExemplarObserver).ObserveWithExemplar(
                v, prometheus.Labels{"dummyID": fmt.Sprint(rand.Intn(100000))},
            )
            time.Sleep(time.Duration(75*oscillationFactor()) * time.Millisecond)
        }
    }()
    go func() {
        for {
            v := rand.ExpFloat64() / 1e6
            rpcDurations.WithLabelValues("exponential").Observe(v)
            time.Sleep(time.Duration(50*oscillationFactor()) * time.Millisecond)
        }
    }()
    // Expose the registered metrics via HTTP.
    http.Handle("/metrics", promhttp.HandlerFor(
        prometheus.DefaultGatherer,
        promhttp.HandlerOpts{
            // Opt into OpenMetrics to support exemplars.
            EnableOpenMetrics: true,
        },
    ))
    log.Fatal(http.ListenAndServe(*addr, nil))
}

以下にパラメーターを説明します。

  • rpc_duration_secondsメトリックを登録する前に、prometheus.MustRegisterメトリックを登録する必要があります。 この例では、rpc_duration_secondsメトリックはprometheus.NewSummaryVecタイプです。 他のタイプの詳細については、「Prometheus」をご参照ください。

  • rpcDurationsはグローバルシングルトンインスタンスです。 rpcDurations.WithLabelValues("uniform").Observe(v) メソッドは、モニタリングデータを更新するために呼び出されます。

コードテンプレートの詳細については、「prometheus / client_golang」をご参照ください。

ステップ2: アプリケーションをコンテナイメージにパッケージ化し、イメージをリポジトリにアップロードする

インストルメント化されたアプリケーションをコンテナイメージにパッケージ化し、そのイメージをcontainer Registryのリポジトリにアップロードします。

  1. 次のコマンドを実行して、イメージをビルドします。

    docker build -t <Name of the local temporary Docker image>:<Tag of the local temporary Docker image> . --no-cache

    例:

    docker build -t prometheus-demo:v1 . --no-cache
  2. 次のコマンドを実行して、画像にタグを付けます。

    sudo docker tag <Name of the local temporary Docker image>:<Tag of the local temporary Docker image> <Registry domain name>/<Namespace>/<Image name>:<Image tag>

    例:

    sudo docker tag prometheus-demo:v1 registry.cn-hangzhou.aliyuncs.com/ringtail/prometheus-demo:v1
  3. 次のコマンドを実行して、イメージをリポジトリにプッシュします。

    sudo docker push <Registry domain name>/<Namespace>/<Image name>:<Image tag>

    例:

    sudo docker push registry.cn-hangzhou.aliyuncs.com/ringtail/prometheus-demo:v1
  4. Container Registryコンソールで画像を表示します。

    1. Container Registryコンソールにログインします。

    2. 上部のナビゲーションバーで、リージョンを選択します。

    3. 左側のナビゲーションウィンドウで、[インスタンス] をクリックします。

    4. [インスタンス] ページで、管理するPersonal Editionインスタンスをクリックします。

    5. Personal Editionインスタンスの管理ページの左側のナビゲーションウィンドウで、[リポジトリ] > [リポジトリ] を選択します。

    6. [リポジトリ] ページで、管理するリポジトリを見つけ、[操作] 列の [管理] をクリックします。

    7. 左側のナビゲーションウィンドウで、タグをクリックします。

      アップロードした画像は、タグページで確認できます。

手順3: アプリケーションをACKクラスターにデプロイする

  1. ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。

  2. [クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、[ワークロード] > [ポッド] を選択します。

  3. ポッドを作成します。

    1. ポッドページでYAMLから作成するをクリックします。

    2. [作成] ページで、[テンプレート] コードエディターに次のコードを入力し、[作成] をクリックします。

      apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
      kind: Deployment
      metadata:
        name: demo-app
        labels:
          app: demo-app
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: demo-app
        template:
          metadata:
            labels:
              app: demo-app
          spec:
            containers:
            - name: demo-app
              image: <Repository domain name>/<Namespace>/<Image name>:<Image tag>
              command:
              - /random 
              ports:
              - containerPort: 8080

      例:

      apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
      kind: Deployment
      metadata:
        name: demo-app
        labels:
          app: demo-app
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: demo-app
        template:
          metadata:
            labels:
              app: demo-app
          spec:
            containers:
            - name: demo-app
              image: registry.cn-hangzhou.aliyuncs.com/ringtail/prometheus-demo:v1
              command:
              - /random 
              ports:
              - containerPort: 8080

    [ポッド] ページで、作成したポッドを見つけることができます。

  4. サービスを作成します。

    1. 詳細ページの左側のナビゲーションウィンドウで、[ネットワーク] > [サービス] を選択します。

    2. サービスページでYAMLから作成するをクリックします。

    3. [作成] ページで、次のコードをテンプレートコードエディターにコピーし、[作成] をクリックします。

      apiVersion: v1
      kind: Service
      metadata:
        labels:
          app: demo-app
        name: demo-app
        namespace: default
      spec:
        ports:
        - name: http-metrics
          port: 8080
          protocol: TCP
          targetPort: 8080
        selector:
          app: demo-app
        type: ClusterIP 

    [サービス] ページで、作成したサービスを確認できます。

手順4: サービス検出の設定

Goアプリケーションからデータをキャプチャするように、Managed service for Prometheusでサービス検出を構成します。 次の例は、Application Real-Time Monitoring service (ARMS) コンソールでサービス検出を構成する方法を示しています。

  1. ARMSコンソールにログインします。

  2. 上部のナビゲーションバーで、クラスターがデプロイされているリージョンを選択します。

  3. 左側のナビゲーションウィンドウで、[統合管理] をクリックします。 [統合環境] タブで、クラスターと同じ名前の環境をクリックします。

  4. Container Serviceページで、[メトリックスクレイピング] タブをクリックします。 左側のナビゲーションウィンドウで、[サービスモニター] をクリックします。

  5. [サービスモニター] リストで、[作成] をクリックします。 [ServiceMonitor構成の追加] パネルで、次のコードブロックをコードエディターにコピーし、[作成] をクリックします。

    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      labels:
        app: demo-app
      name: demo-app
      namespace: default
      annotations:
        arms.prometheus.io/discovery: 'true'
    spec:
      endpoints:
      - interval: 30s
        port: http-metrics
      jobLabel: app
      namespaceSelector:
        matchNames:
        - default
      selector:
        matchLabels:
          app: demo-app

    [ServiceMonitor] タブで、構成したServiceMonitorを確認できます。

手順5: Prometheusクライアントがメトリックに基づいてアプリケーションを監視できるかどうかを確認する

  1. ARMSコンソールにログインします。

  2. 上部のナビゲーションバーで、クラスターがデプロイされているリージョンを選択します。

  3. 左側のナビゲーションウィンドウで、[指標センター]> [指標の概要] を選択します。 検索ボックスに、手順1: アプリケーションのインストルメントで登録されたメトリックのrpc_durations_secondsを入力し、アイコンをクリックし查询ます。

    rpc_duration_secondsメトリックが返された場合、Prometheusクライアントがメトリックに基づいてアプリケーションを監視できることを示します。