Kubernetes核心指标监控——Metrics Server
1、概述
从Kubernetes v1.8 开始,资源使用情况的监控可以通过 Metrics API的形式获取,例如容器CPU和内存使用率。这些度量可以由用户直接访问(例如,通过使用kubectl top命令),或者由集群中的控制器(例如,Horizontal Pod Autoscaler)使用来进行决策,具体的组件为Metrics Server,用来替换之前的heapster,heapster从1.11开始逐渐被废弃。
Metrics-Server是集群核心监控数据的聚合器。通俗地说,它存储了集群中各节点的监控数据,并且提供了API以供分析和使用。Metrics-Server作为一个 Deployment对象默认部署在Kubernetes集群中。不过准确地说,它是Deployment,Service,ClusterRole,ClusterRoleBinding,APIService,RoleBinding等资源对象的综合体。
项目地址:https://github.com/kubernetes-sigs/metrics-server ,目前稳定版本是v0.5.2。
metric-server主要用来通过aggregate api向其它组件(kube-scheduler、
HorizontalPodAutoscaler、Kubernetes集群客户端等
)提供集群中的pod和node的cpu和memory的监控指标,弹性伸缩中的podautoscaler就是通过调用这个接口来查看pod的当前资源使用量来进行pod的扩缩容的。
需要注意的是:
- metric-server提供的是实时的指标(实际是最近一次采集的数据,保存在内存中),并没有数据库来存储
- 这些数据指标并非由metric-server本身采集,而是由每个节点上的cadvisor采集,metric-server只是发请求给cadvisor并将metric格式的数据转换成aggregate api
- 由于需要通过aggregate api来提供接口,需要集群中的kube-apiserver开启该功能(开启方法可以参考官方社区的文档)
2、部署Metrics Server
2.1 下载并部署Metrics Server
下载部署清单:
1 | wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.5.2/components.yaml |
修改部署清单内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | [root@master1 metrics-server]# cat components.yaml apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: k8s-app: metrics-server rbac.authorization.k8s.io/aggregate-to-admin: "true" rbac.authorization.k8s.io/aggregate-to-edit: "true" rbac.authorization.k8s.io/aggregate-to-view: "true" name: system:aggregated-metrics-reader rules: - apiGroups: - metrics.k8s.io resources: - pods - nodes verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: k8s-app: metrics-server name: system:metrics-server rules: - apiGroups: - "" resources: - pods - nodes - nodes/stats - namespaces - configmaps verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: k8s-app: metrics-server name: metrics-server-auth-reader namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: extension-apiserver-authentication-reader subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: k8s-app: metrics-server name: metrics-server:system:auth-delegator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: k8s-app: metrics-server name: system:metrics-server roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:metrics-server subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: v1 kind: Service metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: ports: - name: https port: 443 protocol: TCP targetPort: https selector: k8s-app: metrics-server --- apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: metrics-server name: metrics-server namespace: kube-system spec: selector: matchLabels: k8s-app: metrics-server strategy: rollingUpdate: maxUnavailable: 0 template: metadata: labels: k8s-app: metrics-server spec: containers: - args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --kubelet-insecure-tls image: k8s.gcr.io/metrics-server/metrics-server:v0.5.2 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /livez port: https scheme: HTTPS periodSeconds: 10 name: metrics-server ports: - containerPort: 4443 name: https protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /readyz port: https scheme: HTTPS periodSeconds: 10 securityContext: readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 volumeMounts: - mountPath: /tmp name: tmp-dir nodeSelector: kubernetes.io/os: linux priorityClassName: system-cluster-critical serviceAccountName: metrics-server volumes: - emptyDir: {} name: tmp-dir --- apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: labels: k8s-app: metrics-server name: v1beta1.metrics.k8s.io spec: group: metrics.k8s.io groupPriorityMinimum: 100 insecureSkipTLSVerify: true service: name: metrics-server namespace: kube-system version: v1beta1 versionPriority: 100 |
在deploy中,spec.template.containers.args字段中加上--kubelet-insecure-tls选项,表示不验证客户端证书;上述清单主要用deploy控制器将metrics server运行为一个pod,然后授权metrics-server用户能够对pod/node资源进行只读权限;然后把metrics.k8s.io/v1beta1注册到原生apiserver上,让其客户端访问metrics.k8s.io下的资源能够被路由至metrics-server这个服务上进行响应;
应用资源清单:
1 2 3 4 5 6 7 8 9 10 | [root@master1 metrics-server]# kubectl apply -f components.yaml serviceaccount/metrics-server created clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created clusterrole.rbac.authorization.k8s.io/system:metrics-server created rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created service/metrics-server created deployment.apps/metrics-server created apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created |
2.2 验证Metrics Server组件部署成功
(1)查看原生apiserver是否有metrics.k8s.io/v1beta1
1 2 | [root@master1 metrics-server]# kubectl api-versions|grep metrics metrics.k8s.io/v1beta1 |
可以看到metrics.k8s.io/v1beta1群组已经注册到原生apiserver上。
(2)查看metrics server pod是否运行正常
1 2 | [root@master1 ~]# kubectl get pods -n=kube-system |grep metrics metrics-server-855cc6b9d-g6xsf 1/1 Running 0 18h |
可以看到对应pod已经正常运行,接着查看pod日志,只要metrics server pod没有出现错误日志,或者无法注册等信息,就表示pod里的容器运行正常。
(3)使用kubectl top 命令查看pod的cpu ,内存占比,看看对应命令是否可以正常执行,如果Metrics Server服务有异常的话会报Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io)错误。
1 2 3 4 5 | [root@master1 ~]# kubectl top nodes NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% master1 272m 3% 4272Mi 29% node1 384m 5% 9265Mi 30% node2 421m 5% 14476Mi 48% |
可以看到kubectl top命令可以正常执行,说明metrics server 部署成功没有问题。
3、原理
Metrics server复用了api-server的库来实现自己的功能,比如鉴权、版本等,为了实现将数据存放在内存中吗,去掉了默认的etcd存储,引入了内存存储(即实现Storage interface)。
因为存放在内存中,因此监控数据是没有持久化的,可以通过第三方存储来拓展。
来看下Metrics-Server的架构:
从 Kubelet、cAdvisor 等获取度量数据,再由metrics-server提供给 Dashboard、HPA 控制器等使用。本质上metrics-server
相当于做了一次数据的转换,把cadvisor
格式的数据转换成了kubernetes的api
的json
格式。由此我们不难猜测,metrics-server
的代码中必然存在这种先从metric中获取接口中的所有信息,再解析出其中的数据的过程。我们给metric-server
发送请求时,metrics-server
中已经定期从中cadvisor
获取好数据了,当请求发过来时直接返回缓存中的数据。
4、如何获取监控数据
Metrics-Server通过kubelet
获取监控数据。
在1.7版本之前,k8s在每个节点都安装了一个叫做cAdvisor
的程序,负责获取节点和容器的CPU,内存等数据;而在1.7版本及之后,k8s将cAdvisor精简化内置于kubelet中,因此可直接从kubelet中获取数据。
5、如何提供监控数据
Metrics-Server通过metrics API
提供监控数据。
先说下API聚合机制,API聚合机制是kubernetes 1.7版本引入的特性,能将用户扩展的API注册至API Server上。
API Server在此之前只提供kubernetes资源对象的API,包括资源对象的增删查改功能。有了API聚合机制之后,用户可以发布自己的API,而Metrics-Server用到的metrics API
和custom metrics API
均属于API聚合机制的应用。
用户可通过配置APIService资源对象以使用API聚合机制(API聚合机制详解请参考:Kubernetes APIService资源),如下是metrics API的配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 | apiVersion: apiregistration.k8s.io/v1beta1 kind: APIService metadata: name: v1beta1.metrics.k8s.io spec: service: name: metrics-server namespace: kube-system group: metrics.k8s.io version: v1beta1 insecureSkipTLSVerify: true groupPriorityMinimum: 100 versionPriority: 100 |
如上,APIService提供了一个名为v1beta1.metrics.k8s.io
的API,并绑定至一个名为metrics-server
的Service资源对象。
可以通过kubectl get apiservices
命令查询集群中的APIService。
因此,访问Metrics-Server的方式如下:
1 2 3 4 5 | /apis/metrics.k8s.io/v1beta1 ---> metrics-server.kube-system.svc ---> x.x.x.x +---------+ +-----------+ +------------------------+ +-----------------------------+ | 发起请求 +----->+ API Server +----------------->+ Service:metrics-server +-------->+ Pod:metrics-server-xxx-xxx | +---------+ +-----------+ +------------------------+ +-----------------------------+ |
有了访问Metrics-Server的方式,HPA,kubectl top
等对象就可以正常工作了。
6、常见问题
6.1 Kubernetes v1.23.15 版本使用metrics-server v0.4.2版本启动报错
1 2 3 4 5 6 7 8 | I0717 01:38:07.442401 1 tlsconfig.go:255] Shutting down DynamicServingCertificateController I0717 01:38:07.442425 1 dynamic_serving_content.go:145] Shutting down serving-cert::/tmp/apiserver.crt::/tmp/apiserver.key I0717 01:38:07.442472 1 secure_serving.go:241] Stopped listening on [::]:4443 I0717 01:38:07.442498 1 requestheader_controller.go:183] Shutting down RequestHeaderAuthRequestController I0717 01:38:07.442527 1 configmap_cafile_content.go:223] Shutting down client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file I0717 01:38:07.442340 1 configmap_cafile_content.go:223] Shutting down client-ca::kube-system::extension-apiserver-authentication::client-ca-file E0717 01:38:08.427374 1 webhook.go:199] Failed to make webhook authorizer request: Post "https://10.233.0.1:443/apis/authorization.k8s.io/v1/subjectaccessreviews?timeout=10s": context canceled E0717 01:38:08.427632 1 errors.go:77] Post "https://10.233.0.1:443/apis/authorization.k8s.io/v1/subjectaccessreviews?timeout=10s": context canceled |
查看 metrics-server 版本和Kubernetes版本对应关系表,官方文档显示v0.4.x当前版本是可以和k8s 1.23兼容的,但是奇怪报错。
解决方法:
换了个metrics-server v0.5.0,正常运行。
7、总结
kubernetes的新监控体系中,metrics-server属于Core metrics(核心指标),提供API metrics.k8s.io,仅提供Node和Pod的CPU和内存使用情况。而其他Custom Metrics(自定义指标)由Prometheus等组件来完成,后续文章将对自定义指标进行解析。
参考:https://staight.github.io/2019/09/12/metrics-server%E6%B5%85%E8%B0%88/
参考:http://yost.top/2020/05/17/about-metric-server/
参考:https://yasongxu.gitbook.io/container-monitor/yi-.-kai-yuan-fang-an/di-1-zhang-cai-ji/metrics-server
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步