[TOC]html
基于 RED方法 和 USE 方法 对如下四类指标进行分析:node
在Kubernetes中,cAdvisor嵌入到kubelet中,本文使用 USE 方法对容器的指标进行分析。linux
USE方法表明golang
cAdvisor提供的“容器”指标最终是底层Linux cgroup提供的。就像节点指标同样,不少很详细。可是咱们通常对CPU,内存,网络和磁盘感兴趣数据库
对于CPU利用率,Kubernetes仅为咱们提供了每一个容器的三个指标api
全部这些指标都是couter类型,须要对其rate算出使用率吗.缓存
下面的查询展现每一个容器正在使用的CPU:bash
sum( rate(container_cpu_usage_seconds_total [5m])) by(container_name)
若是您定义了CPU的 limit 值,计算饱和度将变得容易得多。服务器
当容器超出其CPU限制时,Linux运行时将“限制”该容器并在container_cpu_cfs_throttled_seconds_total指标中记录其被限制的时间网络
sum( rate(container_cpu_cfs_throttled_seconds_total[5m])) by (container_name)
就像node_exporter同样,cAdvisor不会暴露CPU错误。
cAdvisor中提供的内存指标是从node_exporter公开的43个内存指标的子集。如下是容器内存指标:
你可能认为使用container_memory_usage_bytes来计算内存使用率,可是这个指标还包括了文件系统缓存,是不许确的。更准确的是container_memory_working_set_bytes,他是 OOM 所关心的指标
sum(container_memory_working_set_bytes {name!〜“ POD”})by name
在上面的查询中,咱们须要排除名称包含“ POD”的容器。这是此容器的父级cgroup,将跟踪pod中全部容器的统计信息。
和 CPU 的饱和度计算类似,可是和 CPU 不一样,没法直接使用指标,由于 OOM 后 container 会被杀掉,可使用以下查询:
sum(container_memory_working_set_bytes) by (container_name) / sum(label_join(kube_pod_container_resource_limits_memory_bytes, "container_name", "", "container")) by (container_name)
这里使用label_join组合了 kube-state-metrics 的指标
kubelet不会暴露内存错误。
在处理磁盘I / O时,咱们首先经过查找和读写来跟踪全部磁盘利用率。
cAdvisor有如下指标:
最基本的磁盘I / O利用率是读/写的字节数:
sum(rate(container_fs_writes_bytes_total[5m])) by (container_name,device) sum(rate(container_fs_reads_bytes_total[5m])) by (container_name,device)
对这些求和,以得到每一个容器的整体磁盘I / O利用率。
由于没有磁盘的使用限制,没法对容器磁盘饱和度作衡量
Kubelet没有公开足够的细节,没法查看错误数
容器的网络利用率,能够选择以字节为单位仍是以数据包为单位。网络的指标有些不一样,由于全部网络请求都在Pod级别上进行,而不是在容器上进行
下面查询将按pod名称显示每一个pod的网络利用率:
sum(rate(container_network_receive_bytes_total[5m])) by (name) sum(rate(container_network_transmit_bytes_total[5m])) by (name)
一样,在不知道最大网络带宽是多少的状况下,网络的饱和度定义不明确。您也许可使用丢弃的数据包代替,表示当前已经饱和。
cAdvisor提供了
node-exporter能够检查节点的核心指标,从利用率,饱和度和错误的角度来看CPU,内存,磁盘和网络的监控指标
因为node_exporter提供了近1000个指标,有时很难知道要关心哪些。您的系统有哪些重要指标?分析的方法有多种多样,咱们能够简化和抽象为如下几类:四个黄金信号,USE方法和RED方法。
Google在“SRE Handbook”中以“四个黄金信号”的概念为咱们提供了一个论述:
当我第一次尝试将四个黄金信号应用于系统中的指标时,我常常被其中的一些术语以及它们如何应用于系统中的各个节点和应用程序所绊倒。
CPU的延迟或流量是多少?Kafka主题的饱和度是多少?
要定义应用程序的饱和度,咱们常常须要考虑应用程序使用的基础资源的饱和度。这些资源是什么,咱们如何对其进行监控?咱们可使用USE方法
Brendan Gregg在解释系统资源时如何考虑利用率、饱和度、错误方面作得很是出色。
他给出如下定义:
他建议(但没有规定)确切地表示在Unix系统的上下文中哪些度量表示利用率,饱和度和错误。本文的其他部分,我将USE方法应用于Kubernetes节点中的资源。
尽管USE方法针对的是资源,具备严格限制的实际物理资源,可是对于在这些资源上运行的软件而言,这是不完整的描述。这就是RED方法的用武之地。
Tom Wilkie解释RED方法为:
从表面上看,RED方法彷佛与USE方法和四个黄金信号很是类似。何时使用USE vs RED?
USE方法用于资源,RED方法用于服务 — Tom Wilkie
如今,咱们有两种方法能够帮助您选择要注意的指标。这东西是资源仍是应用程序?
集群中的节点具备资源。您的节点在Kubernetes群集中提供的最重要资源是CPU,内存,网络和磁盘。
让咱们将USE方法应用于全部这些方法。
node_exporter指标node_cpu会跟踪全部10个CPU mode 在每一个内核上花费的全部CPU时间。这些mode是:user, system, nice, idle, iowait, guest, guest_nice, steal, soft_irq and irq。
要计算您的Kubernetes集群中主机的cpu利用率,咱们但愿对全部mode进行累加, idle, iowait, guest, and guest_nice除外。PromQL看起来像这样:
sum(rate( node_cpu{mode!=”idle”, mode!=”iowait”, mode!~”^(?:guest.*)$” }[5m])) BY (instance)
关于此查询的一些注意事项:
cpu 提供的饱和度,是Unix的平均负载。平均负载是正在运行的进程数加上正在等待运行的进程数。一样,布伦丹·格雷格(Brendan Greg)在Linux平均负载方面有「很长的论述](http://www.brendangregg.com/b...。
node_load1,node_load5和node_load15分别表明一、5和15分钟的平均负载。该指标是一个gauge,已经为您进行了平均。做为一个独立的指标,知道节点有多少个CPU有些用处。
平均负载是10到底好仍是坏?这视状况而定。若是将平均负载除以机器拥有的CPU数量,则能够近似得出系统的CPU饱和度。
node_exporter不会直接公开节点CPU的数量,可是若是仅计算上述一种CPU模式(例如“ system”),则能够按节点获取CPU数量:
count(node_cpu{mode="system"}) by (node)
如今,您能够经过以百分比表示的节点上的CPU数量来规范化node_load1指标:
sum(node_load1) by (node) / count(node_cpu{mode="system"}) by (node) * 100
彷佛咱们的系统之一的CPU饱和度高达250%以上。须要调查一下!
node_exporter不显示有关CPU错误的任何信息。
因为已知节点上的物理内存量,所以彷佛能够更容易地推断出内存利用率和饱和度。可没有那么容易!node_exporter为咱们提供了43个node_memory_ *指标供您使用!
Linux系统上的可用内存量不只仅是报告的“free”内存指标。Unix系统严重依赖于应用程序未使用的内存来共享代码(buffers)和缓存磁盘页面(cached)。所以可用内存的一种度量是:
sum(node_memory_MemFree + node_memory_Cached + node_memory_Buffers)
较新的Linux内核(3.14以后)公开了更好的可用内存指标node_memory_MemAvailable。
将其除以节点上可用的总内存,便可获得可用内存的百分比,而后从1中减去以得出节点内存利用率的度量:
1 - sum(node_memory_MemAvailable) by (node) / sum(node_memory_MemTotal) by (node)
内存的饱和度是一个复杂的话题。从理论上讲,Unix系统具备无限数量的“虚拟内存”。若是对内存系统的需求过多,则操做系统将最近未使用的内存page返给硬盘“page to disk”。用某种说法,这称为“going into swap”。在实践中您永远不会想要这个
密切关注节点正在执行的分页数量能够是内存饱和度的一种度量。
node_exporter指标node_vmstat_pgpgin和node_vmstat_pgpgout显示节点的分页活动量。这是一个不完整的指标,由于对于依赖于Linux shared page cache的任何程序使用,内存分页都是正常活动。
Kubernetes为咱们提供了一些其余工具来限制集群中使用的内存量。即 limit 限制,容器资源请求和限制(若是实施得当)能够确保您的节点永远不会开始交换。我将在之后的文章中解决这些问题。
内存错误,在某些硬件上Linux和node_exporter能够经过EDAC,错误检测和纠正报告ECC内存。若是支持,则指标为:
node_edac_correctable_errors_total node_edac_uncorrectable_errors_total node_edac_csrow_correctable_errors_total node_edac_csrow_uncorrectable_errors_total
这些指标在个人机器上没法使用
当咱们谈论磁盘利用率和饱和度时,咱们须要考虑另外两个方面:磁盘容量和磁盘吞吐量。
磁盘容量的饱和度和利用率很是简单;它仅是对所用字节数的一种度量,以可用百分比表示
sum(node_filesystem_free{mountpoint="/"}) by (node, mountpoint) / sum(node_filesystem_size{mountpoint="/"}) by (node, mountpoint)
磁盘吞吐量的利用率和饱和度尚不清楚。
若是使用旋转磁盘,固态硬盘,RAID,网络链接的硬盘或网络块,则须要注意不一样的参数。正如咱们将在网络中看到的那样,饱和度很难在不知道底层硬件的特性的状况下进行计算,而底层硬件的特性一般对于内核是不可知的。
每一个设备的node_exporters会公开一些磁盘写入量之类的指标,还有
磁盘吞吐量显然是一个复杂的问题,您选择的指标将取决于硬件以及正在运行的工做负载的类型
无
无
咱们要解决的最后一个资源是网络
根据您的工做量,您可能对发送流量和接收流量比较感兴趣。如今我将利用率定义为已发送和已接收的总和。该查询将按节点为您提供全部网络接口的每秒字节数:
sum(rate(node_network_receive_bytes[5m])) by (node) + sum(rate(node_network_transmit_bytes[5m])) by (node)
不知道网络的容量,饱和度将很难肯定。咱们可使用丢弃的数据包做为饱和度的侧面论证:
sum(rate(node_network_receive_drop[5m])) by (node) + sum(rate(node_network_transmit_drop[5m])) by (node)
kube-apiserver 是集群全部请求的入口,指标的分析能够反应集群的健康状态。
Apiserver 的指标能够分为如下几大类:
基于 RED 方法,评估 apiserver 服务的一些指标:
Rate 速率
sum(rate(apiserver_request_count[5m])) by (resource, subresource, verb)
该查询会列出Kubernetes资源各类操做的五分钟的速率。操做有:WATCH,PUT,POST,PATCH,LIST,GET,DELETE和CONNECT
Error 错误
rate(apiserver_request_count{code=~"^(?:5..)$"}[5m]) / rate(apiserver_request_count[5m])
此查询获取5分钟内错误率与请求率的比率
Duration 请求时间
histogram_quantile(0.9, sum(rate(apiserver_request_latencies_bucket[5m])) by (le, resource, subresource, verb) ) / 1e+06
查看 90%状况下请求的时间分布
全部资源的请求都会被 apiserver 中的 controller 处理,controller 维护了队列,队列的一些指标能够反应资源处理的速度等指标
以apiserver_admission_controller为例:
API Server对etcd 的读写有缓存
apiserver 是 go 程序,目前全部 prometheus 采集的指标都会包含 golang 程序指标,如:
访问 apiserver 的 metric 时须要的参数
https://docs.signalfx.com/en/...
https://blog.freshtracks.io/a...
Kubernetes使用etcd来存储集群中组件的全部状态,它是 Kubernetes数据库,监视etcd的性能和行为应该是整个Kubernetes监控计划的一部分,Etcd是用Go语言编写的,而且与Kubernetes的其余服务同样,都是通过精心设计的,并使用Prometheus格式公开其指标。
由于 Etcd 是数据中心,所以访问 metrics 时须要配置鉴权,以防数据外泄。
etcd服务器指标分为几个主要类别:
Etcd是一个分布式键值存储。它使用 Rafe协议来选主。Leader能够响应某些事件(例如节点从新启动)而进行更改,从新在Member中选举Leader。更换Leader是很正常的,可是过多的Leader变动也是问题的征兆,多是网络问题致使的网络分区等
要确认Leader是否选出,etcd_server_has_leader值必须是1,不然就没有leader。这是要配置的告警规则:
# alert if any etcd instance has no leader ALERT NoLeader IF etcd_server_has_leader{job="etcd"} == 0 FOR 1m LABELS { severity = "critical" } ANNOTATIONS { summary = "etcd member has no leader", description = "etcd member {{ $labels.instance }} has no leader", }
Leader变动可使用 etcd_server_leader_changes_seen_total指标,能够经过如下PromQL查询:
sum(rate(etcd_server_leader_changes_seen_total[5m]))
这个值应该始终为 0,报警规则应该设置为:
# alert if there are lots of leader changes ALERT HighNumberOfLeaderChanges IF increase(etcd_server_leader_changes_seen_total{job="etcd"}[1h]) > 3 LABELS { severity = "warning" } ANNOTATIONS { summary = "a high number of leader changes within the etcd cluster are happening", description = "etcd instance {{ $labels.instance }} has seen {{ $value }} leader changes within the last hour", }
发送到etcd的写入和配置更改称为投票。Raft 协议确保将其正确提交到集群中。相关 metric 有:
失败数目过多应该报警,报警规则应该配置为:
# alert if there are several failed proposals within an hour ALERT HighNumberOfFailedProposals IF increase(etcd_server_proposals_failed_total{job="etcd"}[1h]) > 5 LABELS { severity = "warning" } ANNOTATIONS { summary = "a high number of proposals within the etcd cluster are failing", description = "etcd instance {{ $labels.instance }} has seen {{ $value }} proposal failures within the last hour", }
磁盘性能是etcd服务器性能的主要衡量指标,由于在follwer能够确认Leader的提议以前,必须将提案写入磁盘并进行同步。
要注意的两个重要指标是
# etcd disk io latency alerts # =========================== # alert if 99th percentile of fsync durations is higher than 500ms ALERT HighFsyncDurations IF histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m])) > 0.5 FOR 10m LABELS { severity = "warning" } ANNOTATIONS { summary = "high fsync durations", description = "etcd instance {{ $labels.instance }} fync durations are high", } # alert if 99th percentile of commit durations is higher than 250ms ALERT HighCommitDurations IF histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket[5m])) > 0.25 FOR 10m LABELS { severity = "warning" } ANNOTATIONS { summary = "high commit durations", description = "etcd instance {{ $labels.instance }} commit durations are high", }
Etcd使用gRPC在集群中的每一个节点之间进行通讯。最好跟踪这些请求的性能和错误数。
指标etcd_grpc_total表示按方法分类的grpc调用总数。
etc_grpc_requests_failed_total表示失败次数。
# gRPC request alerts # =================== # alert if more than 1% of gRPC method calls have failed within the last 5 minutes ALERT HighNumberOfFailedGRPCRequests IF sum by(grpc_method) (rate(etcd_grpc_requests_failed_total{job="etcd"}[5m])) / sum by(grpc_method) (rate(etcd_grpc_total{job="etcd"}[5m])) > 0.01 FOR 10m LABELS { severity = "warning" } ANNOTATIONS { summary = "a high number of gRPC requests are failing", description = "{{ $value }}% of requests for {{ $labels.grpc_method }} failed on etcd instance {{ $labels.instance }}", } # alert if more than 5% of gRPC method calls have failed within the last 5 minutes ALERT HighNumberOfFailedGRPCRequests IF sum by(grpc_method) (rate(etcd_grpc_requests_failed_total{job="etcd"}[5m])) / sum by(grpc_method) (rate(etcd_grpc_total{job="etcd"}[5m])) > 0.05 FOR 5m LABELS { severity = "critical" } ANNOTATIONS { summary = "a high number of gRPC requests are failing", description = "{{ $value }}% of requests for {{ $labels.grpc_method }} failed on etcd instance {{ $labels.instance }}", } # alert if the 99th percentile of gRPC method calls take more than 150ms ALERT GRPCRequestsSlow IF histogram_quantile(0.99, rate(etcd_grpc_unary_requests_duration_seconds_bucket[5m])) > 0.15 FOR 10m LABELS { severity = "critical" } ANNOTATIONS { summary = "slow gRPC requests", description = "on etcd instance {{ $labels.instance }} gRPC requests to {{ $label.grpc_method }} are slow", }
如何查看 etcd 的读写磁盘的 Latency?
能够经过etcd 的 metrics计算得出:5m 内的磁盘IO 延迟(99%区间)。如大于 500ms 报警
histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket{clusterID=”c-07v3Y2v5”,instanceIP=”100.70.181.251”}[5m])) > 0.5