k8s 監控(一)安裝 Prometheus

本文屬於 k8s 監控系列,其他文章爲:node

  1. k8s 監控(二)監控集羣組件和 pod
  2. k8s 監控(三)prometheus-adapter
  3. k8s 監控(四)監控宿主機

k8s 監控咱們要完成如下幾點:git

  • 監控 master/node 自己;
  • 監控集羣組件 apiServer、etcd 等;
  • 監控須要關注的 pod;
  • 自定義的監控,包括 jmx 等。

有了這些監控指標以後,咱們還須要作到如下幾點:github

  1. 制定相應的告警規則;
  2. 提供對應的 webhook 發出告警;
  3. 部署 grafana 進行圖形展現;
  4. 監控相關組件的高可用;
  5. 和 k8s metrics-server 進行結合。

目前而言,k8s 的監控業界公認的標準就是使用 Prometheus,Prometheus 也能很好的完成 k8s 的監控工做。只不過若是使用原生 Prometheus 進行監控的話,還要完成上述操做,須要作的工做很是多,須要對 k8s 以及 Prometheus 自己有必定的理解。web

爲何不使用 prometheus-operator

爲了方便操做,coreos 提供了 prometheus-operator 這樣一個產品,它包裝了 Prometheus,而且還提供了四個自定義的 k8s 類型(CustomResourceDefinitions),讓你經過定義 manifest 的方式還完成新監控(job)以及告警規則的添加,而無需手動操做 Prometheus 的配置文件,讓整個過程更 k8s。正則表達式

而且在此基礎之上,coreos 還有推出了 kube-prometheus 這樣的升級版,它在 prometheus-operator 的基礎之上高可用了 Prometheus 和 Alertmanager,提供了 node-exporter 用於宿主機的監控,還有 Kubernetes Metrics APIs 的 Prometheus 適配器和 grafana,讓你實現一鍵部署。json

老外喜歡這麼搞,是否是必定合適我不知道,可是確定是存在問題的,畢竟這個 prometheus-operator 依然處於 bate 狀態。而且它裏面多出的不少組件都只是爲了不讓你直接操做配置文件,而這些組件都是額外的消耗。vim

同時也是由於你不能直接操縱配置文件,因此一旦你想修改配置文件就很是困難了,由於配置文件是自動生成的,一旦你想要修改它的 relabel_config 配置,你只能在它生成的規則後面添加。api

這樣會出現一種狀況,就是你可能想刪掉它爲你自動生成的標籤,可是這個標籤原本就沒有,是它爲你生成的,可是生成以後你又想刪除,這樣就平白多了兩臺規則。而且一旦你配置定義錯了,由於是 prometheus-operator 幫你 reload 的,所以就算有錯誤你也收不到。bash

若是你只是簡單使用的話能夠直接使用 kube-prometheus。可是隻要你想要了解其中的原理部分,或者有本身定製化的需求,那就搞原生的吧,全部 prometheus-operator 可以實現的,原生都能實現。markdown

怎麼作

本文會從 0 開始,一點一點完成一開始的監控需求。即便你仍是想用 kube-prometheus,等你看完個人全部文章以後,你使用起來也就沒有絲毫的障礙了。

咱們要作的就是將 Prometheus 鏡像部署到 k8s 中,而後使用 kubernetes_sd_config 對 k8s 進行完成監控。固然,prometheus-operator 也是這麼作的。

雖然 Prometheus 能夠作到對 k8s 集羣中全部 pod 的發現,可是 pod 的 ip 會隨時改變,並且你進行全部 pod 的發現讓你無從對它們進行分類管理,這樣就會很是亂。

所以,我這裏會和 prometheus-operator 同樣,只對 endpoint 進行發現。由於建立 service 就會建立對應的 endpoint,因此咱們徹底能夠經過 service 對 pod 進行分類,而後針對一類 pod 咱們使用一個 Prometheus 的 job,這樣就很是簡潔明瞭了。

