從Kubectl Top說起,談談Kubernetes是如何進行資源監控的?
一、前言
kubectl top 可以很方便地檢視node、pod 的實時資源使用情況:如CPU、記憶體。這篇文章會介紹其資料鏈路和實現原理,同時借 kubectl top 闡述 k8s 中的監控體系,窺一斑而知全豹。最後會解釋常見的一些問題:
kubectl top 為什麼會報錯?
kubectl top node 怎麼計算,和節點上直接 top 有什麼區別?
kubectl top pod 怎麼計算,包含 pause 嗎?
kubectl top pod 和exec 進入 pod 後看到的 top 不一樣?
kubectl top pod 和 docker stats得到的值為什麼不同?
以下命令的執行環境為:
k8s 1.8
k8s 1.13
二、使用
kubectl top 是基礎命令,但是需要部署配套的元件才能獲取到監控值
1.8以下:部署 heapter
1.8以上:部署 metric-server
kubectl top node: 檢視node的使用情況
kubectl top pod: 檢視 pod 的使用情況
不指定pod 名稱,則顯示名稱空間下所有 pod,–containers可以顯示 pod 內所有的container
指標含義:
和 k8s中 的 request、limit 一致,CPU單位100m=0.1 記憶體單位1Mi=1024Ki
pod 的記憶體值是其實際使用量,也是做 limit 限制時判斷 oom 的依據。pod的使用量等於其所有業務容器的總和,不包括 pause 容器,值等於 cadvisr中的 container_memory_working_set_bytes 指標
node 的值並不等於該 node 上所有 pod 值的總和,也不等於直接在機器上執行 top 或 free 看到的值
三、實現原理
3.1 資料鏈路
kubectl top、 k8s dashboard 以及 HPA 等排程元件使用的資料是一樣,資料鏈路如下:
使用 heapster 時:apiserver 會直接將 metric 請求透過 proxy 的方式轉發給叢集內的 hepaster 服務。
而使用 metrics-server 時:apiserver 是透過 /apis/metrics.k8s.io/ 的地址訪問 metric
這裡可以對比下 kubect get pod 時的日誌:
3.2 metric api
可以發現,heapster 使用的是 proxy 轉發,而 metric-server 和普通 pod都是使用 api/xx 的資源介面,heapster採用的這種 proxy 方式是有問題的:
proxy 只是代理請求,一般用於問題排查,不夠穩定,且版本不可控
heapster 的介面不能像 apiserver 一樣有完整的鑑權以及 client 整合,兩邊都維護的話代價高,如 generic apiserver
pod 的監控資料是核心指標(HPA排程),應該和 pod 本身擁有同等地位,即 metric 應該作為一種資源存在,如 metrics.k8s.io 的形式,稱之為 Metric Api
於是官方從 1.8 版本開始逐步廢棄 heapster,並提出了上邊 Metric api 的概念,而 metrics-server 就是這種概念下官方的一種實現,用於從 kubelet獲取指標,替換掉之前的 heapster。
3.3 kube-aggregator
有了 metrics-server 元件,採集到了需要的資料,也暴露了介面,但走到這一步和 heapster 其實沒有區別,最關鍵的一步就是如何將打到 apiserver的 /apis/metrics.k8s.io 請求轉發給 metrics-server 元件?解決方案就是:kube-aggregator。kube-aggregator 是對 apiserver 的有力擴充套件,它允許 k8s 的開發人員編寫一個自己的服務,並把這個服務註冊到 k8s 的 api 裡面,即擴充套件 API,metric-server 其實在 1.7版本就已經完成了,只是在等 kube-aggregator 的出現。kube-aggregator 是 apiserver 中的實現,有些 k8s 版本預設沒開啟,你可以加上這些配置來開啟,他的核心功能是動態註冊、發現彙總、安全代理。
如 metric-server 註冊 pod 和 node 時:
3.4 監控體系
在提出 metric api 的概念時,官方也提出了新的監控體系,監控資源被分為了2種:
Core metrics(核心指標):從 Kubelet、cAdvisor 等獲取度量資料,再由metrics-server 提供給 Dashboard、HPA 控制器等使用。
Custom Metrics(自定義指標):由 Prometheus Adapter 提供 API custom.metrics.k8s.io,由此可支援任意Prometheus採集到的指標。
核心指標只包含 node 和 pod 的 cpu、記憶體等,一般來說,核心指標作 HPA 已經足夠,但如果想根據自定義指標:如請求 qps/5xx 錯誤數來實現 HPA,就需要使用自定義指標了。目前 Kubernetes 中自定義指標一般由 Prometheus 來提供,再利用 k8s-prometheus-adpater 聚合到 apiserver,實現和核心指標同樣的效果。
3.5 kubelet
前面提到,無論是 heapster 還是 metric-server,都只是資料的中轉和聚合,兩者都是呼叫的 kubelet 的 api 介面獲取的資料,而 kubelet 程式碼中實際採集指標的是 cadvisor 模組,你可以在 node 節點訪問 10255 埠(1.11版本過後是10250埠)獲取監控資料:
Kubelet Summary metrics: 127.0.0.1:10255/metrics,暴露 node、pod 彙總資料
Cadvisor metrics: 127.0.0.1:10255/metrics/cadvisor,暴露 container 維度資料
示例,容器的記憶體使用量:
Kubelet 雖然提供了 metric 介面,但實際監控邏輯由內建的 cAdvisor 模組負責,演變過程如下:
從k8s 1.6開始,kubernetes 將 cAdvisor 開始整合在kubelet中,不需要單獨配置
從k8s 1.7開始,Kubelet metrics API 不再包含 cadvisor metrics,而是提供了一個獨立的 API 介面來做彙總
從 k8s 1.12 開始,cadvisor 監聽的埠在k8s中被刪除,所有監控資料統一由 Kubelet 的 API 提供
到這裡為止,k8s 範圍內的監控體系就結束了。
3.6 cadvisor
cadvisor 由谷歌開源,使用 Go 開發,cadvisor 不僅可以蒐集一臺機器上所有執行的容器資訊,包括 CPU 使用情況、記憶體使用情況、網路吞吐量及檔案系統使用情況,還提供基礎查詢介面和 http 介面,方便其他元件進行資料抓取。在K8S 中整合在 Kubelet 裡作為預設啟動項,k8s 官方標配。cadvisor 拿到的資料結構示例:
核心邏輯是透過 new 出來的 memoryStorage 以及 sysfs 例項,建立一個manager 例項,manager 的 interface 中定義了許多用於獲取容器和 machine 資訊的函式。
cadvisor的指標解讀:cgroup-v1( https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt)
cadvisor 獲取指標時實際呼叫的是 runc/libcontainer 庫,而 libcontainer 是對 cgroup 檔案 的封裝,即 cadvsior 也只是個轉發者,它的資料來自於cgroup 檔案。
3.7 cgroup
cgroup 檔案中的值是監控資料的最終來源,如
mem usage 的值,來自於
/sys/fs/cgroup/memory/docker/[containerId]/memory.usage_in_bytes
如果沒限制記憶體,Limit=machine_mem,否則來自於
/sys/fs/cgroup/memory/docker/[id]/memory.limit_in_bytes
記憶體使用率=memory.usage_in_bytes/memory.limit_in_bytes
一般情況下,cgroup資料夾下的內容包括CPU、記憶體、磁碟、網路等資訊:
如 memory 下的幾個常用的指標含義:
memory.stat 中的資訊是最全的:
原理到這裡結束,這裡解釋下最開始的 kubectl top 的幾個問題:
四、問題
一般情況下 top 報錯有以下幾種,可以 kubectl top pod -v=10看到具體的呼叫日誌:
沒有部署 heapster 或者 metric-server,或者 pod 執行異常,可以排查對應 pod 日誌
要看的 pod 剛剛建出來,還沒來得及採集指標,報 not found 錯誤,預設 1 分鐘
以上兩種都不是,可以檢查下 kubelet 的 10255 埠是否開放,預設情況下會使用這個只讀埠獲取指標,也可以在 heapster 或 metric-server 的配置中增加證書,換成 10250 認證埠
4.2 kubectl top pod 記憶體怎麼計算,包含 pause容器嗎
每次啟動 pod,都會有一個 pause 容器,既然是容器就一定有資源消耗(一般在 2-3M 的記憶體),cgroup 檔案中,業務容器和 pause 容器都在同一個 pod的資料夾下。
但 cadvisor 在查詢 pod 的記憶體使用量時,是先獲取了 pod 下的container列表,再逐個獲取container的記憶體佔用,不過這裡的 container 列表並沒有包含 pause,因此最終 top pod 的結果也不包含 pause 容器pod 的記憶體使用量計算kubectl top pod 得到的記憶體使用量,並不是 cadvisor 中的 container_memory_usage_bytes,而是 container_memory_working_set_bytes,計算方式為:
container_memory_usage_bytes = container_memory_rss + container_memory_cache + kernel memory
container_memory_working_set_bytes = container_memory_usage_bytes – total_inactive_file(未啟用的匿名快取頁)
container_memory_working_set_bytes 是容器真實使用的記憶體量,也是 limit限制時的 oom 判斷依據。cadvisor 中的 container_memory_usage_bytes 對應 cgroup 中的 memory.usage_in_bytes 檔案,但 container_memory_working_set_bytes 並沒有具體的檔案,他的計算邏輯在 cadvisor 的程式碼中,如下:
同理,node 的記憶體使用量也是 container_memory_working_set_bytes。
4.3 kubectl top node 怎麼計算,和節點上直接 top 有什麼區別
kubectl top node 得到的 cpu 和記憶體值,並不是節點上所有 pod 的總和,不要直接相加。top node 是機器上 cgroup 根目錄下的彙總統計。
在機器上直接 top 命令看到的值和 kubectl top node 不能直接對比,因為計算邏輯不同,如記憶體,大致的對應關係是(前者是機器上 top,後者是 kubectl top):
4.4 kubectl top pod 和 exec 進入 pod 後看到的 top 不一樣
top 命令的差異和上邊一致,無法直接對比,同時,就算你對 pod 做了 limit 限制,pod 內的 top 看到的記憶體和 cpu 總量仍然是機器總量,並不是pod 可分配量
程式的RSS為程式使用的所有實體記憶體(file_rss+anon_rss),即Anonymous pages+Mapped apges(包含共享記憶體)
cgroup RSS為(anonymous and swap cache memory),不包含共享記憶體。兩者都不包含file cache
4.5 kubectl top pod 和 docker stats得到的值為什麼不同?
docker stats dockerID 可以看到容器當前的使用量:
如果你的 pod 中只有一個 container,你會發現 docker stats 值不等於kubectl top 的值,既不等於 container_memory_usage_bytes,也不等於container_memory_working_set_bytes。因為docker stats 和 cadvisor 的計算方式不同,總體值會小於 kubectl top:計算邏輯是: 五、後記
一般情況下,我們並不需要時刻關心 node 或 pod 的使用量,因為有叢集自動擴縮容(cluster-autoscaler)和 pod 水平擴縮容(HPA)來應對這兩種資源變化,資源指標的意義更適合使用 prometheus 來持久化 cadvisor 的資料,用於回溯歷史或者傳送報警。其他補充:
雖然 kubectl top help 中顯示支援 Storage,但直到 1.16 版本仍然不支援
1.13 之前需要 heapster,1.13 以後需要 metric-server,這部分 kubectl top help 的輸出 有誤,裡面只提到了heapster
k8s dashboard 中的監控圖預設使用的是 heapster,切換為 metric-server後資料會異常,需要多部署一個metric-server-scraper 的 pod 來做介面轉換,具體參考 pr:
來自 “ http://www.xuyasong.com/?p=1781 ”, 原文作者:yasong;原文連結:http://www.xuyasong.com/?p=1781,如有侵權,請聯絡管理員刪除。
相關文章
- 從如何更好的監控Oracle共享池談起Oracle
- 在Linux中,如何進行系統資源的監控?Linux
- 阿里雲容器Kubernetes監控(一)-資源監控阿里
- 監控雜談
- 【雲端計算】從Serverless說起,談談邊緣計算的未來;從物理機到Kubernetes的那些坑與心得Server
- Flutter異常監控 - 壹 | 從Zone說起Flutter
- 從資料庫開源商業版本差異談起資料庫
- 漫談混淆技術----從Citadel混淆殼說起
- 從影像融合談起
- 談談如何使用 opencv 進行影像識別OpenCV
- AI繪畫漫談——從AI網頁生成說起AI網頁
- 談談 Kubernetes Operator
- 從火爆一時的Clubhouse說起,淺談HMS Core與社交
- 如何進行監控設計?
- 從JavaScript 的關鍵詞談起JavaScript
- 談談 Kubernetes 的匿名訪問
- 1995年的資深工程師,和你談談如何進階工程師
- 從沙盒和開放世界談起,說說日本的箱庭設計理念
- 談服務可用性監控
- 高可用一覽-從LVS談起
- 【Zabbix】如何使用Zabbix進行IPMI監控?
- 談談傳說中的redo log是什麼?有啥用?
- 【雜談】如何對Redis進行原子操作Redis
- 從Balatro小丑牌的成功說起:淺談rogue的核心體驗與設計
- 從JS的執行機制的角度談談作用域JS
- 如何使用表格儲存控制檯進行資料監控
- 談談MYSQL索引是如何提高查詢效率的MySql索引
- 談談如何高效學習開源專案
- 使用 Skywalking 對 Kubernetes(K8s)中的微服務進行監控K8S微服務
- 從一起丟包故障來談談 nginx 中的 tcp keep-aliveNginxTCPKeep-Alive
- kubernetes雜談之(二)Pod初談
- 從機器學習談起,深度好文機器學習
- 在Linux中,如何進行磁碟效能監控?Linux
- Node效能如何進行監控以及優化?優化
- 談談你們是如何開始寫部落格的
- 如何跟玩家一起運營遊戲?——從《影之詩》的玩家文化談起遊戲
- 如何進行網站的真實使用者監控(RUM)?怎麼進入監控網站網站
- 一起來談談 Spring AOP!Spring