Metrics-Python操作Metrics Server API 获取node、pod资源率
一、原理说明
-
其实目前新版的K8S在监控这块的架构已经非常明确了,只不过国内很少有文章解释这一块,其官方架构说明见:
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/monitoring_architecture.md。 -
其架构分位2个部分:
- 内置于K8S的核心指标采集,安装K8S就自带了(下图黑色部分)。
- 第三方的监控采集方案,需要大家自己选型,比如prometheus等(下图蓝色部分)。
-
像kubectl top获取的cpu/mem使用情况,就属于K8S内置的核心指标采集而来,完全不需要第三方的支持
二、API 访问 metrics-server
-
那么当前,metrics-server在API SERVER注册的GROUP叫做metrics.k8s.io,VERSION是v1beta1,所以其对应的Restful资源URI就是以:/apis/metrics.k8s.io/v1beta1/为前缀的。
-
metrics-server官方已经说明了其资源URI的几种形式:https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/resource-metrics-api.md。
-
The list of supported endpoints:
- /nodes – all node metrics; type []NodeMetrics
- /nodes/{node} – metrics for a specified node; type NodeMetrics
- /namespaces/{namespace}/pods – all pod metrics within namespace with support for all-namespaces; type []PodMetrics
- /namespaces/{namespace}/pods/{pod} – metrics for a specified pod; type PodMetrics
-
The following query parameters are supported:
- labelSelector – restrict the list of returned objects by labels (list endpoints only)
-
-
所以,为了获取某个namespace下面的pods的资源利用率,我们可以有2种方式:
- 按标签筛选:/apis/metrics.k8s.io/v1beta1/namespaces/{namespace}/pods?labelSelector=xxxx
- 按pod名字获取:/apis/metrics.k8s.io/v1beta1/namespaces/{namespace}/pods/
- 首先启动一个proxy,它会帮我们解决和API SERVER之间的认证问题,我们只需要关注于接口参数即可:
# kubectl proxy --port=8181 --address=0.0.0.0
# nodes -> curl localhost:8181/apis/metrics.k8s.io/v1beta1/nodes
# pods -> curl localhost:8181/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/redis-master-dasdhjasd
curl localhost:8181/apis/metrics.k8s.io/v1beta1/namespaces/test/pods
- 通过接口访问节点资源信息路径
查看node资源指标
# kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq | less
查看pods资源指标
# kubectl get --raw "/apis/metrics.k8s.io/v1beta1/pods" | jq | less
三、requests封装API
# 仅为示例,代码不完整!!!
import requests
import re
def eventer_alarm_cutpods(string):
string = re.sub(r'\\n', '\n', string)
pods = string.split('\n')[2].split()[1]
print(pods)
return pods
def metric_get_pods(host, pods):
"""
:param hosts -> 127.0.0.1:8181
"""
if pods:
url = 'http://' + host + '/apis/metrics.k8s.io/v1beta1/namespaces/test/pods'
response = requests.get(url)
with response:
print(response.json())
else:
url = 'http://' + host + '/apis/metrics.k8s.io/v1beta1/pods'
def metric_get_nodes(host, node):
"""
:param hosts -> 127.0.0.1:8181
:return:
"""
if node:
pass
else:
url = 'http://' + host + '/apis/metrics.k8s.io/v1beta1/nodes'
response = requests.get(url)
with response:
print(response.json())
if __name__ == '__main__':
# metric_get_nodes('127.0.0.1:8181')
string = 'EventType: Warning\nEventKind: Pod\nEventObject: test-nginx-7d97ffc85d-nrnfn\nEventReason: Failed\nEventTime: 2021-05-23 17:48:12 +0800 CST\nEventMessage: Error: ErrImagePull'
eventer_alarm_cutpods(string)
向往的地方很远,喜欢的东西很贵,这就是我努力的目标。