文章中全部的文件我都已上傳到 GitHub,你能夠直接 clone 下來,而不須要頻繁的複製粘貼。

本文中 k8s 版本爲 1.14.2,採用 kubeadm 安裝。此外,本文不會對 Prometheus 進行過多的介紹,也就是說你須要有必定的 Prometheus 基礎。

查詢 kubelet 指標頁面

你們應該清楚,應用若是想要被 Prometheus 監控,就應該提供一個 url,一旦訪問這個 url,那麼全部監控項就會以文本的形式一行行打印出來,Prometheus 就經過訪問這個 url 來得到全部的監控數據,這個 uri 默認爲 http[s]://IP:PORT/metrics

由於 Prometheus 已經成爲了一個標準,所以 k8s 的全部組件都提供了 /metrics 這個 url。對於一些主機層面或者沒有提供這個 url 應用的監控,可使用一箇中間產品,這個產品收集應用相關的監控指標,而後提供這個 url,讓 Prometheus 進行採集。

這種產品稱爲 XXX_exporter,好比 node_exporter、jmx_exporter 等,官方收錄了不少的 exporter,有官方和非官方的,你也能夠經過它們提供的客戶端庫本身實現一個。

既然 Prometheus 可以經過 http 收集,那經過 curl 同樣也行。所以在使用 Prometheus 收集以前,我會使用 curl 命令將全部要收集的指標數據先輸出出來,以便你們心中有數。

固然,由於是在 k8s 環境,監控指標在收取以後會附加上一些標籤,好比它所在的名稱空間、所屬的 service、pod 名稱,以及 ip 端口等,這些標籤你也能夠選擇加仍是不加。

話很少說,咱們先看看 kubelet 的指標數據。先建立一個目錄,用於存放後續全部的 manifest 文件:

mkdir -p /opt/kube/prometheus
複製代碼

首先建立一個名稱空間,全部監控相關的資源都放在這個名稱空間之下:

# vim 00namespace.yml
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring

# kubectl apply -f 00namespace.yml
複製代碼

咱們知道,pod 都是由 kubelet 建立的,所以 pod 的相關指標(包括使用的 cpu、內存、流量等)是由 kubelet 提供的,咱們如今就能夠訪問 kubelet 的指標頁面,看看有哪些指標數據。

做爲一個守護進程,kubelet 默認監聽 10250 端口,所以能夠在 master 或者 node 上直接訪問:

# curl https://127.0.0.1:10250/metrics/cadvisor -k
Unauthorized
複製代碼

其中:

  • 必須使用 https;
  • metrics/cadvisor 是 kubelet pod 相關的監控指標,它還有一個 metrics,這是 kubelet 自身的監控指標;
  • -k 表示不驗證 kubelet 證書,由於整個集羣都是使用自簽署證書,所以不必驗證;

上面提示咱們沒有認證,看不到指標數據。認證很簡單,使用 token 便可,那麼咱們首先要建立這個 token。你們應該清楚,當咱們建立一個 serviceAccount 以後,k8s 會自動爲其生成一個 secret,這個 secret 中就有 token 信息。

所以咱們須要建立了一個 clusterRole,並建立一個 clusterrolebinding 將權限綁定到一個 serviceAccount 上,那麼咱們就拿到了這個權限的 token 了。

那咱們須要建立 prometheus-clusterRole.ymlprometheus-clusterRoleBinding.ymlprometheus-serviceAccount.yml 這三個文件,它們的內容以下。

prometheus-clusterRole.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
 name: prometheus-k8s
rules:
 - apiGroups:
 - ""
 resources:
 - nodes/metrics
 verbs:
 - get
 - nonResourceURLs:
 - /metrics
 verbs:
 - get
複製代碼

prometheus-clusterRoleBinding.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
 name: prometheus-k8s
roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: ClusterRole
 name: prometheus-k8s
subjects:
 - kind: ServiceAccount
 name: prometheus-k8s
 namespace: monitoring
複製代碼

prometheus-serviceAccount.yml:

