kube-state-metrics

https://github.com/kubernetes/kube-state-metrics/tree/master/kubernetes

概述

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

  • 我調(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

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

2MiB memory per node 0.001 cores per node

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

因?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衔蹲,無需其他配置。

使用kube-state-metrics后的常用場景有:

存在執(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ù)來源远寸,雖然現(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)控就可以通過kube-state-metrics來實(shí)現(xiàn)贱枣,如metric-serverpod的運(yùn)行狀態(tài)监署。
深入解析
kube-state-metrics本質(zhì)上是不斷輪詢api-server,代碼結(jié)構(gòu)也很簡單

主要代碼目錄

.
├── 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 {
   // 過濾傳入的白名單
    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è)問題:

/metrics接口響應(yīng)慢(10-20s)
內(nèi)存消耗太大,導(dǎo)致超出limit被殺掉
問題一的方案就是基于client-go的cache tool實(shí)現(xiàn)本地緩存俏拱,具體結(jié)構(gòu)為:

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

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

優(yōu)化點(diǎ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ā)讀問題當(dāng)期是用了一個(gè)簡單的互斥鎖,應(yīng)該可以解決問題癞季,后續(xù)會(huì)考慮golang的sync.Map安全map劫瞳。
4.kube-state-metrics通過比較resource version來保證event的順序
5.kube-state-metrics并不保證包含所有資源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绷柒,隨后出現(xiàn)的幾起案子志于,更是在濱河造成了極大的恐慌,老刑警劉巖废睦,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恨憎,死亡現(xiàn)場離奇詭異,居然都是意外死亡郊楣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門瓤荔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來净蚤,“玉大人,你說我怎么就攤上這事输硝〗衿伲” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵点把,是天一觀的道長橘荠。 經(jīng)常有香客問我,道長郎逃,這世上最難降的妖魔是什么哥童? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮褒翰,結(jié)果婚禮上贮懈,老公的妹妹穿的比我還像新娘匀泊。我一直安慰自己,他們只是感情好朵你,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布各聘。 她就那樣靜靜地躺著,像睡著了一般抡医。 火紅的嫁衣襯著肌膚如雪躲因。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天忌傻,我揣著相機(jī)與錄音大脉,去河邊找鬼。 笑死芯勘,一個(gè)胖子當(dāng)著我的面吹牛箱靴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荷愕,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼衡怀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了安疗?” 一聲冷哼從身側(cè)響起抛杨,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荐类,沒想到半個(gè)月后怖现,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玉罐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年屈嗤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吊输。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饶号,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出季蚂,到底是詐尸還是另有隱情茫船,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布扭屁,位于F島的核電站算谈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏料滥。R本人自食惡果不足惜然眼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望幔欧。 院中可真熱鬧罪治,春花似錦丽声、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽所坯。三九已至,卻和暖如春霉撵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背洪囤。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工徒坡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘤缩。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓喇完,卻偏偏與公主長得像,于是被迫代替她去往敵國和親剥啤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锦溪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355