k8s Metrics Server 0.6.x

发布时间 2023-06-12 18:24:15作者: 小吉猫

资源监控指标

  Kubernetes系统上的关键指标大体可以分为两个主要组成部分:集群系统本身的指标和容器应用相关的指标。对于集群系统本身相关的监控层面而言,监控整个Kubernetes集群的健康状况是最核心的需求,包括所有工作节点是否运行正常、系统资源容量大小、每个工作节点上运行的容器化应用的数量以及整个集群的资源利用率等,它们通常可分为如下一些可衡量的指标。
  监控集群所有节点的常用方法之一是通过DaemonSet控制器在各节点部署一个采集监控指标数据的代理程序,由代理程序将节点级采集的各种指标数据上报至监控服务端,以统一进行数据的处理、存储和展示。

集群系统本身指标

节点资源状态

  多数指标都与节点上的系统资源利用状况有关,例如网络带宽、磁盘空间、CPU和内存的利用率等,它们也是管理员能够评估集群规模合理性的重要标准。

节点数量

  在公有云服务商以实例数量计费的场景中,根据集群整体应用的资源需求规模实时调整集群节点规模是常见的弹性伸缩应用场景之一,而实时了解集群中的可用节点数量也给了用户计算所需支付费用的参考标准。

活动Pod对象的数量

  正在运行的Pod对象数量常用于评估可用节点的数量是否足够,以及在节点发生故障时它们是否能够承接整个工作负载等。

容器应用相关的指标

  编排运行容器化应用是Kubernetes平台的核心价值所在,通常以Pod资源形式存在的容器化应用才是集群上计算资源的消耗主力,这些应用的监控需求通常可以大体分为3类:应用编排指标、容器指标和应用程序指标。

应用编排指标

  用于监视特定应用程序相关的Pod对象的部署过程、当前副本数量、期望的副本数量、部署过程进展状态、健康状态监测及网络服务器的可用性等,这些指标数据需要经由Kubernetes系统接口获取。

容器指标

  包括容器的资源需求、资源限制以及CPU、内存、磁盘空间、网络带宽等资源的实际占用状况等。

应用程序指标

  应用程序内置的指标,通常与其所处理的业务规则相关,例如,关系型数据库应用程序可能会内置用于暴露索引状态的指标,以及表和关系的统计指标等。

指标系统

  Kubernetes通过API Aggregator(聚合器)为开发人员提供了轻松扩展API资源的能力,为集群添加指标数据API的自定义指标API、资源指标API(简称为指标API)和外部指标API都属于这种类型的扩展。
资源指标API是调度程序、HPA、VPA和kubectl top命令等核心系统组件可选甚至是强制依赖的基础功能,尽管是以扩展方式实现,但它提供的是Kubernetes系统必备的“核心指标”,因而并不适合与类似于Prometheus一类的第三方监控系统集成。这类的指标由轻量级且基于易失性存储器的Metrics Server收集,并通过metrics.k8s.io这一API群组公开。另一方面,自定义指标API或外部指标API为用户提供了按需进行指标扩展的接口,它支持用户将自定义指标类型的APIServer直接聚合进主API服务器中,因此具有更广泛的使用场景。简单总结起来,Kubernetes监控系统架构主要由核心指标流水线和监控指标流水线共同组成。

核心指标管道

  由kubelet、资源评估器、Metrics Server以及提供关键指标API的API Server共同组成,它们为Kubernetes系统提供核心指标。Metrics Server通过服务发现机制发现集群上的所有节点,而后自动采集每个节点上kubelet的CPU和内存使用状态。kubelet完全能够基于容器运行时接口获取容器的统计信息,同时为了能够兼容较旧版本的Docker,它也支持从内部集成的cAdvisor采集资源指标信息,这些指标数据经由kubelet守护进程监听TCP的10250端口,并以只读方式对外提供,最终由Metrics Server完成聚合后对外公开。
  截至目前,核心指标管道中的指标主要包括CPU累计使用、内存即时利用率、Pod资源占用率及容器的磁盘占用率等。这些度量标准的核心系统组件包括调度逻辑(基于指标数据的调度程序和应用规模的水平缩放),以及部分UI组件(例如kubectl top命令和Dashboard)等。

