相关指标

监控Kubernetes集群需要采集的指标,包括:

  • 基础设施的指标,即node的CPU、内存、网络等指标,这些指标主要通过Kubelet和Node-Export获取;

    Kubelet 服务本身会采集所在节点的相关,endpoint为:/api/v1/nodes/$1/proxy/metrics

  • 容器基础设施,即所有容器的CPU、内存、网络等指标;

    Kubelet 服务本身集成了cAdvisor,用户可以直接通过Kubelet组件获取给节点上容器相关监控指标,endpoint为:/api/v1/nodes/$1/proxy/metrics/cadvisor

  • Kubernetes组件指标,这些指标主要来自api-service

    api-service:https://:6443/metrics

  • Service、Endpoint、Ingress可用性的监控
  • 用户应用指标

监控组件

以下服务是Kubernetes常用监控组件:

1.K8S Metric

K8S 自身提供一下Summary API

  • API service
  • Kubelet 集成的节点资源API,以及cadvisor

通过HTTP访问上述API:

1
2
3
4
5
6
# PS: 使用prometheus-server的token可以保证有权限
TOKEN=$(kubectl get secrets $(kubectl get secrets -n kube-system | grep default-token | awk '{print $1}') -n kube-system -o jsonpath={.data.token} | base64 -d)
TOKEN=$(kubectl get secrets $(kubectl get secrets -n prometheus | grep prometheus-server-token | awk '{print $1}') -n prometheus -o jsonpath={.data.token} | base64 -d)
curl -k -H "Authorization:Bearer $TOKEN" https://<HOST_NAME or HOST_IP>:6443/metrics
curl -k -H "Authorization:Bearer $TOKEN" https://<HOST_NAME or HOST_IP>:6443/api/v1/nodes/<NODE_HOST_NAME>/proxy/metrics
curl -k -H "Authorization:Bearer $TOKEN" https://<HOST_NAME or HOST_IP>:6443/api/v1/nodes/<NODE_HOST_NAME>/proxy/metrics/cadvisor

上述可以获取的一些指标:

  • API Service
    • etcd_object_counts:etcd的对象数目
    • etcd_request_duration_seconds:etcd服务的请求时间
    • ssh_tunnel_open_count/ssh_tunnel_open_fail_count
    • API Service 本身的内存、进程数、GC等信息
  • Kubelet Node
    • Kubelet节点的证书信息、Token信息等
    • Kubelet服务的内存、进程数、GC等信息
  • Kubelet cadvisor Metrics

2.Metric-Server

Metrics Server 是集群核心监控数据的聚合器,周期性的调用Kubelet提供的 Summary API,将结果按Pod、Node 维度聚合,并存储在内存中。 另一方面,系统可以为自定义监控数据实现对应的 adapter, 用户就可以以 custom metrics API 的方式查询数据,保持与查询原生数据一致的体验。 通常弹性伸缩工具通过Metric-Server获取指标。

默认Metrics Server只包含了核心指标metrics.k8s.io,该Group提供了NodeMetricsPodMetrics2种类型的指标(高版本还有**ContainerMetrics **)。

1
curl -k -H "Authorization:Bearer $TOKEN" https://<metric-service-svc>:443/apis/metrics.k8s.io

Metrics Server 的最大作用实际上是整合了 K8S Metrics API 和 K8S 原有的管理平面API,使Metrics API 成为K8S集群的第一公民。 用户可以通过API Server 调用上述API(由于Kubectl是基于API Server工作的,因此安装了Metrics Server,kubectl top 命令才能正常工作)。

以下是使用RestAPI调用的示例代码,用户也可以引入k8s.io/metrics 包从而直接通过API进行调用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
var podMetrics models.PodMetricsList
	data, err := k8sClient.RESTClient().Get().AbsPath("apis/metrics.k8s.io/v1beta1/namespaces/my-namespace/pods").
		Param("labelSelector", "my-label=label1").
		Param("labelSelector", "my-label=label2").DoRaw()
	if err != nil {
		log.WithFields(map[string]interface{}{
			"error":          err.Error(),
		}).Errorf("get pods resource faield")
	}
	err = json.Unmarshal(data, &podMetrics)
	for _, item := range podMetrics.Items {
		retMetric := models.RetMetric{
			PodName: item.Metadata.Name,
			CPU:     item.Containers[0].Usage.CPU,
			Memory:  item.Containers[0].Usage.Memory,
		}
	}

Metric Server本质上是通过Kubernetes的[【 Aggregation Layer】](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/apiserver-aggreg ation/)实现的。

3.自定义HPA指标

当HPA请求metrics时,API-Service会将请求转发到Adapter(基于Aggregator机制),此时Adapter从Prometheus抓取并处理metrics并返回给HPA,最后由HPA实现对Deployment/ReplicaSet扩缩容。

Adapter作为extension-apiserver,充当了代理kube-apiserver请求Prometheus的功能。

4.Kube-State-Metrics

