Prometheus介紹
Prometheus是一個最初在SoundCloud上構建的開源監控系統 。它現在是一個獨立的開源項目,為了強調這一點,並說明項目的治理結構,Prometheus 於2016年加入CNCF,作為繼Kubernetes之后的第二個托管項目。
特點
- 具有由 metric 名稱和鍵/值對標識的時間序列數據的多維數據模型
- PromQL,有一個靈活的查詢語言
- 不依賴分布式存儲,只和本地磁盤有關
- 通過 HTTP 的服務拉取時間序列數據
- 也支持推送的方式來添加時間序列數據
- 通過服務發現或靜態配置發現目標
- 多種圖形和儀表板支持
組件
Prometheus系統由多個組件組成,其中許多組件是可選的:
- Prometheus Server:用於抓取指標、存儲時間序列數據
- exporter:暴露指標讓任務來抓
- pushgateway:push 的方式將指標數據推送到該網關
- alertmanager:處理報警的報警組件
- adhoc:用於數據查詢
大多數 Prometheus 組件都是用 Go 編寫的,因此很容易構建和部署為靜態的二進制文件。
架構圖
此圖說明prometheus的體系結構及其一些系統組件

整體流程比較簡單,Prometheus 直接接收或者通過中間的 Pushgateway 網關被動獲取指標數據,在本地存儲所有的獲取的指標數據,並對這些數據進行一些規則整理,用來生成一些聚合數據或者報警信息,Grafana 或者其他工具用來可視化這些數據。
安裝
由於 Prometheus 是 Golang 編寫的程序,所以要安裝的話也非常簡單,只需要將二進制文件下載下來直接執行即可,前往地址:https://prometheus.io/download 下載我們對應的版本即可。
Prometheus 是通過一個 YAML 配置文件來進行啟動的,如果我們使用二進制的方式來啟動的話,可以使用下面的命令:
./prometheus --config.file=prometheus.yml
prometheus.yml配置文件
global: scrape_interval: 15s evaluation_interval: 15s rule_files: # - "first.rules" # - "second.rules" scrape_configs: - job_name: prometheus static_configs: - targets: ['localhost:9090']
配置文件中配置的三個模塊:global,rule_files,和scrape_configs
global 模塊是prometheus的全局配置:
- scrape_interval:表示 prometheus 抓取指標數據的頻率,默認是15s,我們可以覆蓋這個值
- evaluation_interval:用來控制評估規則的頻率,prometheus 使用規則產生新的時間序列數據或者產生警報
rule_files 模塊制定了規則所在的位置,prometheus 可以根據這個配置加載規則,用於生成新的時間序列數據或者報警信息,當前我們沒有配置任何規則。
scrape_configs 用於控制 prometheus 監控哪些資源。由於 prometheus 通過 HTTP 的方式來暴露的它本身的監控數據,prometheus 也能夠監控本身的健康情況。在默認的配置里有一個單獨的 job,叫做prometheus,它采集 prometheus 服務本身的時間序列數據。這個 job 包含了一個單獨的、靜態配置的目標:監聽 localhost 上的9090端口。prometheus 默認會通過目標的/metrics路徑采集 metrics。所以,默認的 job 通過 URL:http://localhost:9090/metrics采集 metrics。收集到的時間序列包含 prometheus 服務本身的狀態和性能。如果我們還有其他的資源需要監控的話,直接配置在該模塊下面就可以了。
在kubernetes中部署安裝
這里我們把prometheus相關的服務都部署在kube-ops這個namespace下
1、我們把prometheus.yml中部署成ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config namespace: kube-ops data: prometheus.yml: | global: scrape_interval: 15s scrape_timeout: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090']
2、創建prometheus相關pod資源
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: prometheus namespace: kube-ops labels: app: prometheus spec: template: metadata: labels: app: prometheus spec: containers: - image: prom/prometheus:v2.6.0 name: prometheus imagePullPolicy: IfNotPresent args: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" - "--storage.tsdb.retention=7d" - "--web.enable-admin-api" - "--web.enable-lifecycle" ports: - containerPort: 9090 name: http volumeMounts: - mountPath: "/prometheus" subPath: prometheus name: data - mountPath: "/etc/prometheus" name: config resources: requests: cpu: 1000m memory: 2Gi limits: cpu: 1000m memory: 2Gi securityContext: runAsUser: 0 volumes: - name: config configMap: name: prometheus-config - name: data persistentVolumeClaim: claimName: prometheus
- 通過
storage.tsdb.path指定了 TSDB 數據的存儲路徑 - 通過
storage.tsdb.retention設置了保留多長時間的數據 通過web.enable-admin-api參數可以用來開啟對 admin api 的訪問權限- 通過
web.enable-lifecycle非常重要,用來開啟支持熱更新的,有了這個參數之后,prometheus.yml 配置文件只要更新了,通過執行http://localhost:9090/-/reload就會立即生效,所以一定要加上這個參數
我們這里將 prometheus.yml 文件對應的 ConfigMap 對象通過 volume 的形式掛載進了 Pod,這樣 ConfigMap 更新后,對應的 Pod 里面的文件也會熱更新的,然后我們再執行上面的 reload 請求,Prometheus 配置就生效了
為了將時間序列數據進行持久化,我們將數據目錄和一個 pvc 對象進行了綁定,所以我們需要提前創建好這個 pvc 對象(這里我們使用的storageclass)
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: prometheus namespace: kube-ops spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: "rook-ceph-block"
除了上面的注意事項外,我們這里還需要配置 rbac 認證,因為我們需要在 prometheus 中去訪問 Kubernetes 的相關信息,所以我們這里管理了一個名為 prometheus 的 serviceAccount 對象:
apiVersion: v1 kind: ServiceAccount metadata: name: prometheus namespace: kube-ops --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus rules: - apiGroups: - "" resources: - nodes - services - endpoints - pods - nodes/proxy verbs: - get - list - watch - apiGroups: - "" resources: - configmaps - nodes/metrics verbs: - get - nonResourceURLs: - /metrics verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: prometheus roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus subjects: - kind: ServiceAccount name: prometheus namespace: kube-ops
由於我們要獲取的資源信息,在每一個 namespace 下面都有可能存在,所以我們這里使用的是 ClusterRole 的資源對象,值得一提的是我們這里的權限規則聲明中有一個nonResourceURLs的屬性,是用來對非資源型 metrics 進行操作的權限聲明。
還有一個要注意的地方是我們這里必須要添加一個securityContext的屬性,將其中的runAsUser設置為0,這是因為現在的 prometheus 運行過程中使用的用戶是 nobody,否則會出現下面的permission denied之類的權限錯誤:
level=error ts=2018-10-22T14:34:58.632016274Z caller=main.go:617 err="opening storage failed: lock DB directory: open /data/lock: permission denied"
這里我們還需要一個svc服務,作為外部訪問。
apiVersion: v1 kind: Service metadata: name: prometheus namespace: kube-ops labels: app: prometheus spec: selector: app: prometheus type: NodePort ports: - name: web port: 9090 targetPort: http
文件准備完成后我們可以使用以下命令構建
kubectl apply -f .
訪問
kubectl get svc -n kube-ops NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE prometheus NodePort 10.111.210.47 <none> 9090:31990/TCP 7d
我們可以通過任意節點訪問31990端口即可訪問