监控管道

  监控指标相关的管道负责从系统收集各种指标数据,并提供给终端用户、存储系统以及HPA控制器等使用。事实上,监控管道会收集包含核心指标(未必是Kubernetes可解析的格式)在内的大多数指标,核心指标集合之外的其他指标通常称为非核心指标。Kubernetes自定义指标API允许用户扩展任意数量的、特定于应用程序的指标,例如队列长度、每秒入站请求数等。Kubernetes系统自身既不会提供这类组件,也不为这些指标提供相关的解释,它依赖于用户使用的第三方整体解决方案。
  Kubernetes系统上能同时使用资源指标API和自定义指标API的代表组件是HPA v2控制器(HorizontalPodAutoscaler),它能够基于观察到的指标自动缩放Deployment或ReplicaSet一类控制器编排的应用程序的规模。而传统的HPA v1控制器仅支持根据CPU利用率进行应用规模缩放,但CPU利用率并不总是最适合自动调整应用程序规模的度量指标,也不应该是唯一指标。
  从根本上来讲,资源指标API与自定义指标API都仅是API的定义和规范,它们自身都未提供具体的实现。目前,资源指标API的主流实现是Metrics Service项目,而自定义指标API则以构建在Prometheus[1]之上的k8s-prometheus-adapter接受最为广泛。

资源监控工具

  要扩展应用程序并提供可靠的服务,你需要了解应用程序在部署时的行为。 你可以通过检测容器检查 Kubernetes 集群中的应用程序性能, Pod、 服务和整个集群的特征。 Kubernetes 在每个级别上提供有关应用程序资源使用情况的详细信息。 此信息使你可以评估应用程序的性能,以及在何处可以消除瓶颈以提高整体性能。

  在 Kubernetes 中,应用程序监控不依赖单个监控解决方案。在新集群上, 你可以使用资源度量或完整度量管道来收集监视统计信息。

资源度量管道

  资源指标管道提供了一组与集群组件,例如 Horizontal Pod Autoscaler 控制器以及 kubectl top 实用程序相关的有限度量。 这些指标是由轻量级的、短期、内存存储的 metrics-server 收集的, 通过 metrics.k8s.io 公开。

  度量服务器发现集群中的所有节点,并且查询每个节点的 kubelet 以获取 CPU 和内存使用情况。 Kubelet 充当 Kubernetes 主节点与节点之间的桥梁,管理机器上运行的 Pod 和容器。 kubelet 将每个 Pod 转换为其组成的容器,并通过容器运行时接口从容器运行时获取各个容器使用情况统计信息。 如果某个容器运行时使用 Linux cgroups 和名字空间来实现容器。 并且这一容器运行时不发布资源用量统计信息, 那么 kubelet 可以直接查找这些统计信息(使用来自 cAdvisor 的代码)。 无论这些统计信息如何到达,kubelet 都会通过 metrics-server Resource Metrics API 公开聚合的 Pod 资源用量统计信息。 该 API 在 kubelet 的经过身份验证和只读的端口上的 /metrics/resource/v1beta1 中提供。

完整度量管道

  一个完整度量管道可以让你访问更丰富的度量。 Kubernetes 还可以根据集群的当前状态,使用 Pod 水平自动扩缩器等机制, 通过自动调用扩展或调整集群来响应这些度量。 监控管道从 kubelet 获取度量值,然后通过适配器将它们公开给 Kubernetes, 方法是实现 custom.metrics.k8s.io 或 external.metrics.k8s.io API。

  Kubernetes 在设计上保证能够与 OpenMetrics 一同使用, OpenMetrics 是 CNCF 可观测性和分析 - 监控项目之一, 它构建于 Prometheus 暴露格式之上, 并对其进行了扩展,这些扩展几乎 100% 向后兼容。
 
  如果你浏览 CNCF Landscape, 你可以看到许多监控项目,它们可以用在 Kubernetes 上,抓取指标数据并利用这些数据来观测你的集群, 选择哪种工具或哪些工具可以满足你的需求,这完全取决于你自己。 CNCF 的可观测性和分析景观包括了各种开源软件、付费的软件即服务(SaaS)以及其他混合商业产品。

  当你设计和实现一个完整的指标监控数据管道时,你可以将监控数据反馈给 Kubernetes。 例如,HorizontalPodAutoscaler 可以使用处理过的指标数据来计算出你的工作负载组件运行了多少个 Pod。

  将完整的指标管道集成到 Kubernetes 实现中超出了 Kubernetes 文档的范围,因为可能的解决方案具有非常广泛的范围。

  监控平台的选择在很大程度上取决于你的需求、预算和技术资源。 Kubernetes 不推荐任何特定的指标管道; 可使用许多选项。 你的监控系统应能够处理 OpenMetrics 指标传输标准, 并且需要选择最适合基础设施平台的整体设计和部署。

