如何监控Kubernetes API服务器

【编者的话】本文介绍讨论了Kubernetes API服务器监控的重要性和相关方法

在生产环境中运行Kubernetes时,学习如何监控Kubernetes API服务器是至关重要的。监视kube-apiserver能使您检测和排除延迟、错误,并验证服务是否按预期执行。继续阅读可以了解如何从kube-apiserver收集最重要的指标,并用它们来监视该服务。

Kubernetes API服务器是Kubernetes控制面板的基础组件。集群中运行的所有服务都使用这个接口进行通信。整个用户交互也通过API处理:kubectl是一个向API发送请求的包装工具。kubectl使用HTTP连接API服务器,而其余的控制面板组件使用gRPC通信。我们应该准备好监控这两个渠道。

与其他微服务一样,我们将采用 黄金指标 方法来监视Kubernetes API服务器的健康状况和性能:

  • 延迟
  • 通讯量
  • 错误
  • 饱和度

但在深入研究每个指标的含义之前,让我们先看看如何获取这些指标。

获取用于监视kube-apiserver指标

API服务器已经被测量过,默认情况下它展示在 Prometheus指标 中,提供诸如延迟、请求、错误和etcd缓存状态等监控指标。这些信息节点可以轻松地获取到,从而获得有用的信息,而不需要额外的脚本或导出程序。

API服务器需要身份验证才能向 /metrics 节点发出请求,因此您需要为此获得具有特权的凭据。如果您在集群中运行Prometheus,我们可以使用绑定到 ClusterRole 的服务帐户进行身份验证,允许GET请求查询 /metrics 节点。

这可以使用Prometheus向 ClusterRole 添加一条规则来实现:

通过这种方式,我们可以使用服务帐户中的不记名的令牌访问 /metrics 节点,该令牌位于 /var/run/secrets/kubernet.io/serviceaccount 中的pod中。

我们可以在Prometheus pod中执行这个shell命令来测试身份验证:

#curl  https://kubernetes.default.svc/metrics -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"

--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

它将返回一长串Prometheus 指标(这里有截断):

# TYPE APIServiceOpenAPIAggregationControllerQueue1_adds counter 

APIServiceOpenAPIAggregationControllerQueue1_adds 108089
# HELP APIServiceOpenAPIAggregationControllerQueue1_depth Current depth of workqueue:APIServiceOpenAPIAggregationControllerQueue1

TYPE APIServiceOpenAPIAggregationControllerQueue1_depth gauge

APIServiceOpenAPIAggregationControllerQueue1_depth 0

# TYPE APIServiceOpenAPIAggregationControllerQueue1_queue_latency summary

APIServiceOpenAPIAggregationControllerQueue1_queue_latency{quantile="0.5"} 15

...

通过添加一个job到您的targets,配置Prometheus 就可以抓取Kubernetes API服务器节点信息:

监视Kubernetes API服务器:要找什么?

我们可以使用 黄金指标 来监视Kubernetes API服务器。Golden Signals是一种技术,用于通过一些指标来监视服务,可以洞察服务如何为消费者执行(这里是kubectl用户和内部集群组件)。这些指标是延迟、通信量、错误和饱和度(服务器使用当前资源时达到最大容量的繁忙程度)。

免责声明:不同Kubernetes版本的API服务器指标可能不同。这里我们使用的是Kubernetes

1.15。您可以在 Kubernetes repo (1.15.3版本的链接)中查看您的版本的可用指标。

延迟:可以从apiserver_request_duration_seconds直方图中提取延迟:

# TYPE apiserver_request_latencies histogram apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="125000"} 2 apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="250000"} 2 apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="500000"} 2 apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="1e+06"} 2 apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="2e+06"} 2 apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="4e+06"} 2 apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="8e+06"} 2 apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="+Inf"} 2 apiserver_request_duration_seconds_sum{resource="adapters",scope="cluster",subresource="",verb="LIST"} 50270 apiserver_request_duration_seconds_count{resource="adapters",scope="cluster",subresource="",verb="LIST"} 2

使用百分位数来理解延迟传播是个好主意:

histogram_quantile(0.99, sum(rate(apiserver_request_latencies_count{job="kubernetes-apiservers"}[5m])) by (verb, le))

