容器監(jiān)控實(shí)踐—kube-state-metrics

概述

已經(jīng)有了cadvisor匾效、heapster惩妇、metric-server,幾乎容器運(yùn)行的所有指標(biāo)都能拿到冒版,但是下面這種情況卻無(wú)能為力:

  • 我調(diào)度了多少個(gè)replicas液茎?現(xiàn)在可用的有幾個(gè)?
  • 多少個(gè)Pod是running/stopped/terminated狀態(tài)辞嗡?
  • Pod重啟了多少次捆等?
  • 我有多少job在運(yùn)行中

而這些則是kube-state-metrics提供的內(nèi)容,它基于client-go開發(fā)续室,輪詢Kubernetes API栋烤,并將Kubernetes的結(jié)構(gòu)化信息轉(zhuǎn)換為metrics。

功能

kube-state-metrics提供的指標(biāo)挺狰,按照階段分為三種類別:

  • 1.實(shí)驗(yàn)性質(zhì)的:k8s api中alpha階段的或者spec的字段明郭。

  • 2.穩(wěn)定版本的:k8s中不向后兼容的主要版本的更新

  • 3.被廢棄的:已經(jīng)不在維護(hù)的买窟。

指標(biāo)類別包括:

  • CronJob Metrics
  • DaemonSet Metrics
  • Deployment Metrics
  • Job Metrics
  • LimitRange Metrics
  • Node Metrics
  • PersistentVolume Metrics
  • PersistentVolumeClaim Metrics
  • Pod Metrics
  • Pod Disruption Budget Metrics
  • ReplicaSet Metrics
  • ReplicationController Metrics
  • ResourceQuota Metrics
  • Service Metrics
  • StatefulSet Metrics
  • Namespace Metrics
  • Horizontal Pod Autoscaler Metrics
  • Endpoint Metrics
  • Secret Metrics
  • ConfigMap Metrics

以pod為例:

  • kube_pod_info
  • kube_pod_owner
  • kube_pod_status_phase
  • kube_pod_status_ready
  • kube_pod_status_scheduled
  • kube_pod_container_status_waiting
  • kube_pod_container_status_terminated_reason
  • ...

使用

部署清單

 kube-state-metrics/
    ├── kube-state-metrics-cluster-role-binding.yaml
    ├── kube-state-metrics-cluster-role.yaml
    ├── kube-state-metrics-deployment.yaml
    ├── kube-state-metrics-role-binding.yaml
    ├── kube-state-metrics-role.yaml
    ├── kube-state-metrics-service-account.yaml
    ├── kube-state-metrics-service.yaml

主要鏡像有:
image: quay.io/coreos/kube-state-metrics:v1.5.0
image: k8s.gcr.io/addon-resizer:1.8.3(參考metric-server文章,用于擴(kuò)縮容)

對(duì)于pod的資源限制薯定,一般情況下:

200MiB memory 0.1 cores

超過(guò)100節(jié)點(diǎn)的集群:

2MiB memory per node 0.001 cores per node

kube-state-metrics做過(guò)一次性能優(yōu)化始绍,具體內(nèi)容參考下文

部署成功后,prometheus的target會(huì)出現(xiàn)如下標(biāo)志

image

因?yàn)閗ube-state-metrics-service.yaml中有prometheus.io/scrape: 'true'標(biāo)識(shí)话侄,因此會(huì)將metric暴露給prometheus亏推,而Prometheus會(huì)在kubernetes-service-endpoints這個(gè)job下自動(dòng)發(fā)現(xiàn)kube-state-metrics,并開始拉取metrics满葛,無(wú)需其他配置。

使用kube-state-metrics后的常用場(chǎng)景有:

  • 存在執(zhí)行失敗的Job: kube_job_status_failed{job="kubernetes-service-endpoints",k8s_app="kube-state-metrics"}==1
  • 集群節(jié)點(diǎn)狀態(tài)錯(cuò)誤: kube_node_status_condition{condition="Ready",status!="true"}==1
  • 集群中存在啟動(dòng)失敗的Pod:kube_pod_status_phase{phase=~"Failed|Unknown"}==1
  • 最近30分鐘內(nèi)有Pod容器重啟: changes(kube_pod_container_status_restarts[30m])>0

配合報(bào)警可以更好地監(jiān)控集群的運(yùn)行