Kubernetes 集群的監控方案
目前主要有以下集中方案
- Heapster: 是一個集群范圍的監控和數據聚合工具,以 Pod 的形式運行在集群中。除了 Kubelet/cAdvisor 之外,我們還可以向 Heapster 添加其他指標源數據比如 kube-state-metrics
- cAdvisor: 是
Google開源的容器資源監控和性能分析工具,它是專門為容器而生,本身也支持 Docker 容器,在 Kubernetes 中,我們不需要單獨去安裝,cAdvisor 作為 kubelet 內置的一部分程序可以直接使用。 - Kube-state-metrics: 通過監聽 API Server 生成有關資源對象的狀態指標,比如 Deployment、Node、Pod,需要注意的是 kube-state-metrics 只是簡單提供一個 metrics 數據,並不會存儲這些指標數據,所以我們可以使用 Prometheus 來抓取這些數據然后存儲。
- metrics-server: 也是一個集群范圍內的資源數據聚合工具,是 Heapster 的替代品,同樣的,metrics-server 也只是顯示數據,並不提供數據存儲服務。
不過 kube-state-metrics 和 metrics-server 之間還是有很大不同的,二者的主要區別如下:
- kube-state-metrics 主要關注的是業務相關的一些元數據,比如 Deployment、Pod、副本狀態等
- metrics-server 主要關注的是資源度量 API 的實現,比如 CPU、文件描述符、內存、請求延時等指標。
監控kubernetes集群節點
對於集群的監控一般我們需要考慮以下幾個方面:
- Kubernetes 節點的監控:比如節點的 cpu、load、disk、memory 等指標
- 內部系統組件的狀態:比如 kube-scheduler、kube-controller-manager、kubedns/coredns 等組件的詳細運行狀態
- 編排級的 metrics:比如 Deployment 的狀態、資源請求、調度和 API 延遲等數據指標
這里通過 Prometheus 來采集節點的監控指標數據,可以通過node_exporter來獲取,顧名思義,node_exporter 抓喲就是用於采集服務器節點的各種運行指標的,目前 node_exporter 支持幾乎所有常見的監控點,比如 conntrack,cpu,diskstats,filesystem,loadavg,meminfo,netstat等,詳細的監控點列表可以參考其Github repo。
我們可以通過 DaemonSet 控制器來部署該服務,這樣每一個節點都會自動運行一個這樣的 Pod,如果我們從集群中刪除或者添加節點后,也會進行自動擴展。
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: node-exporter namespace: kube-ops labels: name: node-exporter spec: template: metadata: labels: name: node-exporter spec: hostPID: true hostIPC: true hostNetwork: true containers: - name: node-exporter image: prom/node-exporter:v0.17.0 ports: - containerPort: 9100 resources: requests: cpu: 0.15 securityContext: privileged: true args: - --path.procfs - /host/proc - --path.sysfs - /host/sys - --collector.filesystem.ignored-mount-points - '"^/(sys|proc|dev|host|etc)($|/)"' volumeMounts: - name: dev mountPath: /host/dev - name: proc mountPath: /host/proc - name: sys mountPath: /host/sys - name: rootfs mountPath: /rootfs tolerations: - key: "node-role.kubernetes.io/master" operator: "Exists" effect: "NoSchedule" volumes: - name: proc hostPath: path: /proc - name: dev hostPath: path: /dev - name: sys hostPath: path: /sys - name: rootfs hostPath: path: /
由於我們要獲取到的數據是主機的監控指標數據,而我們的 node-exporter 是運行在容器中的,所以我們在 Pod 中需要配置一些 Pod 的安全策略,這里我們就添加了hostPID: true、hostIPC: true、hostNetwork: true3個策略,用來使用主機的 PID namespace、IPC namespace 以及主機網絡,這些 namespace 就是用於容器隔離的關鍵技術,要注意這里的 namespace 和集群中的 namespace 是兩個完全不相同的概念。
另外我們還將主機的/dev、/proc、/sys這些目錄掛載到容器中,這些因為我們采集的很多節點數據都是通過這些文件夾下面的文件來獲取到的,比如我們在使用top命令可以查看當前cpu使用情況,數據就來源於文件/proc/stat,使用free命令可以查看當前內存使用情況,其數據來源是來自/proc/meminfo文件。
另外由於我們集群使用的是 kubeadm 搭建的,所以如果希望 master 節點也一起被監控,則需要添加響應的容忍。
創建上面的資源對象即可:
$ kubectl apply -f node-exporter.yaml $ kubectl get pods -n kube-ops -o wide | grep node-exporter node-exporter-48b6g 1/1 Running 0 7d 172.16.138.42 k8s-node02 node-exporter-4swrs 1/1 Running 0 7d 172.16.138.43 k8s-node03 node-exporter-4w2dd 1/1 Running 0 7d 172.16.138.40 k8s-master node-exporter-fcp9x 1/1 Running 0 7d 172.16.138.41 k8s-node01
部署完成后,我們可以看到在3個節點上都運行了一個 Pod,有的同學可能會說我們這里不需要創建一個 Service 嗎?我們應該怎樣去獲取/metrics數據呢?我們上面是不是指定了hostNetwork=true,所以在每個節點上就會綁定一個端口 9100,我們可以通過這個端口去獲取到監控指標數據:
服務發現
由於我們這里3個節點上面都運行了 node-exporter 程序,如果我們通過一個 Service 來將數據收集到一起用靜態配置的方式配置到 Prometheus 去中,就只會顯示一條數據,我們得自己在指標數據中去過濾每個節點的數據,那么有沒有一種方式可以讓 Prometheus 去自動發現我們節點的 node-exporter 程序,並且按節點進行分組呢?是有的,就是我們前面和大家提到過的服務發現。
在 Kubernetes 下,Promethues 通過與 Kubernetes API 集成,目前主要支持5中服務發現模式,分別是:Node、Service、Pod、Endpoints、Ingress。
但是要讓 Prometheus 也能夠獲取到當前集群中的所有節點信息的話,我們就需要利用 Node 的服務發現模式,同樣的,在 prometheus.yml 文件中配置如下的 job 任務即可:
- job_name: "kubernetes-nodes" kubernetes_sd_configs: - role: node relabel_configs: - source_labels: [__address__] regex: '(.*):10250' replacement: '${1}:9100' target_label: __address__ action: replace
- action: labelmap regex: __meta_kubernetes_node_label_(.+)
通過指定kubernetes_sd_configs的模式為node,Prometheus 就會自動從 Kubernetes 中發現所有的 node 節點並作為當前 job 監控的目標實例,發現的節點/metrics接口是默認的 kubelet 的 HTTP 接口。
配置文件說明:
這里就是一個正則表達式,去匹配__address__,然后將 host 部分保留下來,port 替換成了9100。
因為我們是通過prometheus 去發現 Node 模式的服務的時候,訪問的端口默認是10250,而現在該端口下面已經沒有了/metrics指標數據了,因為我們是要去配置上面通過node-exporter抓取到的節點指標數據,而我們上面是不是指定了hostNetwork=true,所以在每個節點上就會綁定一個端口9100,所以我們應該將這里的10250替換成9100。
這里我們就需要使用到 Prometheus 提供的relabel_configs中的replace能力了,relabel 可以在 Prometheus 采集數據之前,通過Target 實例的 Metadata 信息,動態重新寫入 Label 的值。除此之外,我們還能根據 Target 實例的 Metadata 信息選擇是否采集或者忽略該 Target 實例。比如我們這里就可以去匹配__address__這個 Label 標簽,然后替換掉其中的端口。
通過labelmap這個屬性來將 Kubernetes 的 Label 標簽添加為 Prometheus 的指標標簽,添加了一個 action 為labelmap,正則表達式是__meta_kubernetes_node_label_(.+)的配置,這里的意思就是表達式中匹配都的數據也添加到指標數據的 Label 標簽中去。
對於 kubernetes_sd_configs 下面可用的標簽如下:
- __meta_kubernetes_node_name:節點對象的名稱
- __meta_kubernetes_node_label:節點對象中的每個標簽
- __meta_kubernetes_node_annotation:來自節點對象的每個注釋
- __meta_kubernetes_node_address:每個節點地址類型的第一個地址(如果存在) *
prometheus 的 ConfigMap 更新完成后,同樣的我們執行 reload 操作,讓配置生效:
$ kubectl delete -f prome-cm.yaml $ kubectl create -f prome-cm.yaml $ kubectl get svc -n kube-ops $ curl -X POST "http://10.111.210.47:9090/-/reload"
配置生效后,我們再去 prometheus 的 dashboard 中查看 Targets 是否能夠正常抓取數據,訪問任意節點IP:30358:

