一、Pod監(jiān)控相關指標
對于Pod內(nèi)存相關的指標,主要有兩個數(shù)據(jù)源:
- 基于kube-state-metrics,采集到的是內(nèi)存Limits和Requests的設置情況。關鍵的指標如下:
指標 | 含義 |
---|---|
kube_pod_container_resource_limits_memory_bytes | Pod內(nèi)存Limits設置量 |
kube_pod_container_resource_requests_memory_bytes | Pod內(nèi)存Requests設置量 |
- 基于kubelet上的CAdvisor,采集到的是內(nèi)存使用情況。關鍵的指標如下:
CAdvisor是Google開源用于收集容器資源和性能指標的一個工具,對于Kubernetes,其集成在kubelet里面,可以收集到每個節(jié)點上的Pod指標。
指標 | 含義 |
---|---|
container_memory_usage_bytes | 當前使用的內(nèi)存總量。包括所有使用的內(nèi)存,不管有沒有被訪問 (包括 cache, rss, swap等)。 |
container_memory_rss | RSS使用量。RSS是常駐內(nèi)存集(Resident Set Size)的縮寫,是分配給進程使用實際物理內(nèi)存,包括所有分配到的棧內(nèi)存和堆內(nèi)存 以及 加載到物理內(nèi)存中的共享庫占用的內(nèi)存空間。不包含磁盤緩存 |
container_memory_cache | 緩存使用量。 |
container_memory_swap | 虛擬內(nèi)存使用量。虛擬內(nèi)存(swap)指的是用磁盤來模擬內(nèi)存使用。對性能有影響,一般不用。 |
container_memory_working_set_bytes | 當前內(nèi)存工作集(working set)使用量。工作區(qū)內(nèi)存使用量=活躍的匿名與和緩存,以及file-baked頁。(working_set <= usage) |
container_memory_failcnt | 申請內(nèi)存失敗次數(shù)。 |
container_memory_failures_total | 內(nèi)存申請錯誤總次數(shù)。 |
基于以上的指標,就可以計算Pod的內(nèi)存使用率,當然,需要Pod有設置Limits才有意義
sum(container_memory_working_set_bytes{pod!="POD", container!=""}) by (pod) / sum(kube_pod_container_resource_requests_memory_bytes{}) by (pod)
二、關于Pod OOM
先說結(jié)論,Pod OOM主要看的是working_set的使用量是否超過limits。
準備一個簡單的程序,其功能是不斷地申請內(nèi)存
// main.go
package main
import (
"fmt"
"net/http"
"time"
"os"
"strconv"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
ticker, err := strconv.ParseInt(os.Getenv("Ticker"), 10, 64)
if err != nil {
panic(err)
}
memoryTicker := time.NewTicker(time.Millisecond * time.Duration(ticker))
leak := make(map[int][]byte)
i := 0
go func() {
for range memoryTicker.C {
leak[i] = make([]byte, 1024)
i++
}
}()
http.Handle("/metrics", promhttp.Handler())
fmt.Println("Strat listening on 0:8000...")
http.ListenAndServe(":8000", nil)
}
# Dockerfile
FROM golang:alpine3.15
WORKDIR /app
COPY main ./
EXPOSE 8000
CMD ["./main"]
WorkingSet(container_memory_working_set_bytes)和Usage(container_memory_usage_bytes)基本上是以1:1的趨勢到達limits,然后Pod觸發(fā)OOM
接下來在程序中添加一個goroutine,不斷在文件系統(tǒng)上寫入文件
// main.go
package main
import (
"fmt"
"net/http"
"time"
"os"
"strconv"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
ticker, err := strconv.ParseInt(os.Getenv("Ticker"), 10, 64)
if err != nil {
panic(err)
}
memoryTicker := time.NewTicker(time.Millisecond * time.Duration(ticker))
leak := make(map[int][]byte)
i := 0
go func() {
for range memoryTicker.C {
leak[i] = make([]byte, 1024)
i++
}
}()
fileTicker := time.NewTicker(time.Millisecond * time.Duration(ticker))
go func() {
os.Create("/tmp/file")
buffer := make([]byte, 1024)
defer f.Close()
for range fileTicker.C {
f.Write(buffer)
f.Sync()
}
}()
http.Handle("/metrics", promhttp.Handler())
fmt.Println("Strat listening on 0:8000...")
http.ListenAndServe(":8000", nil)
}
當Usage達到Limits,Pod不會OOM,隨著WorkingSet繼續(xù)增大,Cache逐漸減小,等WorkingSet到達Limit,Pod才OOM。文章來源:http://www.zghlxwxcb.cn/news/detail-653509.html
說明Usage中包含文件系統(tǒng)頁面的緩存。當實際內(nèi)存不夠用的時候,這些緩存會讓給程序使用。因為僅僅為了緩存就把程序給OOM掉是不合理的。文章來源地址http://www.zghlxwxcb.cn/news/detail-653509.html
到了這里,關于Kubernetes Pod內(nèi)存監(jiān)控的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!