與metric-server的對(duì)比

  • metric-server(或heapster)是從api-server中獲取cpu罢屈、內(nèi)存使用率這種監(jiān)控指標(biāo)嘀韧,并把他們發(fā)送給存儲(chǔ)后端,如influxdb或云廠商缠捌,他當(dāng)前的核心作用是:為HPA等組件提供決策指標(biāo)支持锄贷。
  • kube-state-metrics關(guān)注于獲取k8s各種資源的最新狀態(tài),如deployment或者daemonset曼月,之所以沒有把kube-state-metrics納入到metric-server的能力中谊却,是因?yàn)樗麄兊年P(guān)注點(diǎn)本質(zhì)上是不一樣的。metric-server僅僅是獲取哑芹、格式化現(xiàn)有數(shù)據(jù)炎辨,寫入特定的存儲(chǔ),實(shí)質(zhì)上是一個(gè)監(jiān)控系統(tǒng)聪姿。而kube-state-metrics是將k8s的運(yùn)行狀況在內(nèi)存中做了個(gè)快照碴萧,并且獲取新的指標(biāo),但他沒有能力導(dǎo)出這些指標(biāo)
  • 換個(gè)角度講末购,kube-state-metrics本身是metric-server的一種數(shù)據(jù)來(lái)源破喻,雖然現(xiàn)在沒有這么做。
  • 另外盟榴,像Prometheus這種監(jiān)控系統(tǒng)曹质,并不會(huì)去用metric-server中的數(shù)據(jù),他都是自己做指標(biāo)收集擎场、集成的(Prometheus包含了metric-server的能力)羽德,但Prometheus可以監(jiān)控metric-server本身組件的監(jiān)控狀態(tài)并適時(shí)報(bào)警停蕉,這里的監(jiān)控就可以通過(guò)kube-state-metrics來(lái)實(shí)現(xiàn)凌蔬,如metric-serverpod的運(yùn)行狀態(tài)粥脚。

深入解析

kube-state-metrics本質(zhì)上是不斷輪詢api-server盗冷,代碼結(jié)構(gòu)也很簡(jiǎn)單
主要代碼目錄

.
├── collectors
│   ├── builder.go
│   ├── collectors.go
│   ├── configmap.go
│   ......
│   ├── testutils.go
│   ├── testutils_test.go
│   └── utils.go
├── constant
│   └── resource_unit.go
├── metrics
│   ├── metrics.go
│   └── metrics_test.go
├── metrics_store
│   ├── metrics_store.go
│   └── metrics_store_test.go
├── options
│   ├── collector.go
│   ├── options.go
│   ├── options_test.go
│   ├── types.go
│   └── types_test.go
├── version
│   └── version.go
└── whiteblacklist
    ├── whiteblacklist.go
    └── whiteblacklist_test.go

所有類型:

var (
    DefaultNamespaces = NamespaceList{metav1.NamespaceAll}
    DefaultCollectors = CollectorSet{
        "daemonsets":               struct{}{},
        "deployments":              struct{}{},
        "limitranges":              struct{}{},
        "nodes":                    struct{}{},
        "pods":                     struct{}{},
        "poddisruptionbudgets":     struct{}{},
        "replicasets":              struct{}{},
        "replicationcontrollers":   struct{}{},
        "resourcequotas":           struct{}{},
        "services":                 struct{}{},
        "jobs":                     struct{}{},
        "cronjobs":                 struct{}{},
        "statefulsets":             struct{}{},
        "persistentvolumes":        struct{}{},
        "persistentvolumeclaims":   struct{}{},
        "namespaces":               struct{}{},
        "horizontalpodautoscalers": struct{}{},
        "endpoints":                struct{}{},
        "secrets":                  struct{}{},
        "configmaps":               struct{}{},
    }
)

構(gòu)建對(duì)應(yīng)的收集器

Family即一個(gè)類型的資源集合聊闯,如job下的kube_job_info缸兔、kube_job_created陨囊,都是一個(gè)FamilyGenerator實(shí)例

metrics.FamilyGenerator{
            Name: "kube_job_info",
            Type: metrics.MetricTypeGauge,
            Help: "Information about job.",
            GenerateFunc: wrapJobFunc(func(j *v1batch.Job) metrics.Family {
                return metrics.Family{&metrics.Metric{
                    Name:  "kube_job_info",
                    Value: 1,
                }}
            }),
        },