apiVersion: v1
kind: ServiceAccount
metadata:
 name: prometheus-k8s
 namespace: monitoring
複製代碼

這樣咱們就建立了一個 ServiceAccount,名爲 prometheus-k8s,這個 ServiceAccount 不只如今能夠用來獲取 kubelet 的監控指標,後續 Prometheus 也會使用這個 serviceAccount 啓動。

kubectl apply -f prometheus-clusterRole.yml
kubectl apply -f prometheus-clusterRoleBinding.yml
kubectl apply -f prometheus-serviceAccount.yml
複製代碼

建立完成後,會自動在生成一個 secret,裏面包含了 token:

# kubectl -n monitoring get secret
NAME                         TYPE                                  DATA   AGE
prometheus-k8s-token-xmkd4   kubernetes.io/service-account-token   3      3h26m
複製代碼

獲取 token:

token=`kubectl -n monitoring get secret prometheus-k8s-token-xmkd4 -o jsonpath={.data.token} | base64 -d`
複製代碼

而後使用這個 token 訪問 kubelet 的指標頁面:

curl https://127.0.0.1:10250/metrics/cadvisor -k -H "Authorization: Bearer $token"
複製代碼

只須要將這個 token 放到請求頭中就行,而後就能夠看到全部的監控指標了。

能夠看到裏面有不少這樣的標籤的指標存在:

{container="",container_name="",id="/system.slice/tuned.service",image="",name="",namespace="",pod="",pod_name="",state="stopped"}
複製代碼

我徹底沒有搞懂這些是幹啥的,不知道有沒有用,反正我是準備全刪除的。使用 Prometheus 就是有這樣的問題,什麼樣的指標數據都有,巴不得把全部的都暴露出來,若是你是默認使用而沒有管裏面到底有什麼指標數據的話,你可能接收了幾倍的無用數據(對於不少人來說,確實是沒用的,由於歷來都不會關注),形成了大量的資源浪費。

kubelet 除了 /metrics/cadvisor 這個 url 以外,還有一個 /metrics,這是它自己的監控指標而非 pod 的。說實話,裏面的數據我都看不懂,我在考慮要不要接收。

經過這種方式,其餘幾個 k8s 組件你應該都可以訪問了,可是 etcd 不行,它須要驗證客戶端證書。

查詢 etcd 指標頁面

etcd 的指標頁面的 url 也是 /metrics,可是你想要訪問它須要提供證書,由於它會驗證客戶端證書。固然你能夠在它的啓動參數中經過 --listen-metrics-urls http://ip:port 讓監控指標頁使用 http 而非 https,這樣就不用提供證書了。

etcd 雖然部署在容器中,可是因爲使用了 hostNetwork,因此咱們能夠經過直接訪問 master 的 2379 端口訪問它。默認它會採用了 https,所以咱們須要提供它的 peer 證書。若是 k8s 是使用 kubeadm 安裝的,etcd 的證書在 /etc/kubernetes/pki/etcd/ 目錄下。

所以訪問 etcd 的命令爲:

curl https://127.0.0.1:2379/metrics --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/healthcheck-client.crt --key /etc/kubernetes/pki/etcd/healthcheck-client.key
複製代碼

後面咱們須要將這三個文件掛載到 Prometheus 容器中,以便它能收集 etcd 監控數據。

安裝 Prometheus

Prometheus 自己會依賴一些東西,所以在安裝以前咱們必須作一些準備工做。

咱們先建立兩個 configmap,一個是 Prometheus 的配置文件,另外一個是告警的規則文件。配置文件必定要使用 configmap 進行保存,不能直接放在容器中,否則容器掛了配置文件就沒了。

Prometheus 配置文件

先建立 Prometheus 配置文件 configmap prometheus-config.yml,它的內容以下:

