全部產品
Search
文件中心

Container Service for Kubernetes:使用Prometheus Client監控應用

更新時間:Nov 16, 2024

通過在應用中埋點來暴露應用資料,使用Prometheus Client監控抓取資料,即可實現利用Prometheus監控應用的目的。本文以阿里雲Container ServiceKubernetes叢集和阿里雲Container Registry為例,介紹如何通過Prometheus Client監控應用。

前提條件

步驟一:對應用埋點

Prometheus Client目前支援大部分程式設計語言,更多資訊,請參見CLIENT LIBRARIES。以下樣本通過對應用埋點以暴露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_durations_seconds指標前需要註冊一個監控指標prometheus.MustRegister。本樣本中rpc_durations_secondsprometheus.NewSummaryVec類型,更多其他類型,請參見Prometheus

  • rpcDurations是一個全域的單例,在更新監控資料時通過調用rpcDurations.WithLabelValues("uniform").Observe(v)增加監控資料。

關於代碼模板,請參見prometheus / client_golang

步驟二:將應用製作為鏡像並上傳到鏡像倉庫

將完成埋點的應用製作成鏡像並上傳至阿里雲Container Registry的鏡像倉庫。

  1. 執行以下命令構建鏡像。

    docker build -t <本地臨時Docker鏡像名稱>:<本地臨時Docker鏡像版本號碼> . --no-cache

    樣本命令:

    docker build -t prometheus-demo:v1 . --no-cache
  2. 執行以下命令為鏡像打標。

    sudo docker tag <本地臨時Docker鏡像名稱>:<本地臨時Docker鏡像版本號碼> <Registry網域名稱>/<命名空間>/<鏡像名稱>:<鏡像版本號碼>

    樣本命令:

    sudo docker tag prometheus-demo:v1 registry.cn-hangzhou.aliyuncs.com/ringtail/prometheus-demo:v1
  3. 執行以下命令將鏡像推送至鏡像倉庫。

    sudo docker push <Registry網域名稱>/<命名空間>/<鏡像名稱>:<鏡像版本號碼>

    樣本命令:

    sudo docker push registry.cn-hangzhou.aliyuncs.com/ringtail/prometheus-demo:v1
  4. 查看已推送的鏡像。

    1. 登入Container Registry控制台

    2. 在頂部功能表列,選擇所需地區。

    3. 在左側導覽列,選擇執行個體列表

    4. 執行個體列表頁面單擊個人版執行個體。

    5. 在個人版執行個體管理頁面選擇倉庫管理 > 鏡像倉庫

    6. 鏡像倉庫頁面單擊目標倉庫操作列的管理

    7. 在左側導覽列,選擇鏡像版本

      在鏡像版本列表中可查看已推送的鏡像。

步驟三:將應用部署至Container ServiceKubernetes叢集

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  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: <Registry網域名稱>/<命名空間>/<鏡像名稱>:<鏡像版本號碼>
              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 

    服務頁面可查看已建立的服務。

步驟四:佈建服務發現

配置阿里雲Prometheus監控的服務發現以抓取Go應用資料。本樣本以ARMS控制台操作為例:

  1. 登入ARMS控制台

  2. 在頂部功能表列,選擇叢集所在的地區。

  3. 在左側導覽列,單擊接入管理,在已接入環境的環境列表頁面,單擊目標環境名稱(和叢集名稱一致)。

  4. 容器環境頁面,單擊指標採集頁簽,然後在左側導覽列單擊ServiceMonitor

  5. 在ServiceMonitor列表單擊新增,在新增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頁簽下可查看已配置的服務發現。

步驟五:驗證Prometheus Client是否支援通過指標監控應用資料

  1. 登入ARMS控制台

  2. 在頂部功能表列,選擇叢集所在的地區。

  3. 在左側導覽列,選擇指標中心>指標總覽,然後在搜尋方塊輸入步驟一:對應用埋點註冊的指標rpc_durations_seconds,單擊查詢表徵圖。

    若查詢到指標rpc_durations_seconds,表示Prometheus Client已通過該指標監控應用資料。