【Kubernetes社區】監控指標穩定性框架介紹

引言

使用Kubernetes 1.15版本,經過API(/metrics)查詢Kubernetes監控指標時,在某些指標的 HELP 信息中,能夠看到諸如 「[ALPHA]」 、「[STABLE]」 、「(Deprecated)」等字樣,用來標明監控指標的穩定性,以便於用戶跟據自身需求來放心的使用這些指標來監控集羣。golang

一個典型的指標以下所示:編程

# HELP rest_client_request_latency_seconds [ALPHA] (Deprecated) Request latency in seconds. Broken down by verb and URL.
# TYPE rest_client_request_latency_seconds histogram
rest_client_request_latency_seconds_bucket{url="https://[::1]:6443/%7Bprefix%7D",verb="GET",le="0.001"} 36
rest_client_request_latency_seconds_bucket{url="https://[::1]:6443/%7Bprefix%7D",verb="GET",le="0.002"} 148
rest_client_request_latency_seconds_bucket{url="https://[::1]:6443/%7Bprefix%7D",verb="GET",le="0.004"} 166
rest_client_request_latency_seconds_bucket{url="https://[::1]:6443/%7Bprefix%7D",verb="GET",le="0.008"} 172

與其餘API的標識同樣,ALPHA意味着該監控指標還處理於實驗階段,可能隨時會改變,並且不保證會通知用戶,用戶須要謹慎使用。Deprecated意味着該監控指標已被棄用,在未來的版本中會被刪除,用戶須要儘快中止使用或使用替代的監控指標。api

本文編寫時間爲1.16版本發佈前夕,既有的監控指標還未所有遷移到該框架中,因此只有部分監控指標會有穩定性標識。app

本文但願從監控指標穩定性框架的開發背景講起,接着介紹該框架的實現原理,以幫助開發者更詳細的瞭解和使用這個特性。框架

背景

不少集羣監控系統都使用Kubernetes提供的監控指標來監控集羣運行情況,然而Kubernetes提供的指標沒有任何穩定性的保證,也就是說Kubernetes隨時有可能修改這些指標,用戶升級新的Kubernetes版本後,有可能原有的監控指標已被修改或直接刪除,這給用戶帶來了困擾,這種用戶的困擾引發了社區關注。學習

爲了解決這個問題,社區進行了普遍的討論,總結下來有這兩種主流的思路:測試

  • 使用版本標記:爲監控指標劃分版本標識,好比 /metrics/v1beta1/metrics/v1等;
  • 使用文檔標記:提供文檔標記那些穩定的監控指標;

這兩種思路都有相應的優缺點:this

  • 使用版本標記的辦法更相似於Kubernetes API的作法,這種作法優勢是能夠同時支持多個版本,缺點是實現起來很是笨重;
  • 使用文檔標記優勢是實現簡單,把穩定的監控指標記錄到文檔中便可,缺點是後續迭代時仍然會不可避免的破壞這個規則,從工程角度講,很是難以管理。

最後,結合這兩個思路的優缺點,社區使用了一個更具創新性的方案,也就是本文要介紹的穩定性框架,該框架在實現層面相對使用版本標記更簡單,在工程層面比使用文檔標記更易於管理。url

願景

與每一個公司成立時都須要一個願景或口號同樣,監控指標穩定性框架也有本身的願景:設計

  • 提供一種描述監控指標穩定性的機制;
  • 提供多種監控穩定性描述;

兩個願景,一個是幫助Kubernetes開發人員定義本身的監控指標,一個是如何向用戶呈現穩定性保證。

同時,如下內容不在框架的考慮範圍:

  • 不定義某個具體的監控指標穩定級別;
  • 不負責檢查具體的監控指標是否符合規範;

事實上,本框架不考慮的這些內容也很重要,會在社區其餘事項中去作,只是本框架不負責這些內容。

實現原理

舊的實現

