cka有一道考题,需要试用kubectl top,这个命令需要有对应的metrics接口,如果不安装metrics-server,使用top命令查看Pod的CPU、内存使用过程中,会遇到以下问题:
$ kubectl top po
W0818 03:22:46.090578 26207 top_pod.go:140] Using json format to get metrics.e-protocol-buffers flag
error: Metrics API not available
安装metric-server组件可以参考Github上的安装参考资料:GitHub - kubernetes-sigs/metrics-server
$ wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -O metrics-server-components.yaml
需要注意的是,metrics-server镜像用的是gcr镜像,需要换到国内的镜像仓库
sed -i 's/k8s.gcr.io\/metrics-server/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' metrics-server-components.yaml
如果是macOS,执行sed报错,需要执行以下命令
brew install gnu-sed
alias sed=gsed
下载GNU的sed,终端中默认的是BSD的sed。
然后用gsed代替sed命令就行了
apply修改之后的配置文件,查看该metric-server运行Pod
$ kubectl get pods --all-namespaces | grep metrics
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system metrics-server-6dfddc5fb8-f54vr 0/1 Running 0 44s
发现pod处于running状态但是没有ready,推测应该是探针检测没过,describe查看其详细信息:
……
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 79s default-scheduler Successfully assigned kube-system/metrics-server-6dfddc5fb8-f54vr to loki
Normal Pulled 78s kubelet Container image "k8s.gcr.io/metrics-server/metrics-server:v0.5.0" already present on machine
Normal Created 78s kubelet Created container metrics-server
Normal Started 78s kubelet Started container metrics-server
Warning Unhealthy 9s (x5 over 49s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 500
可以看到在描述中的事件信息中,“Readiness probe failed: HTTP probe failed with statuscode: 500”。
然后查看该Pod的日志:
$ kubectl logs -n kube-system metrics-server-6dfddc5fb8-f54vr
……
I0816 01:07:06.734107 1 server.go:188] "Failed probe" probe="metric-storage-ready" err="not metrics to serve"
I0816 01:07:16.736864 1 server.go:188] "Failed probe" probe="metric-storage-ready" err="not metrics to serve"
E0816 01:07:18.834625 1 scraper.go:139] "Failed to scrape node" err="Get \"https://192.168.130.100:10250/stats/summary?only_cpu_and_memory=true\": x509: cannot validate certificate for 192.168.130.100 because it doesn't contain any IP SANs" node="loki"
如上可以看到Readiness Probe探针检测到Metris Server容器启动后对httpGet探针存活没反应,具体原因是“cannot validate certificate for 192.168.130.100 because it doesn’t contain any IP SANs”。
针对“cannot validate certificate for 192.168.130.100 because it doesn’t contain any IP SANs”这个报错,可以仔细查阅Github上的安装参考资料。其中有提到:
1)安装要求,如下红框中说明,Kubelet证书需要由群集证书颁发机构签名(或可以禁用证书验证,通过对Metrics Server配置参数–Kubelet-insecure-tls不安全)
2)配置,如下红框中说明,添加了“–Kubelet-insecure-tls”这个配置,就不会去验证Kubelets提供的服务证书的CA。
修改tls校验:
......
containers:
- args:
...
- --kubelet-insecure-tls
......
然后重新apply,查看pod成功启动,并通过kubectl top验证能否访问metrics接口。
值得一提的是,集群安装是默认会安装cAdvisor组件,它的作用是:容器数据收集。而metrics-server基于heapster组件,它的作用是:集群监控数据收集,汇总所有节点监控数据。
而prometheus-stack中用于暴露metrics接口的组件是kube-state-metrics,这里简单总结一下metrics-server和kube-state-metrics的区别:
metric-server(或heapster)获取的是容器运行的指标,是cpu、内存使用率这种监控指标,这也不难解释在kubectl top时产生的报错,它还有一个核心作用:为HPA等组件提供决策指标支持。
kube-state-metrics关注于获取k8s各种资源的最新状态,如deployment或者daemonset,这里列出其提供的指标,指标类别包括:
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
之所以没有把kube-state-metrics纳入到metric-server的能力中,是因为他们的关注点本质上是不一样的。metric-server仅仅是获取、格式化现有数据,写入特定的存储,实质上是一个监控系统,可以直接将获取到的监控指标发送给存储后端,如influxdb或云厂商,并可以在grafana配置data source为influxdb来进行展示。
而kube-state-metrics是将k8s的运行状况在内存中做了个快照,并且获取新的指标,但他没有能力导出这些指标,需要借助Prometheus来做指标收集、集成,并导出到grafana
换个角度讲,kube-state-metrics本身是metric-server的一种数据来源,虽然现在没有这么做。
GitHub - kubernetes-sigs/metrics-server
容器监控实践—kube-state-metrics