apiVersion: v1
data:
  prometheus.yml: |  global:
 evaluation_interval: 30s
 scrape_interval: 30s
 external_labels:
 prometheus: monitoring/k8s
 rule_files:
 - /etc/prometheus/rules/*.yml
 scrape_configs:
 - job_name: prometheus
 honor_labels: false
 kubernetes_sd_configs:
 - role: endpoints
 namespaces:
 names:
 - monitoring
 scrape_interval: 30s
 relabel_configs:
 - action: keep
 source_labels:
 - __meta_kubernetes_service_label_prometheus
 regex: k8s
 - source_labels:
 - __meta_kubernetes_endpoint_address_target_kind
 - __meta_kubernetes_endpoint_address_target_name
 separator: ;
 regex: Pod;(.*)
 replacement: ${1}
 target_label: pod
 - source_labels:
 - __meta_kubernetes_namespace
 target_label: namespace
 - source_labels:
 - __meta_kubernetes_service_name
 target_label: service
 - source_labels:
 - __meta_kubernetes_pod_name
 target_label: pod
 - source_labels:
 - __meta_kubernetes_service_name
 target_label: job
 replacement: ${1}
 - target_label: endpoint
 replacement: web
kind: ConfigMap
metadata:
 name: prometheus
 namespace: monitoring
複製代碼

簡單的說明下這個配置文件的內容:這個配置文件只是一個第一版,能夠看到裏面只有一個 job,就是監控 Prometheus 自己。能夠看到,這裏使用了 kubernetes_sd_configs,使用這個配置能夠自動發現 k8s 中 node、service、pod、endpoint、ingress,併爲其添加監控,更多的內容能夠直接查看官方文檔

這裏使用的是 endpoint 的方式對 Prometheus 自己進行發現,你能夠有疑問了,爲何不直接對自身的 127.0.0.1:9090 進行採集呢?由於考慮到 Prometheus 可能會有多臺,這樣即便有多臺,它們也都在一個 job 下面。

固然,你若是嫌麻煩也能夠直接對自身進行採集,沒有任何問題。而後下面就是一堆的 relabel_configs 配置了,我一個個解釋這些配置是幹啥的。

首先看第一個配置:

- action: keep
 source_labels:
 - __meta_kubernetes_service_label_prometheus
 regex: k8s
複製代碼

你們應該知道,每建立一個 service 就會建立一個對應的 endpoint,可是 prometheus 的 endpoint 的發現會對 k8s 指定名稱空間下全部 endpoint 進行發現,那麼怎麼保證 Prometheus 只發現咱們須要的 endpoint 呢?答案是經過 relabel_configs,這裏 keep 就是幹這個的。

上面配置的意思是隻有 service 的標籤包含 prometheus=k8s,k8s 纔會對其對應的 endpoint 進行採集。因此咱們後面要爲 Prometheus 建立一個 service,而且要爲這個 service 加上 prometheus: k8s 這樣的標籤。

這裏沒有指定 url,Prometheus 會採集默認的 url /metrics

接着看下一段配置:

- source_labels:
 - __meta_kubernetes_endpoint_address_target_kind
 - __meta_kubernetes_endpoint_address_target_name
 separator: ;
 regex: Pod;(.*)
 replacement: ${1}
 target_label: pod
複製代碼

若是 __meta_kubernetes_endpoint_address_target_kind 的值爲 Pod,__meta_kubernetes_endpoint_address_target_name 的值爲 prometheus-0,在它們之間加上一個 ; 以後,它們合起來就是 Pod;prometheus-0。使用正則表達式 Pod;(.*) 對其進行匹配,那麼 ${1} 就是取第一個分組,它值就是 prometheus-0,最後將這個值交給 pod 這個標籤。

所以這一段配置就是爲全部採集到的監控指標增長一個 pod=prometheus-0 的標籤。

若是 __meta_kubernetes_endpoint_address_target_kind 的值不是 Pod,那麼不會添加任何標籤。

後面的配置我想就不用多說了,無非就是將指定的元標籤轉換爲指定的標籤,由於不轉換的話,元標籤會在 relabel 以後都會被幹掉。

建立它:

kubectl apply -f prometheus-config.yml
複製代碼

Prometheus 規則文件

咱們目前不須要任何規則文件,可是因爲會將對應 configmap 掛載進容器中,因此咱們建立一個空的規則文件。

先建立一個 prometheus-config-rulefiles.yml 文件,它的內容以下:

apiVersion: v1
data:
  k8s.yml: ""
kind: ConfigMap
metadata:
 name: prometheus-rulefiles
 namespace: monitoring
複製代碼

建立:

kubectl apply -f prometheus-config-rulefiles.yml
複製代碼

role 和 roleBinding

由於 Prometheus 會使用以前建立的 sa(serviceAccount)prometheus-k8s 運行,那麼光如今 prometheus-k8s 這個 sa 的權限是沒有辦法查看 service 以及 endpoint 的。

咱們使用 kubernetes_sd_config 主要會使用 endpoint 進行發現,所以 prometheus-k8s 必須具有更多的權限。

咱們須要建立更多的 role,並經過 roleBinding 將這些權限綁定到 prometheus-k8s 這個 sa 上,之因此不使用 clusterRole 是爲了權限最小化。

這裏會建立 prometheus-roleConfig.ymlprometheus-roleBindingConfig.ymlprometheus-roleSpecificNamespaces.ymlprometheus-roleBindingSpecificNamespaces.yml 這四個文件,它們的內容以下。

prometheus-roleConfig.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
 name: prometheus-k8s-config
 namespace: monitoring
rules:
 - apiGroups:
 - ""
 resources:
 - configmaps
 verbs:
 - get
複製代碼

prometheus-roleBindingConfig.yml:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
 name: prometheus-k8s-config
 namespace: monitoring
roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: Role
 name: prometheus-k8s-config
subjects:
 - kind: ServiceAccount
 name: prometheus-k8s
 namespace: monitoring
複製代碼

prometheus-roleSpecificNamespaces.yml:

apiVersion: rbac.authorization.k8s.io/v1
items:
 - apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
 name: prometheus-k8s
 namespace: default
 rules:
 - apiGroups:
 - ""
 resources:
 - services
 - endpoints
 - pods
 verbs:
 - get
 - list
 - watch
 - apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
 name: prometheus-k8s
 namespace: kube-system
 rules:
 - apiGroups:
 - ""
 resources:
 - services
 - endpoints
 - pods
 verbs:
 - get
 - list
 - watch
 - apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
 name: prometheus-k8s
 namespace: monitoring
 rules:
 - apiGroups:
 - ""
 resources:
 - services
 - endpoints
 - pods
 verbs:
 - get
 - list
 - watch
kind: RoleList
複製代碼

prometheus-roleBindingSpecificNamespaces.yml:

apiVersion: rbac.authorization.k8s.io/v1
items:
 - apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
 name: prometheus-k8s
 namespace: default
 roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: Role
 name: prometheus-k8s
 subjects:
 - kind: ServiceAccount
 name: prometheus-k8s
 namespace: monitoring
 - apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
 name: prometheus-k8s
 namespace: kube-system
 roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: Role
 name: prometheus-k8s
 subjects:
 - kind: ServiceAccount
 name: prometheus-k8s
 namespace: monitoring
 - apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
 name: prometheus-k8s
 namespace: monitoring
 roleRef:
 apiGroup: rbac.authorization.k8s.io
 kind: Role
 name: prometheus-k8s
 subjects:
 - kind: ServiceAccount
 name: prometheus-k8s
 namespace: monitoring
kind: RoleBindingList
複製代碼

上面的權限中,config 是用來讀 configmap 的,後面的就是 Prometheus 用來進行 k8s 發現時必需要的權限了,最後使用 rulebinding 將這些全部的權限都綁定到 prometheus-k8s 這個 sa 上。

這樣後續 Prometheus 容器訪問 api server 以及集羣內的組件時,就會使用這些權限訪問。

最後應用:

kubectl apply -f prometheus-roleBindingConfig.yml
kubectl apply -f prometheus-roleBindingSpecificNamespaces.yml
kubectl apply -f prometheus-roleConfig.yml
kubectl apply -f prometheus-roleSpecificNamespaces.yml
複製代碼

建立 pv

Prometheus 由於會將數據存儲到磁盤上,所以咱們必須使用 statefulset,這樣就須要一個存儲了,我這裏就直接使用 nfs 了,你可能須要搭建一個,這裏就很少提了。

先建立 prometheus-pv.yml

apiVersion: v1
kind: PersistentVolume
metadata:
 name: prometheus
 labels:
 name: prometheus
spec:
 nfs:
 path: /data/prometheus
 server: 10.1.1.3
 accessModes: ["ReadWriteMany", "ReadWriteOnce"]
 capacity:
 storage: 1Ti
複製代碼

而後應用:

kubectl apply -f prometheus-pv.yml
複製代碼

建立 service

statefulset 必需要一個無頭的 service,同時咱們要進行 endpoint 發現也須要建立 service,建立一個 service 正好知足它們,不過要爲這個 service 添加 prometheus=k8s 這個標籤。

所以建立文件 prometheus-service.yml,它的內容以下:

apiVersion: v1
kind: Service
metadata:
 name: prometheus
 namespace: monitoring
 labels:
 prometheus: k8s
spec:
 clusterIP: None
 ports:
 - name: web
 port: 9090
 protocol: TCP
 targetPort: web
 selector:
 app: prometheus
 type: ClusterIP
複製代碼

上面定義了 app=prometheus 這樣的標籤選擇器,所以 Prometheus 容器必須存在這個標籤。

建立:

kubectl apply -f prometheus-service.yml
複製代碼

建立 etcd secret

若是你不打算監控 etcd,那麼能夠直接跳過,而且將下面 Prometheus yml 文件中的 secret 相關的掛載刪掉。

直接建立一個 secret 就行:

kubectl -n monitoring create secret generic etcd-client-cert --from-file=/etc/kubernetes/pki/etcd/ca.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.crt --from-file=/etc/kubernetes/pki/etcd/healthcheck-client.key
複製代碼

爲了方便後續使用,建議你在這個命令以後加上 --dry-run -o yaml,而後將輸出的內容保存在 prometheus-secret.yml 中。由於加了 --dry-run 以後不會執行,你還須要手動建立:

kubectl apply -f prometheus-secret.yml
複製代碼

部署 Prometheus

到此全部前置工做完成,接下來就能夠直接部署 prometheus 了。先建立文件 prometheus.yml,它的內容以下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
 labels:
 app: prometheus
 prometheus: k8s
 name: prometheus
 namespace: monitoring
spec:
 replicas: 1
 revisionHistoryLimit: 10
 selector:
 matchLabels:
 app: prometheus
 prometheus: k8s
 serviceName: prometheus
 template:
 metadata:
 creationTimestamp: null
 labels:
 app: prometheus
 prometheus: k8s
 spec:
 serviceAccount: prometheus-k8s
 containers:
 - args:
 - --web.console.templates=/etc/prometheus/consoles
 - --web.console.libraries=/etc/prometheus/console_libraries
 - --config.file=/etc/prometheus/config/prometheus.yml
 - --storage.tsdb.path=/prometheus
 - --web.enable-admin-api
 - --storage.tsdb.retention.time=20d
 - --web.enable-lifecycle
 - --storage.tsdb.no-lockfile
 - --web.external-url=http://example.com/
 - --web.route-prefix=/
 image: prom/prometheus:v2.11.1
 imagePullPolicy: IfNotPresent
 livenessProbe:
 failureThreshold: 6
 httpGet:
 path: /-/healthy
 port: web
 scheme: HTTP
 periodSeconds: 5
 successThreshold: 1
 timeoutSeconds: 3
 name: prometheus
 ports:
 - containerPort: 9090
 name: web
 protocol: TCP
 readinessProbe:
 failureThreshold: 120
 httpGet:
 path: /-/ready
 port: web
 scheme: HTTP
 periodSeconds: 5
 successThreshold: 1
 timeoutSeconds: 3
 resources:
 requests:
 memory: 400Mi
 terminationMessagePath: /dev/termination-log
 terminationMessagePolicy: File
 volumeMounts:
 - mountPath: /etc/prometheus/config
 name: config
 readOnly: true
 - mountPath: /prometheus
 name: prometheus-data
              #subPath: prometheus-db
 - mountPath: /etc/prometheus/rules/
 name: prometheus-rulefiles
 - mountPath: /etc/prometheus/secrets/etcd-client-cert
 name: secret-etcd-client-cert
 readOnly: true
 volumes:
 - name: config
 configMap:
 defaultMode: 420
 name: prometheus
 - name: prometheus-rulefiles
 configMap:
 defaultMode: 420
 name: prometheus-rulefiles
 - name: secret-etcd-client-cert
 secret:
 defaultMode: 420
 secretName: etcd-client-cert
 updateStrategy:
 type: RollingUpdate
 volumeClaimTemplates:
 - metadata:
 name: prometheus-data
 spec:
 accessModes:
 - ReadWriteOnce
 resources:
 requests:
 storage: 1Ti
 volumeMode: Filesystem
複製代碼

基礎的 statfulset 相關的知識我就很少提了,說幾個重點吧:

  • --storage.tsdb.retention.time=20d 這個啓動選項表示 Prometheus 所收集的監控數據只保留 20 天,這個值最好不要太大。若是歷史數據保存好久,建議寫到持久存儲中,好比 VictoriaMetrics、thanos、influxdb、opentsdb 等;
  • --web.enable-admin-api 這個啓動選項表示啓動管理員 api,你能夠經過 api 對監控數據進行刪除等;
  • serviceAccount 它的值必須是 prometheus-k8s,否則前面的賦權操做都白乾了;
  • pod 必須存在 app: prometheus 這個標籤,否則沒法被前面建立的 service 選擇到;
  • 掛載了兩個 configmap、一個 secret 還有一個存儲卷。

其餘沒有什麼好說的了,直接幹吧:

kubectl apply -f prometheus.yml
複製代碼

而後等待 Prometheus 啓動成功:

kubectl -n monitoring get pod -w
複製代碼

訪問 Prometheus

啓動成功以後就能夠直接訪問了,咱們先不建立 ingress,而是將 pod 的端口綁定到宿主機上:

kubectl -n monitoring port-forward --address 0.0.0.0 pod/prometheus-0 9090:9090
複製代碼

而後經過訪問當前主機的 9090 端口就能夠打開 Prometheus 頁面。咱們點開 Status,而後選擇 Targets 就能夠發現 Prometheus 自身已經被監控了。

能夠看到,它顯示了額外的 6 個標籤,這些都是咱們前面經過 relabel_configs 配置附加上去的,你如今只要在 Prometheus 查詢任意一條監控指標,都會有這 6 個標籤。若是你以爲這些標籤中有你不須要的,只須要在前面的配置中刪除對應的配置便可。

而後你將鼠標懸浮在這些標籤之上,就能看到全部 relabel 以前全部的元標籤,若是有你須要的,能夠在前面的配置文件中添加響應的配置,將對應的標籤加上去。

你能夠選擇點擊左上角的 Prometheus 回到主頁,而後在下面的查詢框中,隨便輸入一個字母,而後在出現的全部監控指標中隨便點擊一個,就能夠看到它的全部標籤和其對應的值了。

能夠看到,額外的 6 個標籤都存在,從此你能夠經過這些標籤來進行查詢了。

最後,給 Prometheus 建立一個 ingress,文件名爲 prometheus-ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: prometheus
 namespace: monitoring
spec:
 rules:
 - host: example.com
 http:
 paths:
 - path: /
 backend:
 serviceName: prometheus
 servicePort: 9090
複製代碼

注意將上面的 example.com 替換成你 Prometheus 的域名。