本文屬於 k8s 監控系列,其他文章爲:node
原本按計劃這篇文章應該講 grafana 和 alertmanager 的,可是因爲它們部署起來太簡單沒有啥寫的動力。最近由於研究了 Prometheus adapter,因此想將本身的研究所得寫下來,也許下一篇會寫 grafana 和 alertmanager。。python
ok,讓咱們直接進入正文。git
kubernetes apiserver 提供了兩種 api 用於監控指標相關的操做:github
kubectl top
;kubernetes apiserver 用於將 kubernetes 的功能經過 restapi 的方式暴露出去,給其餘組件使用,可是它提供的都是核心相關功能。有些功能有用,可是非核心,apiserver 又得提供這樣的功能咋辦?正則表達式
考慮到這樣的狀況,kubernetes apiserver 提供對應的 api,可是對於達到這個 api 的請求,它並不處理,而是轉發到一個擴展 apiserver 上。有意思的是,這個擴展 apiserver 只要遵循規範,任何人均可以開發。json
使用者在使用擴展 apiserver 時,只須要將其註冊到 kube-aggregator(kubernetes apiserver 的功能),aggregator 就會將對於這個 api 的請求轉發到這個擴展 apiserver 上。固然 kubernetes apiserver 和擴展 apiserver 之間的交互會涉及到很是多的細節,這裏就很少提。api
resource metrics API 和 custom metrics API 就是這樣的例子,kubernetes apiserver 提供了這兩個 api,可是具體的實現它就無論了。markdown
而這篇文章的目的就是經過 Prometheus adapter 實現它們。app
在實現這兩個 api 以前,咱們先來聊聊 api 組和 api 版本。ide
所謂的 api group 就是你執行 kubectl api-versions
出現的值,這些值由 api group 和 api version 構成。
# kubectl api-versions admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 ... 複製代碼
內容太多,這裏只列出了 5 個。第一個 admissionregistration.k8s.io/v1beta1 中,admissionregistration.k8s.io
是 api group,v1beta1
表示它的版本。
若是 api group 爲空表示核心 api,kubernetes 的資源都是由 api group 提供的。那麼如何知道哪些資源是由哪些 api group 提供的呢?
執行 kubectl api-resources
就可以知道了:
# kubectl api-resources NAME SHORTNAMES APIGROUP NAMESPACED KIND bindings true Binding componentstatuses cs false ComponentStatus configmaps cm true ConfigMap endpoints ep true Endpoints events ev true Event limitranges limits true LimitRange namespaces ns false Namespace nodes no false Node ... 複製代碼
內容不少,這裏只列出一部分。輸出結果爲 5 列,NAME
列就是資源名,它的功能由 APIGROUP
列的 api group 提供。SHORTNAMES
列就是這些資源的縮寫了,縮寫在使用 kubectl 時很是好用。
上面列出的全部結果中,APIGROUP
都爲空,表示這些資源都是核心 api 提供的。當你看到某些 role 或者 clusterRole 中 apiGroup
的值爲 ""
時,就應該知道它要訪問的資源都是核心 api 提供的。
對於咱們要實現的兩個 api:
metrics.k8s.io
,版本爲 v1beta1
;custom.metrics.k8s.io
,版本爲 v1beta1
。它們的 api group 和 api version 會在後面註冊時用到。
先說這個 custom metrics API,resource metrics API 放在後面。你若是說你只須要 resource metrics API,那你也得看這個,由於這兩個 api 都由 Prometheus adapter 來實現。
custom metrics API 徹底就是給 HPA v2 準備的,由於 v1 只能使用 CPU 做爲 pod 橫向擴展的指標,很明顯沒法知足使用者的須要。
custom metrics API 的實現有多個,咱們之因此選擇 Prometheus adapter,是由於咱們已經安裝了 Prometheus。而經過 Prometheus adapter,只要存在於 Prometheus 中的指標,均可以拿來作 HPA 的條件,這樣就能知足全部的使用場景了。
kubernetes 1.14 中 apiserver 已經開啓了 Aggregation layer,所以咱們只須要安裝 Prometheus adapter 就行。
咱們會使用 deployment 部署 Prometheus adapter,固然會爲啓動它的 serviceAccount 綁定各類角色。由於它自己就是一個 apiserver,所以它會監聽一個端口,對外提供 http 服務。
咱們還須要爲它建立一個 service,kubernetes apiserver 轉發請求時,會將請求發送到 service 上,經由 service 到達後面的 Prometheus adapter。
本文全部的 yml 文件均保存在 GitHub,這裏就不一一列出了。Prometheus adapter 相關的文件都在 adapter 目錄下,custom metrics API 用到的文件有:
prometheus-adapter-apiServiceCustomMetrics.yml
prometheus-adapter-apiServiceMetrics.yml
prometheus-adapter-clusterRoleAggregatedMetricsReader.yml
prometheus-adapter-clusterRoleBindingDelegator.yml
prometheus-adapter-clusterRoleBinding.yml
prometheus-adapter-clusterRole.yml
prometheus-adapter-configMap.yml
prometheus-adapter-deployment.yml
prometheus-adapter-roleBindingAuthReader.yml
prometheus-adapter-serviceAccount.yml
prometheus-adapter-service.yml
複製代碼
其中:
custom.metrics.k8s.io
,版本爲 v1beta1
;metrics.k8s.io
,版本爲 v1beta1
。這是給 resource metrics 使用的;metrics.k8s.io
和 custom.metrics.k8s.io
下面的任意資源具備任意權限;不少人在使用的時候會使用 kubernetes CA 簽署一個證書以後用這個證書來爲 Prometheus adapter 提供 https。其實不須要如此,Prometheus adapter 啓動的時候,若是你沒有給它提供證書,它會生成一個自簽署的證書來提供 https。
至於這個證書是否受信任並不重要,由於 prometheus-adapter-apiServiceCustomMetrics.yml
文件中存在 insecureSkipTLSVerify: true
這個選項。
clone 並部署:
git clone https://github.com/maxadd/k8s-prometheus kubectl apply -f k8s-prometheus/adapter 複製代碼
經過下面直接訪問 api 的方式來測試部署是否 ok(你可能須要略等一下子):
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/" | python -mjson.tool kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/*/fs_usage_bytes" | python -mjson.tool 複製代碼
第一條命令會輸出很是多的值,都是能夠用做 HPA 的指標。若是你沒有,那麼部署存在問題,緣由後面會講。
第二條命令會輸出 monitoring 名稱空間下全部 pod 的 fs_usage_bytes
指標的值,若是你沒有,那麼部署一樣存在問題。
由於我前面安裝 Prometheus 的文章中對 Prometheus 中的一些指標和標籤作了一些修改,所以若是你直接使用官方的配置,那麼確定會出問題的。配置相關的內容下面會提到。
另外,Prometheus adapter 啓動參數中的 -v
至關於 debug 級別,值越大,輸出的日誌就越詳細,最高貌似爲 10?可是好像這個日誌沒啥做用。。
Prometheus adapter 的配置文件格式以下所示(因爲過長,因此截取了一部分)。它分爲兩個部分,第一個是 rules,用於 custom metrics;另外一個是 resourceRules,用於 metrics。若是你只用 Prometheus adapter 作 HPA,那麼 resourceRules 就能夠省略,反之亦然。
咱們從 rules 規則講起,這個規則下面有不少的查詢語句,這些查詢語句的做用就是儘量多的獲取指標,從而讓這些指標均可以用於 HPA。
也就是說經過 Prometheus adapter,你能夠將 Prometheus 中的任何一個指標都用於 HPA,可是前提是你得經過查詢語句將它拿到(包括指標名稱和其對應的值)。也就是說,若是你只須要使用一個指標作 HPA,那麼你徹底就能夠只寫一條查詢,而不像下面使用了好多個查詢。
rules: - seriesQuery: '{__name__=~"^container_.*",container_name!="POD",namespace!="",pod!=""}' seriesFilters: [] resources: overrides: namespace: resource: namespace pod: # 官方示例中的這個值爲 pod_name,因爲我以前將 pod_name 改成了 pod,因此這裏也爲 pod resource: pods name: matches: ^container_(.*)_seconds_total$ as: "" metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>,container_name!="POD"}[1m])) by (<<.GroupBy>>) --- resourceRules: cpu: containerQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>}[1m])) by (<<.GroupBy>>) nodeQuery: sum(rate(container_cpu_usage_seconds_total{<<.LabelMatchers>>, id='/'}[1m])) by (<<.GroupBy>>) resources: overrides: instance: resource: nodes namespace: resource: namespace pod: resource: pods containerLabel: container_name 複製代碼
接下來咱們會對其關鍵字進行解釋:
is: <regex>
:只獲取正則表達式匹配到的指標名稱;isNot: <regex>
:overrides
,另外一種是 template
。
microservice: {group: "apps", resource: "deployment"}
這麼寫表示將指標中 microservice 這個標籤和 apps 這 api 組中 deployment 資源關聯起來;template: "kube_<<.Group>>_<<.Resource>>"
這麼寫表示,假如 <<.Group>>
爲 apps,<<.Resource>>
爲 deployment,那麼它就是將指標中 kube_apps_deployment
標籤和 deployment 資源關聯起來;$1
,也就是第一個分組。as 爲空就是使用默認值的意思。前面訪問 /apis/custom.metrics.k8s.io/v1beta1/
出現的全部指標都是這些規則中 seriesQuery 查詢到的,固然名稱可能和 Prometheus 中不徹底同樣,由於這裏使用了 name 進行了重命名。
其實不少指標拿來作 HPA 是沒有必要的,好比說 Prometheus 自身的指標以及 k8s 組件指標等,可是 Prometheus adapter 確定但願將全部的指標都暴露出來,讓你想使用啥就使用啥,因此它的 seriesQuery 纔會這麼多。
訪問 /apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/*/fs_usage_bytes
則是經過 metricsQuery 進行查詢,從而獲取每一個 pod 的指標值。
部署有問題的多半就是配置文件中的關聯沒有作好,只有理解了這個配置文件的意思才能保證部署沒有問題。
剩下的 resourceRules 規則則是用於 resource metrics,只有 cpu 和 memory 兩個屬性,而這兩個屬性又分爲 node 和 pod,很容易看懂。當執行 kubectl top pods/nodes
時就會執行這兩條查詢語句。
關於 custom metrics 就到此爲止了,HPA 的內容這裏就不涉及了。
resource metrics API 官方的說法是給 k8s 核心組件提供監控指標的,可是它只提供了 pod 和 node 的 CPU 和內存指標,功能實在有限。
官方給出它能夠作如下工做:
因此總結下來,resource metrics API 的最大做用就是居然是讓你可使用 kubectl top
命令?固然我們先無論它是否有用,咱們目的之一就是部署一個擴展 apiserver 來實現它,接下來就是選一個擴展 apiserver。
不少人會使用 metrics server 提供 resource metrics API,而後使用 Prometheus adapter 提供 custom metrics API。可是其實 Prometheus adapter 徹底能夠支持這兩種 api,所以咱們徹底不須要 metrics server,只部署一個 Prometheus adapter 就行。
前面咱們其實已經部署好了,只須要驗證就行。
# kubectl -n monitoring top pods NAME CPU(cores) MEMORY(bytes) alertmanager-c8d754fbc-2slzr 1m 15Mi grafana-74bf6c49f6-lf7vw 7m 50Mi kube-state-metrics-856448748c-xtdxl 0m 24Mi prometheus-adapter-548c9b9c4c-mr9zq 0m 39Mi 複製代碼
可是執行 kubectl top node
會出現問題,由於我將 id='/'
的指標都刪掉了,若是不想將這些指標恢復,能夠看我下一篇收集宿主機指標的文章。
這篇文章就到這了,感謝閱讀,謝謝!