咱們或許都據說過Prometheus已成爲Kubernetes監控的事實標準,這體如今Kubernetes的不少組件(kube-scheduler、kubelet、kube-controller-manager和kube-apiserver等)都使用Prometheus客戶端來生成Prometheus格式的監控指標。

使用Prometheus,對於每一個監控指標通常會先初始化一個實例,再添加到全局的註冊表中,最後當用戶使用API訪問時,http handler 負責把這些監控指標導出。

初始化實例:

var authenticatedUserCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "authenticated_user_requests",
			Help: "Counter of authenticated requests broken out by username.",
		},
		[]string{"username"},
	)

添加到註冊表:

prometheus.MustRegister(authenticatedUserCounter)

http handler 使用的也是 Prometheus提供的handler:

// Install adds the DefaultMetrics handler
func (m DefaultMetrics) Install(c *mux.PathRecorderMux) {
	register()
	c.Handle("/metrics", prometheus.Handler())
}

由上能夠看到,原有的監控標標嚴重依賴Prometheus的特性,而新的框架設計將會對監控指標的定義、初始化、註冊過程進行封裝,即各組件再也不直接使用Prometheus,而是使用新的框架,儘管新的框架仍是使用Prometheus來實現,但提供了更多個性化的設計。

新的實現:監控指示定義

在監控指標定義環節,新框架提供了新的指標參數結構體,以便於增長穩定性標識。

好比,曾經使用Prometheus定義一個計數器時會使用prometheus.CounterOpts結構體,以下所示:

var someMetricDefinition = prometheus.CounterOpts{
    Name: "some_metric",
    Help: "some description",
}

新框架則提供了一個通過擴展的參數結構體kubemetrics.CounterOpts,新增長了StabilityLevelDeprecatedVersion等字段用於表示穩定性和棄用標示。

表示一個監控指標被廢棄,能夠以下定義:

var deprecatedMetricDefinition = kubemetrics.CounterOpts{
    Name: "some_deprecated_metric",
    Help: "some description",
    StabilityLevel: kubemetrics.STABLE, // 自定義字段,穩定性標識
    DeprecatedVersion: "1.15", // 自定義字段,棄用標識
}

表示一個ALPHA監控指標,能夠以下定義:

var alphaMetricDefinition = kubemetrics.CounterOpts{
    Name: "some_alpha_metric",
    Help: "some description",
    StabilityLevel: kubemetrics.ALPHA,
    DeprecatedVersion: "1.15", // 可選字段,標明將在哪一個版本棄用
}

與Prometheus一致,新框架對4種監控指標分別作了擴展:

  • CounterOpts
  • GaugeOpts
  • HistogramOpts
  • SummaryOpts

本節暫不對每種監控指標展開介紹,仍是聚焦在闡述新框架的實現思路上。

新的實現:監控指標初始化

曾經,使用Prometheus來初始化監控指標(獲取監控指標實例),將使用一系列的prometheus.NewXXX()方法,以下所示:

var someCounterVecMetric = prometheus.NewCounterVec(
    someMetricDefinition, // 指標定義
    []string{"some-label", "other-label"}, // 指標的label
}

一方面,因爲新的框架擴展了指標定義結構體,沒法繼續使用prometheus.NewXXX()方法,另外一方面新框架也但願能在指標初始化時擴展自定義行爲(好比處理定義環節加入的字段),因此新框架中也提供了相似的一系列方法。

使用新框架的方法來初始化實例示例以下:

var deprecatedMetric = kubemetrics.NewCounterVec(
    deprecatedMetricDefinition, // 擴展的指標定義
    []string{"some-label", "other-label"},
}

一樣與Prometheus保持一致,新框架也提供了全部的初始化方法:

  • NewCounter() 和 NewCounterVec()
  • NewGauge() 和 NewGaugeVec()
  • NewHistogram() 和 NewHistogramVec()
  • NewSummary() 和 NewSummaryVec()

一樣,本節暫不對每種初始化方法展開介紹,這部份內容留到後面的章節中。

新的實現:監控指標註冊