kube-state-metrics关注于获取k8s各种资源的最新状态,如deployment或者daemonset。

State-Metrics和Metric-Server的区别在于:

  • metric-server 提供指标聚合能力,本身不产生指标,其数据来自Kubelet、Custom Adapter等。
  • kube-state-metrics 根据集群Deployment等控制器状态,产生指标数据。

Node状态监控指标:

1
2
3
4
5
6
7
# Node 状态可以使用 kube_node_status_condition 进行监控,包括以下Conditions:
#		NetworkUnavailable
#		MemoryPressure
#		DiskPressure
#		PIDPressure
#		Ready
max(kube_node_status_condition{condition="Ready",status="true"}<1)

Pod状态的常用指标:

 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
# Pod状态异常的Reason,包括:<NodeLost|Evicted|UnexpectedAdmissionError> 这四种取值,但是新版本才有这些指标
kube_pod_status_reason
# Pod状态指标,包括:Pending|Running|Succeeded|Failed|Unknown
kube_pod_status_phase
# pod分阶段指标 ready表示状态可以用,scheduled表示容器已经调度(取值均为true/false/unknow)
kube_pod_status_ready/kube_pod_status_scheduled

# Pod Waiting 状态信息: 
# 		ContainerCreating
# 		CrashLoopBackOff
# 		ErrImagePull
# 		ImagePullBackOff
# 		InvalidImageName
# 		CreateContainerError
# 		CreateContainerConfigError
kube_pod_container_status_waiting/kube_pod_container_status_waiting_reason

# Pod 终止状态信息:
# 		OOMKilled
# 		Error
# 		Completed
# 		DeadlineExceeded
# 		Evicted
# 		ContainerCannotRun
kube_pod_container_status_terminated/kube_pod_container_status_last_terminated_reason

# 容器重启次数指标   
kube_pod_container_status_restarts_total

Prometheus监控集成

在监控K8S时,Prometheus通过kubernetes_sd_configs配置去动态发现集群中的target。

Prometheus还支持以下动态发现机制:

  • azure/ec2/digitalocean/openstack/gce_sd_config:动态发现不同平台的虚拟机
  • consul_sd_config:基于consul动态发现
  • dockerswarm_sd_config:动态发现services、tasks、nodes
  • dns_sd_config:基于DNS的动态发现(即根据服务器的DNS A, AAAA, SRV记录进行查询)
  • file_sd_config:基于文件的发现,文件里面是一些静态配置
  • marathon_sd_config:类似于K8S,是一种容器编排工具

Prometheus 动态发现的 target 含有以下 label (称为 Discovered Labels):

  • address : 当前Target实例的访问地址:
  • scheme : 采集目标服务访问地址的HTTP Scheme,HTTP或者HTTPS
  • metrics_path : 采集目标服务访问地址的访问路径
  • _param : 采集任务目标服务的中包含的请求参数
  • __meta_xxx : 和服务相关的若干label

通常,以 __ 开头的 Discovered Labels 是在系统内部使用的,这些标签不会被写入到样本数据中,即样本数据中没有这些label。

kubernetes_sd_configs

Prometheus 能够支持一下模式进行服务发现,包括:

  • node:发现集群中的node的 kubelet 地址,如__address__="172.29.55.234:10250"
  • service: 发现集群中所有Service的ip+端口,主要用来对服务进行黑盒的可用性检查
  • pod:发现所有pod的ip+暴露端口,如果pod没有暴露端口,那么__address__只有ip信息,如果暴露了多个端口那么会形成多个target
  • endpoint:发现所有endpoint的ip+端口,一个endpoint中可能包含了多个ip,每个ip都会被发现为一个target
  • ingress:发现所有的ingress地址

上述所有的发现方式,都会在target中采集到资源的namespace、label、annotation等配置。

relabel_config

relabel_config 发生在 Prometheus 获取 Discovered Labels 之后,从 target 拉数据之前。

这个过程会对 Discovered Labels 进行重写,有以下目的:

  • __address__ 生成样本数据中的 instance 标签;
  • 重写 __metrics_path__,部分endpoint的url地址不是标准的,需要重写;
  • 保留一些 Discovered Labels 到样本数据的 label 中;
  • 每个scrable可以串行配置多个relable;
  • relable 包含下面几个动作:
    • replace(重写值或者加入新值)
    • labelmap(重命名)
    • labelkeep/labeldrop(过滤target)

获取kubelete内置的cAdvisor数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
scrape_configs:
- bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
  job_name: kubernetes-nodes-cadvisor
  kubernetes_sd_configs:
  - role: node
  relabel_configs:
  - action: labelmap
    regex: __meta_kubernetes_node_label_(.+)
  - replacement: kubernetes.default.svc:443  # 默认action,replace
    target_label: __address__
  - regex: (.+) # 默认action,replace
    replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
    source_labels:
    - __meta_kubernetes_node_name
    target_label: __metrics_path__
  scheme: https
  tls_config:
    ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

参考

prometheus-book

relabing