另外由於 kubelet 也自帶了一些監控指標數據,所以我們這里也把 kubelet 的監控任務也一並配置上:
- job_name: 'kubernetes-kubelet' kubernetes_sd_configs: - role: node scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - action: labelmap regex: __meta_kubernetes_node_label_(.+)
上面的配置和我們之前配置 node-exporter 的時候幾乎是一樣的,區別是我們這里使用了 https 的協議,另外需要注意的是配置了 ca.cart 和 token 這兩個文件,這兩個文件是 Pod 啟動后自動注入進來的,通過這兩個文件我們可以在 Pod 中訪問 apiserver。
現在我們再去更新下配置文件,執行 reload 操作,讓配置生效,然后訪問 Prometheus 的 Dashboard 查看 Targets 路徑:

監控 Kubernetes 集群應用
exporter 監控應用
我們這里通過一個redis-exporter的服務來監控 redis 服務,對於這類應用,我們一般會以 sidecar 的形式和主應用部署在同一個 Pod 中,比如我們這里來部署一個 redis 應用,並用 redis-exporter 的方式來采集監控數據供 Prometheus 使用。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: redis namespace: kube-ops spec: template: metadata: annotations: prometheus.io/scrape: "true" prometheus.io/port: "9121" labels: app: redis spec: containers: - name: redis image: redis:4 resources: requests: cpu: 100m memory: 100Mi ports: - containerPort: 6379 - name: redis-exporter image: oliver006/redis_exporter:latest resources: requests: cpu: 100m memory: 100Mi ports: - containerPort: 9121 --- kind: Service apiVersion: v1 metadata: name: redis namespace: kube-ops spec: selector: app: redis ports: - name: redis port: 6379 targetPort: 6379 - name: prom port: 9121 targetPort: 9121
可以看到上面我們在 redis 這個 Pod 中包含了兩個容器,一個就是 redis 本身的主應用,另外一個容器就是 redis_exporter。現在直接創建上面的應用:
$ kubectl create -f prome-redis.yaml deployment.extensions "redis" created service "redis" created
我們可以通過 9121 端口來校驗是否能夠采集到數據:
$ curl 10.104.131.44:9121/metrics # HELP go_gc_duration_seconds A summary of the GC invocation durations. # TYPE go_gc_duration_seconds summary go_gc_duration_seconds{quantile="0"} 0 go_gc_duration_seconds{quantile="0.25"} 0 go_gc_duration_seconds{quantile="0.5"} 0 go_gc_duration_seconds{quantile="0.75"} 0 go_gc_duration_seconds{quantile="1"} 0 go_gc_duration_seconds_sum 0 go_gc_duration_seconds_count 0 ...... # HELP redis_used_cpu_user_children used_cpu_user_childrenmetric # TYPE redis_used_cpu_user_children gauge redis_used_cpu_user_children{addr="redis://localhost:6379",alias=""} 0
同樣的,現在我們只需要更新 Prometheus 的配置文件:
- job_name: 'redis' static_configs: - targets: ['redis:9121']
配置文件更新后,重新加載:
$ kubectl delete -f prome-cm.yaml $ kubectl create -f prome-cm.yaml $ curl -X POST "http://10.111.210.47:9090/-/reload"
Grafana 的安裝使用
前面我們使用 Prometheus 采集了 Kubernetes 集群中的一些監控數據指標,我們也嘗試使用promQL語句查詢出了一些數據,並且在 Prometheus 的 Dashboard 中進行了展示,但是明顯可以感覺到 Prometheus 的圖表功能相對較弱,所以一般情況下我們會一個第三方的工具來展示這些數據,今天我們要和大家使用到的就是grafana。
安裝
grafana 是一個可視化面板,有着非常漂亮的圖表和布局展示,功能齊全的度量儀表盤和圖形編輯器,支持 Graphite、zabbix、InfluxDB、Prometheus、OpenTSDB、Elasticsearch 等作為數據源,比 Prometheus 自帶的圖表展示功能強大太多,更加靈活,有豐富的插件,功能更加強大。
接下來我們就來直接安裝,同樣的,我們將 grafana 安裝到 Kubernetes 集群中,第一步同樣是去查看 grafana 的 docker 鏡像的介紹,我們可以在 dockerhub 上去搜索,也可以在官網去查看相關資料,鏡像地址如下:https://hub.docker.com/r/grafana/grafana/,我們可以看到介紹中運行 grafana 容器的命令非常簡單:
$ docker run -d --name=grafana -p 3000:3000 grafana/grafana
我們將部署grafana的pod資源
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: grafana namespace: kube-ops labels: app: grafana spec: revisionHistoryLimit: 10 template: metadata: labels: app: grafana spec: containers: - name: grafana image: grafana/grafana:5.4.2 imagePullPolicy: IfNotPresent ports: - containerPort: 3000 name: grafana env: - name: GF_SECURITY_ADMIN_USER value: admin - name: GF_SECURITY_ADMIN_PASSWORD value: admin321 readinessProbe: failureThreshold: 10 httpGet: path: /api/health port: 3000 scheme: HTTP initialDelaySeconds: 60 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 30 livenessProbe: failureThreshold: 3 httpGet: path: /api/health port: 3000 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 resources: limits: cpu: 100m memory: 256Mi requests: cpu: 100m memory: 256Mi volumeMounts: - mountPath: /var/lib/grafana subPath: grafana name: storage securityContext: fsGroup: 472 runAsUser: 472 volumes: - name: storage persistentVolumeClaim: claimName: grafana
我們使用了最新的鏡像grafana/grafana:5.4.2,然后添加了監控檢查、資源聲明,另外兩個比較重要的環境變量GF_SECURITY_ADMIN_USER和GF_SECURITY_ADMIN_PASSWORD,用來配置 grafana 的管理員用戶和密碼的,由於 grafana 將 dashboard、插件這些數據保存在/var/lib/grafana這個目錄下面的,所以我們這里如果需要做數據持久化的話,就需要針對這個目錄進行 volume 掛載聲明,其他的和我們之前的 Deployment 沒什么區別,由於上面我們剛剛提到的 Changelog 中 grafana 的 userid 和 groupid 有所變化,所以我們這里需要增加一個securityContext的聲明來進行聲明。
當然如果要使用一個 pvc 對象來持久化數據,我們就需要添加一個可用的 pv 供 pvc 綁定使用:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: grafana namespace: kube-ops annotations: volume.beta.kubernetes.io/storage-class: "rook-ceph-block" spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: "rook-ceph-block"
最后,我們需要對外暴露 grafana 這個服務,所以我們需要一個對應的 Service 對象,當然用 NodePort 或者再建立一個 ingress 對象都是可行的:
apiVersion: v1 kind: Service metadata: name: grafana namespace: kube-ops labels: app: grafana spec: type: NodePort ports: - port: 3000 selector: app: grafana
現在我們直接創建上面的這些資源對象:
$ kubectl create -f .
這個時候我們可以查看 Service 對象啟動的端口:
kubectl get svc -n kube-ops NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana NodePort 10.97.81.127 <none> 3000:30489/TCP 5d prometheus NodePort 10.111.210.47 <none> 9090:31990/TCP 7d
這里我們看到grafana啟動端口是30489。我們可以通過任意節點+30489訪問