Metrics Server

Metrics Server介绍

  资源指标API与Kubernetes系统的其他API并无特别不同之外,它同样可经API Server的URL路径(/apis/metrics.k8s.io/)进行存取,于是也拥有同样级别的安全性、稳定性及可靠性。只有在Kubernetes集群中部署Metrics Server应用后,核心指标API才真正可用。
  Metrics Server是集群级别资源利用率数据的聚合器,它受Heapster项目启发,且在功能和特性上完全可视作一个仅服务于指标数据的简化版的Heapster。Metrics Server通过Kubernetes聚合器(kube-aggregator)注册到主API Server之上,而后基于kubelet的Summary API收集每个节点上的指标数据,将它们存储在内存中并以指标API格式提供。
  Metrics Server基于内存存储,重启后数据将全部丢失,而且它仅能留存最近收集到的指标数据,因此,如果用户希望访问历史数据,就不得不借助第三方的监控系统(例如Prometheus等)或自行开发实现这样的功能。
  Metrics API 及其启用的指标管道仅提供最少的 CPU 和内存指标,以启用使用 HPA 和/或 VPA 的自动扩展。 如果你想提供更完整的指标集,你可以通过部署使用 Custom Metrics API 的第二个指标管道来作为简单的 Metrics API 的补充。

Metrics Server架构

cAdvisor: 用于收集、聚合和公开 Kubelet 中包含的容器指标的守护程序。 cAdvisor 支持从 cgroups 读取指标,它适用于 Linux 上的典型容器运行时。 如果你使用基于其他资源隔离机制的容器运行时,例如虚拟化,那么该容器运行时必须支持 CRI 容器指标 以便 kubelet 可以使用指标。

kubelet: 用于管理容器资源的节点代理。 可以使用 /metrics/resource 和 /stats kubelet API 端点访问资源指标。

Summary API: kubelet 提供的 API,用于发现和检索可通过 /stats 端点获得的每个节点的汇总统计信息。

metrics-server: 集群插件组件,用于收集和聚合从每个 kubelet 中提取的资源指标。 API 服务器提供 Metrics API 以供 HPA、VPA 和 kubectl top 命令使用。Metrics Server 是 Metrics API 的参考实现。

Metrics API: Kubernetes API 支持访问用于工作负载自动缩放的 CPU 和内存。 要在你的集群中进行这项工作,你需要一个提供 Metrics API 的 API 扩展服务器。

Metrics Server配置项

  核心指标是Kubernetes多个核心组件的基础依赖,因此Metric Server应该在集群创建之初便作为核心组件部署运行在集群中。Metrics Server通常仅需要在集群中运行单个实例即可,它会在启用时自动初始化与各节点的连接,因而出于安全方面的考虑,它仅应该运行在普通节点之上,且需要根据目标Kubernetes集群的环境等因素定制几个配置选项。
--tls-cert-file和--tls-private-key-file:metrics-server服务进程使用的证书和私钥,未指定时将由程序自动生成自签证书,生产环境建议自行指定。
--secure-port=<port>:metrics-server服务进程对外提供服务的端口,默认为443,以非管理员账户运行时建议修改为1024及以上的端口号,例如4443等。
--metric-resolution=<duration>:从kubelet抓取指标数据的时间间隔,默认为60秒。
--kubelet-insecure-tls:不验证kubelet签发证书的CA,对于kubelet使用自签证书的测试环境较为有用,但不建议在生产环境使用。
--kubelet-preferred-address-types:与kubelet通信时倾向于使用的地址类型顺序,默认为Hostname、InternalDNS、InternalIP、ExternalDNS和ExternalIP。
--kubelet-port:kubelet监听的能够提供指标数据的端口号,默认为10250。
  对于使用kubeadm部署的Kubernetes集群来说,若未指定签署节点证书的CA,也未给每个节点配置自定义证书,则各kubelet通常是在Bootstrap过程中生成自签证书,这类证书无法由Metrics Server完成CA验证,因此需要使用--kubelet-insecure-tls选项来禁用这种验证功能。

度量资源用量

CPU

  CPU 报告为以 cpu 为单位测量的平均核心使用率。在 Kubernetes 中, 一个 cpu 相当于云提供商的 1 个 vCPU/Core,以及裸机 Intel 处理器上的 1 个超线程。

  该值是通过对内核提供的累积 CPU 计数器(在 Linux 和 Windows 内核中)取一个速率得出的。 用于计算 CPU 的时间窗口显示在 Metrics API 的窗口字段下。