func (b *Builder) buildCronJobCollector() *Collector {
   // 過(guò)濾傳入的白名單
    filteredMetricFamilies := filterMetricFamilies(b.whiteBlackList, cronJobMetricFamilies)
    composedMetricGenFuncs := composeMetricGenFuncs(filteredMetricFamilies)
  // 將參數(shù)寫到header中
    familyHeaders := extractMetricFamilyHeaders(filteredMetricFamilies)
  // NewMetricsStore實(shí)現(xiàn)了client-go的cache.Store接口爷怀,實(shí)現(xiàn)本地緩存。
    store := metricsstore.NewMetricsStore(
        familyHeaders,
        composedMetricGenFuncs,
    )
  // 按namespace構(gòu)建Reflector匀伏,監(jiān)聽變化
    reflectorPerNamespace(b.ctx, b.kubeClient, &batchv1beta1.CronJob{}, store, b.namespaces, createCronJobListWatch)

    return NewCollector(store)
}

性能優(yōu)化:

kube-state-metrics在之前的版本中暴露出兩個(gè)問(wèn)題:

    1. /metrics接口響應(yīng)慢(10-20s)
    1. 內(nèi)存消耗太大洒忧,導(dǎo)致超出limit被殺掉

問(wèn)題一的方案就是基于client-go的cache tool實(shí)現(xiàn)本地緩存,具體結(jié)構(gòu)為:

var cache = map[uuid][]byte{}

問(wèn)題二的的方案是:對(duì)于時(shí)間序列的字符串够颠,是存在很多重復(fù)字符的(如namespace等前綴篩選)熙侍,可以用指針或者結(jié)構(gòu)化這些重復(fù)字符。

優(yōu)化點(diǎn)和問(wèn)題

  • 1.因?yàn)閗ube-state-metrics是監(jiān)聽資源的add履磨、delete蛉抓、update事件,那么在kube-state-metrics部署之前已經(jīng)運(yùn)行的資源剃诅,豈不是拿不到數(shù)據(jù)巷送?kube-state-metric利用client-go可以初始化所有已經(jīng)存在的資源對(duì)象,確保沒有任何遺漏
  • 2.kube-state-metrics當(dāng)前不會(huì)輸出metadata信息(如help和description)
  • 3.緩存實(shí)現(xiàn)是基于golang的map矛辕,解決并發(fā)讀問(wèn)題當(dāng)期是用了一個(gè)簡(jiǎn)單的互斥鎖笑跛,應(yīng)該可以解決問(wèn)題,后續(xù)會(huì)考慮golang的sync.Map安全map聊品。
  • 4.kube-state-metrics通過(guò)比較resource version來(lái)保證event的順序
  • 5.kube-state-metrics并不保證包含所有資源

監(jiān)控?cái)?shù)據(jù)展示

基于kube-state-metrics的監(jiān)控?cái)?shù)據(jù)飞蹂,可以組裝一些常用的監(jiān)控面板,如下面的grafana面板

image
image

本文為容器監(jiān)控實(shí)踐系列文章翻屈,完整內(nèi)容見:container-monitor-book

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末陈哑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子伸眶,更是在濱河造成了極大的恐慌芥颈,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赚抡,死亡現(xiàn)場(chǎng)離奇詭異爬坑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)涂臣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門盾计,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人赁遗,你說(shuō)我怎么就攤上這事署辉。” “怎么了岩四?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵哭尝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我剖煌,道長(zhǎng)材鹦,這世上最難降的妖魔是什么逝淹? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮桶唐,結(jié)果婚禮上栅葡,老公的妹妹穿的比我還像新娘。我一直安慰自己尤泽,他們只是感情好欣簇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坯约,像睡著了一般熊咽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上闹丐,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天横殴,我揣著相機(jī)與錄音,去河邊找鬼妇智。 笑死滥玷,一個(gè)胖子當(dāng)著我的面吹牛氏身,可吹牛的內(nèi)容都是我干的巍棱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛋欣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼航徙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起陷虎,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤到踏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后尚猿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窝稿,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年凿掂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伴榔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庄萎,死狀恐怖踪少,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情糠涛,我是刑警寧澤援奢,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站忍捡,受9級(jí)特大地震影響集漾,放射性物質(zhì)發(fā)生泄漏切黔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一帆竹、第九天 我趴在偏房一處隱蔽的房頂上張望绕娘。 院中可真熱鬧,春花似錦栽连、人聲如沸险领。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绢陌。三九已至,卻和暖如春熔恢,著一層夾襖步出監(jiān)牢的瞬間脐湾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工叙淌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秤掌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓鹰霍,卻偏偏與公主長(zhǎng)得像闻鉴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茂洒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容