由於上面我們配置了管理員的,所以第一次打開的時候會跳轉到登錄界面,然后就可以用上面我們配置的兩個環境變量的值來進行登錄了。
配置
接下來點擊Add data source進入添加數據源界面。
我們這個地方配置的數據源是 Prometheus,所以選擇這個 Type 即可,給改數據源添加一個 name:prometheus,最主要的是下面HTTP區域是配置數據源的訪問模式。
訪問模式是用來控制如何處理對數據源的請求的:
- 服務器(Server)訪問模式(默認):所有請求都將從瀏覽器發送到 Grafana 后端的服務器,后者又將請求轉發到數據源,通過這種方式可以避免一些跨域問題,其實就是在 Grafana 后端做了一次轉發,需要從Grafana 后端服務器訪問該 URL。
- 瀏覽器(Browser)訪問模式:所有請求都將從瀏覽器直接發送到數據源,但是有可能會有一些跨域的限制,使用此訪問模式,需要從瀏覽器直接訪問該 URL。
由於我們這個地方 Prometheus 通過 NodePort 的方式的對外暴露的服務,所以我們這個地方是不是可以使用瀏覽器訪問模式直接訪問 Prometheus 的外網地址,但是這種方式顯然不是最好的,相當於走的是外網,而我們這里 Prometheus 和 Grafana 都處於 kube-ops 這同一個 namespace 下面,是不是在集群內部直接通過 DNS 的形式就可以訪問了,而且還都是走的內網流量,所以我們這里用服務器訪問模式顯然更好,數據源地址:http://prometheus:9090(因為在同一個 namespace 下面所以直接用 Service 名也可以),然后其他的配置信息就根據實際情況了,比如 Auth 認證,我們這里沒有,所以跳過即可,點擊最下方的Save & Test提示成功證明我們的數據源配置正確:
數據源添加完成后,就可以來添加 Dashboard 了。
配置Dashboard
同樣,切換到主頁,我們可以根據自己的需求手動新建一個 Dashboard,除此之外,grafana 的官方網站上還有很多公共的 Dashboard 可以供我們使用,我們這里可以使用Kubernetes cluster monitoring (via Prometheus)(dashboard id 為162)這個 Dashboard 來展示 Kubernetes 集群的監控信息,在左側側邊欄 Create 中點擊import導入:

接下來輸入162號導入(我現在已經導入,所以報一存在)

需要注意的是在執行上面的 import 之前要記得選擇我們的prometheus這個名字的數據源,執行import操作,就可以進入到 dashboard 頁面:

如果這里數據沒出現有兩個原因:
1、時間選擇UTC時間

查詢語句不正確
例如點擊Edit的,我們可以看到查詢語句
(sum(node_memory_MemTotal) - sum(node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached) ) / sum(node_memory_MemTotal) * 100
這就是我們之前在 Prometheus 里面查詢的promQL語句,我們可以將上面的查詢語句復制到 Prometheus 的 Graph 頁面進行查詢,其實可以預想到是沒有對應的數據的,因為我們用node_exporter采集到的數據指標不是node_memory_MemTotal關鍵字,而是node_memory_MemTotal_bytes,將上面的promQL語句做相應的更改:

接下來按照此方法,依次修改Dashboard中的其他圖標。

除此之外,我們也可以前往 grafana dashboard 的頁面去搜索其他的關於 Kubernetes 的監控頁面,地址:https://grafana.com/dashboards,比如id 為747和741的這兩個 dashboard。