曾經,使用Prometheus來註冊一個監控指標實例時,其實是註冊到一個全局的註冊表,以下所示:

prometheus.MustRegister(someCounterVecMetric)

新框架中對註冊也進行了封裝,以便增長自定義的行爲,好比廢棄版本檢查,註冊邏輯僞代碼以下:

import version "k8s.io/apimachinery/pkg/version"

type Registry struct {
    promregistry *prometheus.Registry
    KubeVersion version.Info
}

func (r *Registry) MustRegister(metric kubemetrics.Metric) {
    if metricutils.compare(metric.DeprecatedVersion).isLessThan(r.KubeVersion) { // 若是廢棄版本比當前版本低,檢查廢棄規則,不知足則再也不註冊
        // check if binary has deprecated metrics enabled otherwise
        // no-op registration
        return
    } else if metricutils.compare(metric.DeprecatedVersion).isEqual(r.KubeVersion) { // 若是廢棄版本與當前版本一致,則把棄用信息增長到指標的 HELP 信息中並記錄 warning 日誌
        // append deprecated text to description
        // emit warning in logs
        // continue to actual registration
    }
    // 若是是 ALPHA 監控指標,增長相應的標識到 HELP 信息中
    
    r.promregistry.MustRegister(metric.realMetric) // 最後仍是使用Prometheus來完成註冊
}

使用新框架註冊,以下所示:

kubemetrics.MustRegister(deprecatedMetric)
kubemetrics.MustRegister(alphaMetric)

由上綜述,能夠看到在編程層面,既有的監控指標能夠方便的遷移到新框架,若是監控指標沒有個性化的需求,那麼其行爲與原Prometheus徹底一致,若是有個性化的需求,經過簡單的配置就可完成,具體的實現細節所有由新框架負責。

穩定性聲明

當前版本(kubernetes 1.15 & 1.16)提供兩個級別的穩定性,用來闡述每一個監控指標的穩定性:

  • Alpha
  • Stable

須要額外說起的時,在當前的設計中並無考慮 Beta 級別,新框架做者表示未來有須要時再添加,添加也會很是簡單。

Alpha 級別的監控指標,基本上不提供任何穩定性的保證,它們能夠隨時被修改,並且新框架引入後,既有的監控指標都將標記爲這個級別。

Stable 級別的監控指示,基本上能夠保證「再也不修改」,除非未來被廢棄。這裏所說的「再也不修改」指如下三個內容不會修改:

  • 監控指標自己不會被刪除或重命名;
  • 監控指標類型不會被修改;
  • 監控指標的lable列表不會增長或減小;

針對Stable級別的監控指標,lable列表不會改變,但lable 值是能夠改變的。好比,某個指標用於記錄鑑權的次數,使用"result"做爲lable進行區分,lable 值原來是"success"和"failure",是容許增長新的lable 值的,好比增長一個"error"(不是簡單的鑑權失敗,而是出現某種異常)。

好比,你以前獲得的指標將會由:

authentication_attempts{result="success"} 1345
authentication_attempts{result="failure"} 100

變成:

authentication_attempts{result="success"} 1345
authentication_attempts{result="failure"} 100
authentication_attempts{result="error"} 1     // 增長新的lable 值

通常來說,這種變化對用戶的衝擊不會很大。

針對Stable級別的監控指標,刪除或增長 lable 是不容許的,若是必需要這麼作,須要先把當前的指標廢棄,再提供一個新的監控指標。

對於用戶來說,新框架還提供了一個由用戶顯式的屏蔽某些監控指標的能力,默認狀況下,全部的監控指標都會被註冊並最終經過API提供給用戶,但使用新框架後,用戶能夠經過相應組件的啓動參數顯式的關掉某些監控指標,好比:

--disable-metrics=somebrokenmetric,anothermetric

穩定性保證

把一個監控指標標記爲 Stable 意味着對廣大用戶作出了一個承諾,這跟 API 是一致的。因此將某個監控指標標記爲 Stable 或者 廢棄某個監控指標時,須要很是謹慎的 review。

