[TOC]html
基於 RED方法 和 USE 方法 對如下四類指標進行分析:node
在Kubernetes中,cAdvisor嵌入到kubelet中,本文使用 USE 方法對容器的指標進行分析。linux
USE方法表明golang
cAdvisor提供的「容器」指標最終是底層Linux cgroup提供的。就像節點指標同樣,不少很詳細。可是咱們通常對CPU,內存,網絡和磁盤感興趣數據庫
對於CPU利用率,Kubernetes僅爲咱們提供了每一個容器的三個指標api
全部這些指標都是couter類型,須要對其rate算出使用率嗎.緩存
下面的查詢展現每一個容器正在使用的CPU:bash
sum( rate(container_cpu_usage_seconds_total [5m])) by(container_name)
若是您定義了CPU的 limit 值,計算飽和度將變得容易得多。服務器
當容器超出其CPU限制時,Linux運行時將「限制」該容器並在container_cpu_cfs_throttled_seconds_total指標中記錄其被限制的時間網絡
sum( rate(container_cpu_cfs_throttled_seconds_total[5m])) by (container_name)
就像node_exporter同樣,cAdvisor不會暴露CPU錯誤。
cAdvisor中提供的內存指標是從node_exporter公開的43個內存指標的子集。如下是容器內存指標:
你可能認爲使用container_memory_usage_bytes來計算內存使用率,可是這個指標還包括了文件系統緩存,是不許確的。更準確的是container_memory_working_set_bytes,他是 OOM 所關心的指標
sum(container_memory_working_set_bytes {name!〜「 POD」})by name
在上面的查詢中,咱們須要排除名稱包含「 POD」的容器。這是此容器的父級cgroup,將跟蹤pod中全部容器的統計信息。
和 CPU 的飽和度計算類似,可是和 CPU 不一樣,沒法直接使用指標,由於 OOM 後 container 會被殺掉,可使用以下查詢:
sum(container_memory_working_set_bytes) by (container_name) / sum(label_join(kube_pod_container_resource_limits_memory_bytes, "container_name", "", "container")) by (container_name)
這裏使用label_join組合了 kube-state-metrics 的指標
kubelet不會暴露內存錯誤。
在處理磁盤I / O時,咱們首先經過查找和讀寫來跟蹤全部磁盤利用率。
cAdvisor有如下指標:
最基本的磁盤I / O利用率是讀/寫的字節數:
sum(rate(container_fs_writes_bytes_total[5m])) by (container_name,device) sum(rate(container_fs_reads_bytes_total[5m])) by (container_name,device)
對這些求和,以得到每一個容器的整體磁盤I / O利用率。
由於沒有磁盤的使用限制,沒法對容器磁盤飽和度作衡量
Kubelet沒有公開足夠的細節,沒法查看錯誤數
容器的網絡利用率,能夠選擇以字節爲單位仍是以數據包爲單位。網絡的指標有些不一樣,由於全部網絡請求都在Pod級別上進行,而不是在容器上進行
下面查詢將按pod名稱顯示每一個pod的網絡利用率:
sum(rate(container_network_receive_bytes_total[5m])) by (name) sum(rate(container_network_transmit_bytes_total[5m])) by (name)
一樣,在不知道最大網絡帶寬是多少的狀況下,網絡的飽和度定義不明確。您也許可使用丟棄的數據包代替,表示當前已經飽和。
cAdvisor提供了
node-exporter能夠檢查節點的核心指標,從利用率,飽和度和錯誤的角度來看CPU,內存,磁盤和網絡的監控指標
因爲node_exporter提供了近1000個指標,有時很難知道要關心哪些。您的系統有哪些重要指標?分析的方法有多種多樣,咱們能夠簡化和抽象爲如下幾類:四個黃金信號,USE方法和RED方法。
Google在「SRE Handbook」中以「四個黃金信號」的概念爲咱們提供了一個論述:
當我第一次嘗試將四個黃金信號應用於系統中的指標時,我常常被其中的一些術語以及它們如何應用於系統中的各個節點和應用程序所絆倒。
CPU的延遲或流量是多少?Kafka主題的飽和度是多少?
要定義應用程序的飽和度,咱們常常須要考慮應用程序使用的基礎資源的飽和度。這些資源是什麼,咱們如何對其進行監控?咱們可使用USE方法
Brendan Gregg在解釋系統資源時如何考慮利用率、飽和度、錯誤方面作得很是出色。
他給出如下定義:
他建議(但沒有規定)確切地表示在Unix系統的上下文中哪些度量表示利用率,飽和度和錯誤。本文的其他部分,我將USE方法應用於Kubernetes節點中的資源。
儘管USE方法針對的是資源,具備嚴格限制的實際物理資源,可是對於在這些資源上運行的軟件而言,這是不完整的描述。這就是RED方法的用武之地。
Tom Wilkie解釋RED方法爲:
從表面上看,RED方法彷佛與USE方法和四個黃金信號很是類似。何時使用USE vs RED?
USE方法用於資源,RED方法用於服務 — Tom Wilkie
如今,咱們有兩種方法能夠幫助您選擇要注意的指標。這東西是資源仍是應用程序?
集羣中的節點具備資源。您的節點在Kubernetes羣集中提供的最重要資源是CPU,內存,網絡和磁盤。
讓咱們將USE方法應用於全部這些方法。
node_exporter指標node_cpu會跟蹤全部10個CPU mode 在每一個內核上花費的全部CPU時間。這些mode是:user, system, nice, idle, iowait, guest, guest_nice, steal, soft_irq and irq。
要計算您的Kubernetes集羣中主機的cpu利用率,咱們但願對全部mode進行累加, idle, iowait, guest, and guest_nice除外。PromQL看起來像這樣:
sum(rate( node_cpu{mode!=」idle」, mode!=」iowait」, mode!~」^(?:guest.*)$」 }[5m])) BY (instance)
關於此查詢的一些注意事項:
cpu 提供的飽和度,是Unix的平均負載。平均負載是正在運行的進程數加上正在等待運行的進程數。一樣,布倫丹·格雷格(Brendan Greg)在Linux平均負載方面有「很長的論述](http://www.brendangregg.com/b...。
node_load1,node_load5和node_load15分別表明一、5和15分鐘的平均負載。該指標是一個gauge,已經爲您進行了平均。做爲一個獨立的指標,知道節點有多少個CPU有些用處。
平均負載是10到底好仍是壞?這視狀況而定。若是將平均負載除以機器擁有的CPU數量,則能夠近似得出系統的CPU飽和度。
node_exporter不會直接公開節點CPU的數量,可是若是僅計算上述一種CPU模式(例如「 system」),則能夠按節點獲取CPU數量:
count(node_cpu{mode="system"}) by (node)
如今,您能夠經過以百分比表示的節點上的CPU數量來規範化node_load1指標:
sum(node_load1) by (node) / count(node_cpu{mode="system"}) by (node) * 100
彷佛咱們的系統之一的CPU飽和度高達250%以上。須要調查一下!
node_exporter不顯示有關CPU錯誤的任何信息。
因爲已知節點上的物理內存量,所以彷佛能夠更容易地推斷出內存利用率和飽和度。可沒有那麼容易!node_exporter爲咱們提供了43個node_memory_ *指標供您使用!
Linux系統上的可用內存量不只僅是報告的「free」內存指標。Unix系統嚴重依賴於應用程序未使用的內存來共享代碼(buffers)和緩存磁盤頁面(cached)。所以可用內存的一種度量是:
sum(node_memory_MemFree + node_memory_Cached + node_memory_Buffers)
較新的Linux內核(3.14以後)公開了更好的可用內存指標node_memory_MemAvailable。
將其除以節點上可用的總內存,便可獲得可用內存的百分比,而後從1中減去以得出節點內存利用率的度量:
1 - sum(node_memory_MemAvailable) by (node) / sum(node_memory_MemTotal) by (node)
內存的飽和度是一個複雜的話題。從理論上講,Unix系統具備無限數量的「虛擬內存」。若是對內存系統的需求過多,則操做系統將最近未使用的內存page返給硬盤「page to disk」。用某種說法,這稱爲「going into swap」。在實踐中您永遠不會想要這個
密切關注節點正在執行的分頁數量能夠是內存飽和度的一種度量。
node_exporter指標node_vmstat_pgpgin和node_vmstat_pgpgout顯示節點的分頁活動量。這是一個不完整的指標,由於對於依賴於Linux shared page cache的任何程序使用,內存分頁都是正常活動。
Kubernetes爲咱們提供了一些其餘工具來限制集羣中使用的內存量。即 limit 限制,容器資源請求和限制(若是實施得當)能夠確保您的節點永遠不會開始交換。我將在之後的文章中解決這些問題。
內存錯誤,在某些硬件上Linux和node_exporter能夠經過EDAC,錯誤檢測和糾正報告ECC內存。若是支持,則指標爲:
node_edac_correctable_errors_total node_edac_uncorrectable_errors_total node_edac_csrow_correctable_errors_total node_edac_csrow_uncorrectable_errors_total
這些指標在個人機器上沒法使用
當咱們談論磁盤利用率和飽和度時,咱們須要考慮另外兩個方面:磁盤容量和磁盤吞吐量。
磁盤容量的飽和度和利用率很是簡單;它僅是對所用字節數的一種度量,以可用百分比表示
sum(node_filesystem_free{mountpoint="/"}) by (node, mountpoint) / sum(node_filesystem_size{mountpoint="/"}) by (node, mountpoint)
磁盤吞吐量的利用率和飽和度尚不清楚。
若是使用旋轉磁盤,固態硬盤,RAID,網絡鏈接的硬盤或網絡塊,則須要注意不一樣的參數。正如咱們將在網絡中看到的那樣,飽和度很難在不知道底層硬件的特性的狀況下進行計算,而底層硬件的特性一般對於內核是不可知的。
每一個設備的node_exporters會公開一些磁盤寫入量之類的指標,還有
磁盤吞吐量顯然是一個複雜的問題,您選擇的指標將取決於硬件以及正在運行的工做負載的類型
無
無
咱們要解決的最後一個資源是網絡
根據您的工做量,您可能對發送流量和接收流量比較感興趣。如今我將利用率定義爲已發送和已接收的總和。該查詢將按節點爲您提供全部網絡接口的每秒字節數:
sum(rate(node_network_receive_bytes[5m])) by (node) + sum(rate(node_network_transmit_bytes[5m])) by (node)
不知道網絡的容量,飽和度將很難肯定。咱們可使用丟棄的數據包做爲飽和度的側面論證:
sum(rate(node_network_receive_drop[5m])) by (node) + sum(rate(node_network_transmit_drop[5m])) by (node)
kube-apiserver 是集羣全部請求的入口,指標的分析能夠反應集羣的健康狀態。
Apiserver 的指標能夠分爲如下幾大類:
基於 RED 方法,評估 apiserver 服務的一些指標:
Rate 速率
sum(rate(apiserver_request_count[5m])) by (resource, subresource, verb)
該查詢會列出Kubernetes資源各類操做的五分鐘的速率。操做有:WATCH,PUT,POST,PATCH,LIST,GET,DELETE和CONNECT
Error 錯誤
rate(apiserver_request_count{code=~"^(?:5..)$"}[5m]) / rate(apiserver_request_count[5m])
此查詢獲取5分鐘內錯誤率與請求率的比率
Duration 請求時間
histogram_quantile(0.9, sum(rate(apiserver_request_latencies_bucket[5m])) by (le, resource, subresource, verb) ) / 1e+06
查看 90%狀況下請求的時間分佈
全部資源的請求都會被 apiserver 中的 controller 處理,controller 維護了隊列,隊列的一些指標能夠反應資源處理的速度等指標
以apiserver_admission_controller爲例:
API Server對etcd 的讀寫有緩存
apiserver 是 go 程序,目前全部 prometheus 採集的指標都會包含 golang 程序指標,如:
訪問 apiserver 的 metric 時須要的參數
https://docs.signalfx.com/en/...
https://blog.freshtracks.io/a...
Kubernetes使用etcd來存儲集羣中組件的全部狀態,它是 Kubernetes數據庫,監視etcd的性能和行爲應該是整個Kubernetes監控計劃的一部分,Etcd是用Go語言編寫的,而且與Kubernetes的其餘服務同樣,都是通過精心設計的,並使用Prometheus格式公開其指標。
由於 Etcd 是數據中心,所以訪問 metrics 時須要配置鑑權,以防數據外泄。
etcd服務器指標分爲幾個主要類別:
Etcd是一個分佈式鍵值存儲。它使用 Rafe協議來選主。Leader能夠響應某些事件(例如節點從新啓動)而進行更改,從新在Member中選舉Leader。更換Leader是很正常的,可是過多的Leader變動也是問題的徵兆,多是網絡問題致使的網絡分區等
要確認Leader是否選出,etcd_server_has_leader值必須是1,不然就沒有leader。這是要配置的告警規則:
# alert if any etcd instance has no leader ALERT NoLeader IF etcd_server_has_leader{job="etcd"} == 0 FOR 1m LABELS { severity = "critical" } ANNOTATIONS { summary = "etcd member has no leader", description = "etcd member {{ $labels.instance }} has no leader", }
Leader變動可使用 etcd_server_leader_changes_seen_total指標,能夠經過如下PromQL查詢:
sum(rate(etcd_server_leader_changes_seen_total[5m]))
這個值應該始終爲 0,報警規則應該設置爲:
# alert if there are lots of leader changes ALERT HighNumberOfLeaderChanges IF increase(etcd_server_leader_changes_seen_total{job="etcd"}[1h]) > 3 LABELS { severity = "warning" } ANNOTATIONS { summary = "a high number of leader changes within the etcd cluster are happening", description = "etcd instance {{ $labels.instance }} has seen {{ $value }} leader changes within the last hour", }
發送到etcd的寫入和配置更改稱爲投票。Raft 協議確保將其正確提交到集羣中。相關 metric 有:
失敗數目過多應該報警,報警規則應該配置爲:
# alert if there are several failed proposals within an hour ALERT HighNumberOfFailedProposals IF increase(etcd_server_proposals_failed_total{job="etcd"}[1h]) > 5 LABELS { severity = "warning" } ANNOTATIONS { summary = "a high number of proposals within the etcd cluster are failing", description = "etcd instance {{ $labels.instance }} has seen {{ $value }} proposal failures within the last hour", }
磁盤性能是etcd服務器性能的主要衡量指標,由於在follwer能夠確認Leader的提議以前,必須將提案寫入磁盤並進行同步。
要注意的兩個重要指標是
# etcd disk io latency alerts # =========================== # alert if 99th percentile of fsync durations is higher than 500ms ALERT HighFsyncDurations IF histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m])) > 0.5 FOR 10m LABELS { severity = "warning" } ANNOTATIONS { summary = "high fsync durations", description = "etcd instance {{ $labels.instance }} fync durations are high", } # alert if 99th percentile of commit durations is higher than 250ms ALERT HighCommitDurations IF histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket[5m])) > 0.25 FOR 10m LABELS { severity = "warning" } ANNOTATIONS { summary = "high commit durations", description = "etcd instance {{ $labels.instance }} commit durations are high", }
Etcd使用gRPC在集羣中的每一個節點之間進行通訊。最好跟蹤這些請求的性能和錯誤數。
指標etcd_grpc_total表示按方法分類的grpc調用總數。
etc_grpc_requests_failed_total表示失敗次數。
# gRPC request alerts # =================== # alert if more than 1% of gRPC method calls have failed within the last 5 minutes ALERT HighNumberOfFailedGRPCRequests IF sum by(grpc_method) (rate(etcd_grpc_requests_failed_total{job="etcd"}[5m])) / sum by(grpc_method) (rate(etcd_grpc_total{job="etcd"}[5m])) > 0.01 FOR 10m LABELS { severity = "warning" } ANNOTATIONS { summary = "a high number of gRPC requests are failing", description = "{{ $value }}% of requests for {{ $labels.grpc_method }} failed on etcd instance {{ $labels.instance }}", } # alert if more than 5% of gRPC method calls have failed within the last 5 minutes ALERT HighNumberOfFailedGRPCRequests IF sum by(grpc_method) (rate(etcd_grpc_requests_failed_total{job="etcd"}[5m])) / sum by(grpc_method) (rate(etcd_grpc_total{job="etcd"}[5m])) > 0.05 FOR 5m LABELS { severity = "critical" } ANNOTATIONS { summary = "a high number of gRPC requests are failing", description = "{{ $value }}% of requests for {{ $labels.grpc_method }} failed on etcd instance {{ $labels.instance }}", } # alert if the 99th percentile of gRPC method calls take more than 150ms ALERT GRPCRequestsSlow IF histogram_quantile(0.99, rate(etcd_grpc_unary_requests_duration_seconds_bucket[5m])) > 0.15 FOR 10m LABELS { severity = "critical" } ANNOTATIONS { summary = "slow gRPC requests", description = "on etcd instance {{ $labels.instance }} gRPC requests to {{ $label.grpc_method }} are slow", }
如何查看 etcd 的讀寫磁盤的 Latency?
能夠經過etcd 的 metrics計算得出:5m 內的磁盤IO 延遲(99%區間)。如大於 500ms 報警
histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket{clusterID=」c-07v3Y2v5」,instanceIP=」100.70.181.251」}[5m])) > 0.5