cAdvisor 和 KubeStateMetrics 简介 在部署监控组件监控 Kubernetes 集群服务之前,先了解下监控组件 cAdvisor
和 Kube State Metrics
都是什么。本人从相应的俩个组件的 Github 和相关网址收集了一些信息,分别对其进行描述。
什么是 cAdvisor cAdvisor
(Container Advisor) 是 Google 开源的一个容器监控工具,可用于对容器资源的使用情况和性能进行监控。它以守护进程方式运行,用于收集、聚合、处理和导出正在运行容器的有关信息。具体来说,该组件对每个容器都会记录其资源隔离参数、历史资源使用情况、完整历史资源使用情况的直方图和网络统计信息。
cAdvisor
本身就对 Docker
容器支持,并且还对其它类型的容器尽可能的提供支持,力求兼容与适配所有类型的容器。
由以上介绍我们可以知道,cAdvisor 是用于监控容器引擎的。由于其监控的实用性,Kubernetes 已经默认将其与 Kubelet 融合,所以我们无需再单独部署 cAdvisor 组件来暴露节点中容器运行的信息,直接使用 Kubelet 组件提供的指标采集地址即可。
什么是 KubeStateMetrics Kube State Metrics
是一个简单的服务,该服务通过监听 Kubernetes API
服务器来生成不同资源的状态的 Metrics
数据。它不关注 Kubernetes 节点组件的运行状况,而是关注集群内部各种资源对象 (例如 deployment、node 和 pod) 的运行状况。
Kube State Metrics
是直接从 Kubernetes API
对象中获取生成的指标数据,这个过程中不会对指标数据进行修改。这样可以确保该组件提供的功能具有与 Kubernetes API 对象本身具有相同级别的稳定性。反过来讲,这意味着在某些情况下 Kube State Metrics
的 metrics 数据可能不会显示与 Kubectl
完全相同的值,因为 Kubectl
会应用某些启发式方法来显示可理解的消息。Kube State Metrics
公开了未经 Kubernetes API
修改的原始数据,这样用户可以拥有所需的所有数据,并根据需要执行启发式操作。
由于该组件 Kubernetes 并未与其默认集成在一起,所以需要我们单独部署。Kube-State-Metrics下载
总结 要让 Prometheus
能监控 kubernetes
中容器的性能指标和 kubernetes
资源对象指标,需要部署 cadvisor
与 kube-state-metrics
。目前 cAdvisor
已经被 Kubernetes
默认集成,而Kube State Metrics
并没有被默认集成,所以我们需要在 Kubernetes
中部署 Kube State Metrics
组件,这样才能够将集群中的服务资源指标数据暴露出来,以便于我们对不同资源进行监控。
Prometheus使用kubernetes_sd_config 要想监控Kubernetes中的资源,Prometheus要使用 kubernetes_sd_config
来自动注册和自动发现。Kubernetes SD 配置允许从 Kubernetes 的REST API检索抓取目标,并始终与集群状态保持同步。
kubernetes_sd_config
这个是以角色(role)来定义收集的,<role>
必须是endpoints
、service
、 pod
、node
或ingress
。
以下是生产环境实际配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 scrape_configs: - job_name: kube-apiserver/0 honor_timestamps: true scrape_interval: 30 s scrape_timeout: 10 s metrics_path: /metrics scheme: https authorization: credentials_file: /var/ run/secrets/ kubernetes.io/serviceaccount/ token tls_config: ca_file: /var/ run/secrets/ kubernetes.io/serviceaccount/ ca.crt server_name: kubernetes insecure_skip_verify: false follow_redirects: true kubernetes_sd_configs: - role: endpoints # 使用的role namespaces: # 指定抓取的名称空间,如不指定则表示抓取所有名称空间 names: - default
点击此查看官方示例
Role可配置的发现目标 点击此查看官方介绍
node node角色发现每个群集节点有一个目标,其地址默认为Kubelet的HTTP端口。 目标地址默认为NodeInternalIP,NodeExternalIP,NodeLegacyHostIP和NodeHostName的地址类型顺序中Kubernetes节点对象的第一个现有地址。 可用元标签:
1 2 3 4 5 6 __meta_kubernetes _node_name:节点对象的名称。 __meta_kubernetes _node_label_<labelname>:节点对象中的每个标签。 __meta_kubernetes _node_labelpresent_<labelname>:true 对于节点对象中的每个标签。 __meta_kubernetes _node_annotation_<annotationname>:来自节点对象的每个注释。 __meta_kubernetes _node_annotationpresent_<annotationname>:true 对于节点对象中的每个注释。 __meta_kubernetes _node_address_<address_type>:每个节点地址类型的第一个地址(如果存在)。
另外,对于节点的instance
标签,将会被设置成从API服务中获取的节点名称。
service 该service角色为每个服务发现每个服务端口的目标。这对于服务的黑盒监控通常很有用。该地址将设置为服务的Kubernetes DNS名称和相应的服务端口。 可用元标签:
1 2 3 4 5 6 7 8 9 10 __meta_kubernetes _namespace:服务对象的命名空间。 __meta_kubernetes _service_annotation_<annotationname>:来自服务对象的每个注释。 __meta_kubernetes _service_annotationpresent_<annotationname>:“true ”表示服务对象的每个注释。 __meta_kubernetes _service_cluster_ip:服务的群集IP地址。(不适用于ExternalName类型的服务) __meta_kubernetes _service_external_name:服务的DNS名称。(适用于ExternalName类型的服务) __meta_kubernetes _service_label_<labelname>:来自服务对象的每个标签。 __meta_kubernetes _service_labelpresent_<labelname>:true 对于服务对象的每个标签。 __meta_kubernetes _service_name:服务对象的名称。 __meta_kubernetes _service_port_name:目标服务端口的名称。 __meta_kubernetes _service_port_protocol:目标服务端口的协议。
pod 该pod角色发现所有pod并将其容器公开为目标。对于容器的每个声明端口,将生成单个目标。如果容器没有指定端口,则会创建每个容器的无端口目标,以通过重新标记手动添加端口。 可用元标签:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 __meta_kubernetes _namespace:pod对象的命名空间。 __meta_kubernetes _pod_name:pod对象的名称。 __meta_kubernetes _pod_ip:pod对象的pod IP。 __meta_kubernetes _pod_label_<labelname>:pod对象中的每个标签。 __meta_kubernetes _pod_labelpresent_<labelname>:true 对于pod对象中的每个标签。 __meta_kubernetes _pod_annotation_<annotationname>:pod对象中的每个注释。 __meta_kubernetes _pod_annotationpresent_<annotationname>:true 对于pod对象中的每个注释。 __meta_kubernetes _pod_container_init:true 如果容器是InitContainer __meta_kubernetes _pod_container_name:目标地址指向的容器的名称。 __meta_kubernetes _pod_container_port_name:容器端口的名称。 __meta_kubernetes _pod_container_port_number:容器端口号。 __meta_kubernetes _pod_container_port_protocol:容器端口的协议。 __meta_kubernetes _pod_ready:设置为true 或false 准备好pod的就绪状态。 __meta_kubernetes _pod_phase:设置为Pending,Running,Succeeded,Failed或Unknown在生命周期。 __meta_kubernetes _pod_node_name:pod安排到的节点的名称。 __meta_kubernetes _pod_host_ip:pod对象的当前主机IP。 __meta_kubernetes _pod_uid:pod对象的UID。 __meta_kubernetes _pod_controller_kind:对象类型的pod控制器。 __meta_kubernetes _pod_controller_name:pod控制器的名称。
endpoints 该endpoints角色从列出的服务端点发现目标。对于每个端点地址,每个端口发现一个目标。如果端点由pod支持,则pod的所有其他容器端口(未绑定到端点端口)也会被发现为目标。 可用元标签:
1 2 3 4 5 6 7 8 9 __meta_kubernetes _namespace:端点对象的命名空间。 __meta_kubernetes _endpoints_name:端点对象的名称。对于直接从端点列表中发现的所有目标(不是从底层pod中另外推断的那些),附加以下标签: __meta_kubernetes _endpoint_hostname:端点的主机名。 __meta_kubernetes _endpoint_node_name:托管端点的节点的名称。 __meta_kubernetes _endpoint_ready:设置为true 或false 为端点的就绪状态。 __meta_kubernetes _endpoint_port_name:端点端口的名称。 __meta_kubernetes _endpoint_port_protocol:端点端口的协议。 __meta_kubernetes _endpoint_address_target_kind:端点地址目标的种类。类型不同看到的标签不同。 __meta_kubernetes _endpoint_address_target_name:端点地址目标的名称
如果端点属于服务,则附加role: service
发现的所有标签。 对于由pod支持的所有目标,将附加role: pod
发现的所有标签。
ingress 该ingress角色发现了一个目标,为每个进入的每个路径。这通常用于黑盒监控入口。地址将设置为入口规范中指定的主机。 可用元标签:
1 2 3 4 5 6 7 8 __meta_kubernetes _namespace:入口对象的命名空间。 __meta_kubernetes _ingress_name:入口对象的名称。 __meta_kubernetes _ingress_label_<labelname>:入口对象中的每个标签。 __meta_kubernetes _ingress_labelpresent_<labelname>:true 对于入口对象中的每个标签 __meta_kubernetes _ingress_annotation_<annotationname>:来自入口对象的每个注释。 __meta_kubernetes _ingress_annotationpresent_<annotationname>:true 对于来自入口对象的每个注释。 __meta_kubernetes _ingress_scheme:入口的协议方案,https如果设置了TLS配置。默认为http。 __meta_kubernetes _ingress_path:来自入口规范的路径。默认为/。
配置抓取 service 监控写法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 cat << EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: labels: app: prometheus-k8s name: prometheus-k8s annotations: prometheus.io/scrape: 'true' namespace: monitoring spec: ports: - name: web port: 9090 targetPort: web selector: app: prometheus-k8s sessionAffinity: ClientIP EOF
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 cat << EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: annotations: prometheus.io/port: "10257" prometheus.io/scrape: "true" prometheus.io/scheme: "https" labels: k8s-app: kube-controller-manager name: kube-controller-manager namespace: monitoring spec: clusterIP: None ports: - name: https-metrics port: 10257 protocol: TCP targetPort: 10257 sessionAffinity: None type: ClusterIP --- apiVersion: v1 kind: Endpoints metadata: labels: k8s-app: kube-controller-manager name: kube-controller-manager namespace: monitoring subsets: - addresses: - ip: 192.168 .2 .175 - ip: 192.168 .2 .176 - ip: 192.168 .2 .177 ports: - name: https-metrics port: 10257 protocol: TCP EOF
service写法使用的role 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 - job_name: kubernetes-endpoints honor_timestamps: true scrape_interval: 10s scrape_timeout: 10s metrics_path: /metrics scheme: http kubernetes_sd_configs: - role: endpoints bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true relabel_configs: - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape ] separator: ; regex: "true" replacement: $1 action: keep - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme ] separator: ; regex: (https?) target_label: __scheme__ replacement: $1 action: replace - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path ] separator: ; regex: (.+) target_label: __metrics_path__ replacement: $1 action: replace - source_labels: [__address__ , __meta_kubernetes_service_annotation_prometheus_io_port ] separator: ; regex: ([^:]+)(?::\d+)?;(\d+) target_label: __address__ replacement: $1:$2 action: replace
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 29 30 31 apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: component: kube-apiserver-ha-proxy tier: control-plane annotations: prometheus.io/port: "8404" prometheus.io/scrape: "true" name: kube-apiserver-ha-proxy namespace: kube-system spec: containers: - args: - "CP_HOSTS=192.168.2.175,192.168.2.176,192.168.2.177" image: docker.io/juestnow/nginx-proxy:1.21.0 imagePullPolicy: IfNotPresent name: kube-apiserver-ha-proxy env: - name: CPU_NUM value: "4" - name: BACKEND_PORT value: "5443" - name: HOST_PORT value: "6443" - name: CP_HOSTS value: "192.168.2.175,192.168.2.176,192.168.2.177" hostNetwork: true priorityClassName: system-cluster-critical status: {}
1 2 3 4 5 6 7 8 9 10 11 12 13 spec: selector: matchLabels: k8s-app: traefik template: metadata: creationTimestamp: null labels: k8s-app: traefik annotations: prometheus.io/port: '8080' prometheus.io/scrape: 'true'
pod监控使用的role 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 - job_name: kubernetes-pods honor_timestamps: true scrape_interval: 10s scrape_timeout: 10s metrics_path: /metrics scheme: http bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape ] separator: ; regex: "true" replacement: $1 action: keep - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme ] separator: ; regex: (https?) target_label: __scheme__ replacement: $1 action: replace - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path ] separator: ; regex: (.+) target_label: __metrics_path__ replacement: $1 action: replace - source_labels: [__address__ , __meta_kubernetes_pod_annotation_prometheus_io_port ] separator: ; regex: ([^:]+)(?::\d+)?;(\d+) target_label: __address__ replacement: $1:$2 action: replace
blackbox-exporter 集群内部监控注释方法 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 cat << EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: labels: app: prometheus-k8s name: prometheus-k8s annotations: prometheus.io/web: 'true' prometheus.io/healthz: "/-/healthy" namespace: monitoring spec: ports: - name: web port: 9090 targetPort: web selector: app: prometheus-k8s sessionAffinity: ClientIP EOF cat << EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: labels: app: prometheus-k8s name: prometheus-k8s annotations: prometheus.io/tcp: 'true' namespace: monitoring spec: ports: - name: web port: 9090 targetPort: web selector: app: prometheus-k8s sessionAffinity: ClientIP EOF cat << EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: labels: app: prometheus-k8s name: prometheus-k8s annotations: prometheus.io/icmp: 'true' namespace: monitoring spec: ports: - name: web port: 9090 targetPort: web selector: app: prometheus-k8s sessionAffinity: ClientIP EOF cat << EOF | kubectl apply -f - kind: Ingress apiVersion: networking.k8s.io/v1 metadata: name: prometheus-dashboard annotations: prometheus.io/probed: 'true' namespace: monitoring spec: rules: - host: prometheus.tycng.com http: paths: - pathType: ImplementationSpecific path: / backend: service: name: prometheus-k8s port: number: 9090 EOF
Kubernetes 组件指标 Kubernetes自身的组件也是通过/metrics
来暴露组件内部的一些指标,这样我们可以更好地了解kubernetes系统中各个组件内部发生的情况。我们可以通过 HTTP 访问组件的 /metrics
端点来获取组件的指标。有些组件默认情况下绑定在--bind-address=127.0.0.1
,可以使用 --bind-address=0.0.0.0
标志启用。 这些组件的示例:(以下表格是v1.22.4版本)
组件
metrics端口
协议
kube-controller-manager
10257
https
kube-proxy
10249
http
kkube-apiserver
6443
https
kube-scheduler
10259
https
kubelet
10250
https
在生产环境中,你可能需要配置 Prometheus 服务器 或 某些其他指标搜集器以定期收集这些指标,并使它们在某种时间序列数据库中可用。
请注意,kubelet 还会在 /metrics/cadvisor
, /metrics/resource
和 /metrics/probes
端点中公开度量值。这些度量值的生命周期各不相同。
组件指标 kube-controller-manager 指标 控制器管理器指标可提供有关控制器管理器性能和运行状况的重要洞察。 这些指标包括通用的 Go 语言运行时指标(例如 go_routine 数量)和控制器特定的度量指标, 例如可用于评估集群运行状况的 etcd 请求延迟或云提供商(AWS、GCE、OpenStack)的 API 延迟等。
从 Kubernetes 1.7 版本开始,详细的云提供商指标可用于 GCE、AWS、Vsphere 和 OpenStack 的存储操作。 这些指标可用于监控持久卷操作的运行状况。
比如,对于 GCE,这些指标称为:
1 2 3 4 5 6 cloudprovider_gce_api_request_duration_seconds { request = "instance_list" } cloudprovider_gce_api_request_duration_seconds { request = "disk_insert" } cloudprovider_gce_api_request_duration_seconds { request = "disk_delete" } cloudprovider_gce_api_request_duration_seconds { request = "attach_disk" } cloudprovider_gce_api_request_duration_seconds { request = "detach_disk" } cloudprovider_gce_api_request_duration_seconds { request = "list_disk" }
kube-scheduler 指标 调度器会暴露一些可选的指标,报告所有运行中 Pods 所请求的资源和期望的约束值。 这些指标可用来构造容量规划监控面板、访问调度约束的当前或历史数据、 快速发现因为缺少资源而无法被调度的负载,或者将 Pod 的实际资源用量 与其请求值进行比较。
kube-scheduler 组件能够辩识各个 Pod 所配置的资源 请求和约束。 在 Pod 的资源请求值或者约束值非零时,kube-scheduler 会以度量值时间序列的形式 生成报告。该时间序列值包含以下标签:
名字空间
Pod 名称
Pod 调度所处节点,或者当 Pod 未被调度时用空字符串表示
优先级
为 Pod 所指派的调度器
资源的名称(例如,cpu)
资源的单位,如果知道的话(例如,cores)
一旦 Pod 进入完成状态(其 restartPolicy
为 Never
或 OnFailure
,且 其处于 Succeeded
或 Failed
Pod 阶段,或者已经被删除且所有容器都具有 终止状态),该时间序列停止报告,因为调度器现在可以调度其它 Pod 来执行。 这两个指标称作 kube_pod_resource_request
和 kube_pod_resource_limit。
指标暴露在 HTTP 端点 /metrics/resources
,与调度器上的 /metrics
端点 一样要求相同的访问授权。你必须使用 --show-hidden-metrics-for-version=1.20
标志才能暴露那些稳定性为 Alpha 的指标。