内存

  内存报告为在收集度量标准的那一刻的工作集大小,以字节为单位。

  在理想情况下,“工作集”是在内存压力下无法释放的正在使用的内存量。 然而,工作集的计算因主机操作系统而异,并且通常大量使用启发式算法来产生估计。

  Kubernetes 模型中,容器工作集是由容器运行时计算的与相关容器关联的匿名内存。 工作集指标通常还包括一些缓存(文件支持)内存,因为主机操作系统不能总是回收页面。

Metrics Server部署

  metrics-server部署清单会在kube-system名称空间中创建出多种类型的资源对象,包括RBAC相关的RoleBinding、ClusterRole和ClusterroleBinding对象以及Service Account对象,以实现在启用了RBAC授权插件的集群上对metrics-server开放资源访问的许可。另外,它还会通过一个APIService对象创建Metrics API相关的群组(metrics.k8s.io),从而将Metrics Server提供的API聚合进主APIServer,并且在该群组中提供两个用于指标获取的nodes和pods资源类型。

下载部署清单

# wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.3/components.yaml -O components-v0.6.3.yaml

创建 Metrics Server

# kubectl apply -f components-v0.6.3.yaml

查看metrics server pod

# kubectl get pod -n kube-system | grep metrics-server
metrics-server-6667d7c755-wwb2c           1/1     Running   0                83s

查看Metrics API

# kubectl api-resources --api-group='metrics.k8s.io'
NAME    SHORTNAMES   APIVERSION               NAMESPACED   KIND
nodes                metrics.k8s.io/v1beta1   false        NodeMetrics
pods                 metrics.k8s.io/v1beta1   true         PodMetrics

通过API查询资源信息

查看集群节点资源使用情况

# kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes"| jq .
{
  "kind": "NodeMetricsList",
  "apiVersion": "metrics.k8s.io/v1beta1",
  "metadata": {},
  "items": [
    {
      "metadata": {
        "name": "192.168.174.100",
        "creationTimestamp": "2023-06-12T09:47:16Z",
        "labels": {
          "beta.kubernetes.io/arch": "amd64",
          "beta.kubernetes.io/os": "linux",
          "kubernetes.io/arch": "amd64",
          "kubernetes.io/hostname": "192.168.174.100",
          "kubernetes.io/os": "linux",
          "kubernetes.io/role": "master"
        }
      },
      "timestamp": "2023-06-12T09:47:02Z",
      "window": "20.014s",
      "usage": {
        "cpu": "78545018n",
        "memory": "1432820Ki"
      }
    },
.....

查看kube-system命名空间中pod的资源使用情况

# kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/metrics-server-6667d7c755-wwb2c" | jq '.'
{
  "kind": "PodMetrics",
  "apiVersion": "metrics.k8s.io/v1beta1",
  "metadata": {
    "name": "metrics-server-6667d7c755-wwb2c",
    "namespace": "kube-system",
    "creationTimestamp": "2023-06-12T09:58:09Z",
    "labels": {
      "k8s-app": "metrics-server",
      "pod-template-hash": "6667d7c755"
    }
  },
  "timestamp": "2023-06-12T09:57:54Z",
  "window": "17.711s",
  "containers": [
    {
      "name": "metrics-server",
      "usage": {
        "cpu": "2689684n",
        "memory": "16592Ki"
      }
    }
  ]
}

显示资源使用信息

nodes资源信息

# kubectl top nodes
NAME              CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
192.168.174.100   68m          3%     1428Mi          87%       
192.168.174.101   80m          4%     1362Mi          82%       
192.168.174.102   98m          4%     1344Mi          81%       
192.168.174.106   60m          3%     1364Mi          38%       
192.168.174.107   62m          3%     1058Mi          29%       
192.168.174.108   48m          2%     1047Mi          29%  

pods信息

# kubectl top pods -n default
NAME                          CPU(cores)   MEMORY(bytes)   
demoappv10-78b6586d58-4fmf9   3m           58Mi            
demoappv10-78b6586d58-gwpf5   3m           54Mi            
proxy-6cd46fb7d7-gg8hr        3m           52Mi 

dashboard

参考文档

https://github.com/kubernetes-sigs/metrics-server

https://landscape.cncf.io/card-mode?category=monitoring&project=graduated,incubating,member,no&grouping=category&sort=stars