请求率:可以使用 apiserver_request_total 指标来监视对服务的请求、来自何处、到哪个服务、哪个操作以及是否成功:

# TYPE apiserver_request_count counter apiserver_request_total{client="Go-http-client/1.1",code="0",contentType="",resource="pods",scope="namespace",subresource="portforward",verb="CONNECT"} 4 apiserver_request_total{client="Go-http-client/2.0",code="200",contentType="application/json",resource="alertmanagers",scope="cluster",subresource="",verb="LIST"} 1 apiserver_request_total{client="Go-http-client/2.0",code="200",contentType="application/json",resource="alertmanagers",scope="cluster",subresource="",verb="WATCH"} 72082 apiserver_request_total{client="Go-http-client/2.0",code="200",contentType="appli

例如,你可以像这样获得所有成功的请求:

sum(rate(apiserver_request_total{job="kubernetes-apiservers",code=~"2.."}[5m]))

错误:你可以使用相同的查询请求率,并过滤400和500错误代码:

sum(rate(apiserver_request_total{job="kubernetes-apiservers",code=~"[45].."}[5m]))

饱和度:我们可以通过CPU、内存和网络I/O等系统资源消耗指标来监测饱和度。

除了API服务器相关指标外,我们还可以获得其他相关指标。API服务器提供:

  • controller-manager:
    工作队列添加率 :我们通过控制器调度新操作执行的速度。这些操作可以包括集群中任何资源的添加、删除和修改(工作负载、配置映射表、服务……)。
    工作队列延迟 :控制器-管理器执行这些操作有多快?
    工作队列深度 :有多少动作等待执行?
  • etcd:
    etcd缓存项 :缓存了多少查询结果?
    etcd缓存命中率/失误率 :缓存有用吗?
    etcd缓存持续时间 :缓存结果存储多长时间?

问题示例

检测到对API的请求的延迟有增加

这通常是API服务器过载的标志。可能您的集群有很多负载,需要扩展API服务器。

您可以根据请求类型、资源或谓词来划分指标。通过这种方式,您可以检测问题在哪里。也许你在etcd的读写上有问题,需要解决。

检测到工作队列的深度和延迟的增加

在调度操作时遇到问题。您应该检查调度程序是否工作。可能您的一些节点超载了,需要扩展集群。可能有一个节点有问题,需要替换它。

在Sysdig Monitor中监视Kubernetes API服务器指标

如果你想使用Sysdig monitor来监控Kubernetes API服务器,你只需要向 Sysdig代理yaml配置文件 中添加几个部分:

metrics_filter 部分,您可以确保在达到指标限制时不会丢弃这些指标。你可以添加API服务器提供的任何不在这个列表中的其他指标,如下所示:

metrics_filter:

- include: "apiserver_request_total"

...

- include: "go_goroutines"

然后,配置Sysdig代理将如何收集指标,搜索带有 kube-apiserver 标签的Kubernetes pod,并通过端口8080在本地主机中收集数据。由于Sysdig代理能够切换网络上下文并像在本地主机上那样连接到pod,所以我们不需要使用https。还必须指定代理使用的身份验证令牌来访问metrics 节点:

prometheus:

enabled: true

...

process_filter:

  - include:

      kubernetes.pod.label.k8s-app: kube-apiserver

      port: 8080

      conf:

        tags:

          kubernetes.component.name: kube-apiserver

        host: 127.0.0.1

        port: 8080

        use_https: false

        auth_token_path: "/var/run/secrets/kubernetes.io/serviceaccount/token"

然后可以使用这些指标构建自定义仪表面板。我们有一些预置的仪表面板,我们可以与您分享,如果你有兴趣。

结论

监视Kubernetes API服务器是基础,因为它是集群操作中的关键部分。请记住,集群组件之间的所有通信都是通过 kube-apiserver 完成的。

检测API服务器中的问题可能是修复Kubernetes集群中的问题的关键因素。您应该了解控制面板中服务组件正在发生的事情,并学会如何利用这一点当问题出现时,而问题肯定会出现的。

对所有Kubernetes组件进行完善的监视与监视在集群中运行的工作负载和应用程序同样重要。不要忘记监控你的控制面板!

原文链接:How to Monitor Kubernetes API Server(译者:姜俊厚)