然而,跟據Kubernetes社區的組織劃分,各個組件分別有不一樣的 group (準確叫法是SIG)來負責相應的組件開發,各group的 reviewer 可能並不徹底瞭解新框架所引入的這個理念,因此各group頗有可能未來破壞以前作出的穩定性承諾。而每一個相關監控指標的修改都由負責監控的group來review,代價會很是大,而變得不可取。

針對這個問題,kubernetes社區又提供了讓人眼前一亮的方法,即引入新的一致性測試。 即,生成一份現有的穩定性列表,並存放到某個由監控組管理的目錄中,增長新的CI工做流收集最新的穩定性監控指標,兩者對比,若是不一致,CI 會失敗並拒絕合入,除非顯式的修改穩定性列表。CI能夠保證當顯式的修改穩定性列表時,必須通過監控組的批准。

棄用規則

每一個Stable的監控指標,在決定要將其廢棄後,能夠在監控指標定義處顯式的指定將要棄用的版本(DeprecatedVersion)。某個指標標記爲廢棄後不會立刻被刪除,須要留給用戶一個適配的窗口,在接下來的某些版本中才會真正被刪除。

被廢棄的監控指標都會經歷以下階段(每一個階段表明一個kubernetes minor版本):

Stable metric -> Deprecated metric -> Hidden metric -> Deletion

好比,某個監控指標在1.16版本進入 Stable 階段,將在 1.17版本棄用,那麼在各版本其狀態以下:

  • 1.16(Stable metric):可正常使用;
  • 1.17(Deprecated metric):標記爲棄用,當前版本仍然能夠用,可是用戶須要準備適配;
  • 1.18(Hidden metric):默認不開啓該監控指標,管理員可經過參數顯式的啓用該指標;
  • 1.19(Deletion):完全刪除,沒法再使用;

棄用階段

好比,某個監控指標將在1.17版本廢棄,那麼1.17版本(或更早的版本)開發時能夠這樣設置:

var someCounter = kubemetrics.CounterOpts{
    Name: "some_counter",
    Help: "this counts things",
    StabilityLevel: kubemetrics.STABLE,
    DeprecatedVersion: "1.17", // this metric is deprecated when the Kubernetes version == 1.17
}

使用1.17以前的版本,監控指標信息以下:

# HELP some_counter this counts things
# TYPE some_counter counter
some_counter 0

那麼用戶在使用1.17版本時,將會看到相應的指標信息中出現棄用信息:

# HELP some_counter (Deprecated from 1.17) this counts things
# TYPE some_counter counter
some_counter 0

此外,當監控指標被標記爲廢棄後,雖然能正常使用,可是在相應的組件日誌中能夠看到告警日誌。

隱藏階段

當監控指標被棄用的下一個版本,即DeprecatedVersion == current_kubernetes_version - 1時,該監控指標默認會被隱藏:即不會自動註冊。

被隱藏的指標能夠經過相應組件的啓動參數(--enable-hidden-metrics=really_deprecated_metric)來顯式的啓用。

若是用戶忘記在上個版本中作好適配,仍然能夠在本版本中繼續使用,這無疑給用戶延長了適配窗口。

另外,須要特別說起的幾點是:

  • 被標記爲棄用的監控指標仍然尊守以前的穩定性約定,除了增長棄用標記外不會修改指標內容;
  • 本棄用規則是針對Stable監控指標的,不對 Alpha 監控指標作強制要求。
  • 處於 Alpha 階段的監控指標也能夠標記廢棄版本號,它能夠幫助使用 Alpha 監控指標的用戶準確的瞭解某個監控指標什麼時候會被刪除,僅用於說明,被刪除前能夠不遵循棄用規則;

總結

新的監控指標框架是社區衆多專家智慧的結晶,從其設計理念上能夠看出Kubernetes社區對用戶承諾的重視,能夠看出對軟件工程的深層次的思考,值得學習。

相關文章
相關標籤/搜索