kubernetes

Kubernetes 监控介绍

Kubernetes 改变了现代运维团队部署和扩展应用的方式。尽管 Kubernetes 使在生产环境中使用容器变得更加简单,但这并不意味着可以忽略一个强大的监控系统来帮助您了解系统状态的需求。

Kubernetes 监控至关重要,它能帮助您跟踪性能指标、审计部署环境的变更以及检索用于调试应用崩溃的日志。没有监控解决方案的 Kubernetes 故障排除既繁琐又容易出错,问题往往在被注意到之前就已升级。

我们将介绍监控 Kubernetes 集群的基础知识,并解释如何通过识别收集 Kubernetes 指标的关键机会来最大化工作负载的可观测性。这将有助于在系统生命周期的早期检测错误。

监控 Kubernetes 的 5 个理由

生产应用需要监控,以便您检测错误、优化资源使用和管理成本。Kubernetes 也不例外:监控常常是高效集群与利用不足、性能低下的集群之间的区别所在。

Real-time alerts

1. 实时告警和早期错误检测

主动监控 Kubernetes 集群有助于您在错误影响用户之前提早检测到。日志文件、追踪和性能指标提供了集群中正在发生的情况的可观测性,让您提前获知使用量激增和错误率上升的情况。实时告警可以在问题刚开始时就通知您,避免用户首先发现问题而导致的尴尬对话。这缩短了服务恢复时间,从而保护了您的品牌声誉。

Workload management

2. 更好的工作负载管理和优化

全面的监控有助于更好地管理工作负载和更优化地利用您的资源。监控 Kubernetes 集群可以揭示是否存在过多的资源争用,或者应用程序 Pod 在节点之间的分布不均。简单的调度调整,例如设置亲和性和反亲和性,可以显著提升性能和可靠性,但如果没有对实际集群使用情况的深入了解,您将错过这些机会。

Troubleshooting

3. 更轻松的故障排除

监控在您排查问题时提供帮助。访问应用程序和 Kubernetes 组件的日志通常是发现重现步骤并找出根本原因的最佳途径。如果没有监控解决方案,您将不得不推测问题的可能来源,然后通过试错来测试修复方案。这增加了开发人员的工作量,尤其是对不熟悉系统的新人而言。能够更早地查明问题可以最大程度地减少停机时间,并鼓励每个人贡献力量。

Cost visibility

4. 实时成本可视化

Kubernetes 费用冲击是真实存在的。自动扩缩容架构让您能够实时适应不断变化的需求,但这也会导致成本迅速螺旋式上升。监控至关重要,以便您查看当前部署在您的云账户中的节点负载均衡器持久卷的数量。这些对象通常会产生独立的提供商费用。

Insights

5. 强大的洞察力

Kubernetes 监控可以产生独特的洞察力,突显提升服务的机会。除了简单的性能指标,监控还有助于揭示用户如何与您的应用程序交互,从而为未来的产品决策提供信息。来自诸如Ingress Controller等组件的数据将揭示调用最频繁的端点,以及流经您基础设施的数据量。这些信息在寻找需要进一步扩展的功能时提供了出发点,无论是因为用户活跃度高还是由于可发现性差而使用率低。

Kubernetes 监控:关键组件

Kubernetes 集群由许多不同的组件组成,它们协同工作以支持容器化工作负载。在日常管理中,您会遇到其中的一些组件,但另一些则在幕后协调操作。

基本的 Kubernetes 架构是应用程序作为容器在 Pod 中运行。Pod 分布在多个 节点 上,这些节点代表集群中的物理机。节点由 控制平面 协调,控制平面包括用于与集群交互的API Server和多个ControllerController 监视集群中的变化,并采取行动达到新的期望状态,例如在添加 Pod 对象时启动容器。

Kubernetes 集群的复杂性意味着始终需要采用多方面的方法进行监控。下图中的每个项目都应该被观测,以便您跟踪整个基础设施的性能

Diagram of observability layers to monitor in Kubernetes

接下来,我们将回顾其中一些组件以及如何从中收集指标。

性能指标

性能监控可以帮助您调查集群容量问题并确定何时需要添加更多资源。收集到的指标能让您发现资源消耗趋势,从而帮助您在用户察觉到慢速之前进行应对。

节点资源利用率指标

节点资源利用率指标,例如 CPU 和内存消耗,可以通过多种机制获取。最常见的方法是在每个节点上运行一个代理,例如Prometheus Node Exporter。指标代理会定期抓取节点的当前指标并将数据发送到您的可观测性平台。

或者,当您的集群中安装了Metrics API时,Kubernetes 可以自己收集这些数据。使用 Metrics API,您可以在终端中使用kubectl top 命令访问节点指标。这提供了一种便捷的资源监控方式,无需任何外部依赖。

主要云服务商提供的 Kubernetes 集群通常也有自己的监控仪表盘。您可以登录您的云账户查看关键指标的基本图表,而无需自行设置任何东西。这提供了一种方便的快速入门选项,但未必能显示您需要了解的所有信息。

定期监控这些基本的硬件利用率指标至关重要,以便您预测未来的使用情况并提前增加容量以应对需求。持续较高的 CPU 和内存消耗会降低您服务的性能余量。如果发生使用量激增,这可能导致宕机和不稳定。

对象容量和健康状况指标

kube-state-metrics (KSM) 服务监听 Kubernetes API Server 事件,并暴露 Prometheus 指标,记录集群中对象的状态。一千多个不同的指标提供了单个容器、Pod、Deployment 和其他资源的状态、容量和健康状况。

您可以使用这种插桩来深入探究集群中的对象。例如,Pod Metrics API提供了关于每个 Pod 的 40 多个独立数据点,包括 Pod 的状态、自上次状态转换以来经过的时间、发生的重启次数以及适用于它的资源限制。所有其他 Kubernetes 内置对象类型都有独立的 API 可用。

监控这些指标可以向您发出集群和应用程序问题的警报。重启次数高的 Pod 可能表明集群中存在资源争用,或者您的应用程序中存在导致其崩溃的 Bug。KSM 暴露的指标是原始数据,由 Kubernetes 控制平面收集,您可以直接处理和分析它们。

存储健康状况

kube-state-metrics (KSM) 也可用于监控存储健康状况。它包含暴露StorageClassPersistentVolumePersistentVolumeClaim 指标的 API,例如卷的容量、当前是否可用以及每个 Claim 请求的空间量。

另一种检查存储健康状况的方法是使用卷健康监控系统。这个 Alpha 功能内置于 Kubernetes 中,提供描述持久卷整体健康状况的指标。它包括一个专用的 Controller,用于监控可能表明存储存在问题的异常卷条件。当访问卷的 Pod 被调度到失败的节点时,该 Controller 也会在您的卷上设置事件。这让您可以检查已声明卷的 Pod 是否实际运行。

Kubelet 指标

运行在 Kubernetes 节点上的 Kubelet 进程提供了可以使用 Prometheus 抓取的详细指标。这些指标通过 10255 端口的 /metrics 端点访问。

首先获取您集群内节点的 IP 地址

$ kubectl get nodes -o wide
NAME   	STATUS   ROLES              	AGE   VERSION   INTERNAL-IP	EXTERNAL-IP   OS-IMAGE         	KERNEL-VERSION  	CONTAINER-RUNTIME
minikube   Ready	control-plane,master   74d   v1.23.3   192.168.49.2   <none>    	Ubuntu 20.04.2 LTS   5.4.0-122-generic   docker://20.10.12

该节点的 IP 地址是 192.168.49.2。现在您可以通过访问 10255 端口查询其指标数据

curl http://192.168.49.2:10255/metrics
# HELP apiserver_audit_event_total [ALPHA] Counter of audit events generated and sent to the audit backend.
# TYPE apiserver_audit_event_total counter
apiserver_audit_event_total 0
# HELP apiserver_audit_requests_rejected_total [ALPHA] Counter of apiserver requests rejected due to an error in audit logging backend.
# TYPE apiserver_audit_requests_rejected_total counter
apiserver_audit_requests_rejected_total 0
# HELP apiserver_client_certificate_expiration_seconds [ALPHA] Distribution of the remaining lifetime on the certificate used to authenticate a request.
# TYPE apiserver_client_certificate_expiration_seconds histogram
apiserver_client_certificate_expiration_seconds_bucket{le="0"} 0
apiserver_client_certificate_expiration_seconds_bucket{le="1800"} 0
apiserver_client_certificate_expiration_seconds_bucket{le="3600"} 0
...

Kubelet 指标端点可用于查询您集群内节点的性能。这些数据暴露了与 Kubelet 和 Kubernetes 控制平面交互相关的统计信息,例如工作队列中的任务数量以及完成 API 请求所需的时间。

Kubelet 还在 /metrics/cadvisor 端点提供cAdvisor 指标。cAdvisor (Container Advisor) 是一个用于分析容器资源使用情况和性能特征的工具。

curl http://192.168.49.2:10255/metrics/cadvisor
# HELP cadvisor_version_info A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.
# TYPE cadvisor_version_info gauge
cadvisor_version_info{cadvisorRevision="",cadvisorVersion="",dockerVersion="",kernelVersion="5.4.0-122-generic",osVersion="Ubuntu 20.04.2 LTS"} 1
# HELP container_blkio_device_usage_total Blkio Device bytes usage
# TYPE container_blkio_device_usage_total counter
container_blkio_device_usage_total{container="",device="/dev/nvme0n1",id="/",image="",major="259",minor="0",name="",namespace="",operation="Async",pod=""} 0 1660656772812
container_blkio_device_usage_total{container="",device="/dev/nvme0n1",id="/",image="",major="259",minor="0",name="",namespace="",operation="Discard",pod=""} 0 1660656772812
container_blkio_device_usage_total{container="",device="/dev/nvme0n1",id="/",image="",major="259",minor="0",name="",namespace="",operation="Read",pod=""} 778240 1660656772812
...

这些指标有助于分析容器级别的 CPU、内存、磁盘和网络利用率。一旦您使用上面讨论的集群级别指标识别出一个繁忙的节点,您就可以使用该节点的 cAdvisor 输出找到使用过多资源并与其他对象产生冲突的容器。高利用率可能是由于用户活动增加,这表明您需要通过增加 Pod 来扩展服务,或者容器内部缺少优化导致负载升高。

Kubernetes 日志

除了性能指标和资源利用率,捕获和保留 Kubernetes 日志也很重要,以便您将来查阅。多个 Kubernetes 组件将事件和错误直接写入宿主机文件系统上的日志文件。以下是一些常见路径供您检查。

在 Kubernetes 控制平面节点上,查看以下内容

  • /var/log/kube-apiserver.log: 此日志包含 Kubernetes API Server 中发生的事件。
  • /var/log/kube-scheduler.log: 调度决策记录,当 Kubernetes 决定将 Pod 放置到哪个节点时生成。
  • /var/log/kube-controller-manager.log: 来自 Kubernetes Controller Manager 的日志,它负责运行所有内置的 Controller,用于监控集群中的活动。

在各个工作节点上,查看以下内容

  • /var/log/kubelet.log: Kubelet 进程负责维护节点与 Kubernetes 控制平面服务器之间的通信。当您排除节点为何变为不可用的故障时,此日志文件应是您的起点。
  • /var/log/kube-proxy.log: 这里存储着 kube-proxy 进程的日志。kube-proxy 进程负责通过服务将流量路由到节点上的 Pod。

您可以使用诸如 PromtailGrafana Agent 之类的数据收集器来访问这些日志文件,将新日志行直接流式传输到您的监控平台。在节点上安装其中一个代理将自动化日志收集。这使您能够与性能指标一起查看日志,并无需手动连接到节点并使用 Unix 工具(如 cattail)访问其日志。

Promtail 也适用于您的应用程序写入的容器级别日志。Kubernetes 从您的进程写入其标准输出和错误流的数据创建容器日志。您应该配置您的应用程序来支持这种机制,因为直接写入容器文件系统的日志在容器重启时会被销毁。这会使调查错误和崩溃变得更加困难,因为您将无法访问日志中的错误消息和堆栈跟踪。

使用代理收集容器日志并将其发送到监控平台,可以使日志内容更容易访问。您将能够搜索和过滤日志行,而不是依赖于 kubectl logs 命令提供的简单按时间顺序输出。大多数日志聚合解决方案,例如 Grafana Loki,也支持长期日志归档,使您可以在容器重启或替换后重新查看问题。

追踪

追踪是一种日志记录形式,它记录程序执行期间发生的事件的非常精确的细节。虽然追踪和日志之间的区别有时模糊,但原始追踪通常冗长、嘈杂,旨在为开发者提供最大的保真度。追踪通常包含导致某个事件的代码堆栈层序列。

相比之下,日志消息通常包含更多面向人类的信息。它们记录了某个事件的发生,但没有解释导致该事件的原因。日志消息可能是“处理支付失败”。相应的追踪应该显示代码的执行步骤,从应用程序的入口点到尝试调用外部支付提供商并获得错误响应。

追踪中的单个操作被称为 span。在上面的例子中,追踪是整个操作,从用户发起支付到确定结果。在追踪中,可能包含以下 span:

  • 验证用户输入,例如银行卡详细信息和优惠券代码。
  • 检索用户购物篮的内容。
  • 将数据发送到后端支付提供商。
  • 存储交易结果。
  • 发送订单确认邮件。

Span 通常与它们自己的元数据相关联,例如它们的直接父级、持续时间以及执行的操作。这种区分让您可以深入探究单个事件的特定部分,缩小问题搜索范围。

在调试用户报告的问题时,审查请求所经过的代码路径是无价的。并非所有问题都能在开发环境中轻松重现;追踪可以让您准确地看到用户会话期间发生了什么,从而使问题解决更高效。如果没有追踪,您将不得不要求用户确认 Bug 发生前他们采取的确切步骤。这并非总是可行,也未必能成功重现问题。追踪提供了您所需的所有数据,让您可以直接进行修复。

Kubernetes 也内置了追踪功能。一些系统组件暴露追踪,以便您更好地理解集群的内部操作并衡量性能。集成式集群级别追踪在诊断影响所有应用程序的通用问题时很有用,但在您精确分析代码执行时,用户部署的应用级别追踪更有效。

Kubernetes 事件

Kubernetes 维护着集群中发生的所有事件的全面历史记录。您可以使用 kubectl 在终端中查看事件

$ kubectl get events
LAST SEEN 	TYPE  	REASON  	OBJECT       	MESSAGE
1m    		   Normal	Created 	pod/demo-pod 	Created container demo-pod
1m        	Normal	Started 	pod/demo-pod 	Started container demo-pod

每个事件都包含其引用的对象名称、发生的动作、对象状态(如“Normal”或“Failed”)以及简要描述事件的消息。这提供了集群活动的全面历史记录,包括由 Kubernetes 控制平面生成的事件,以及响应用户操作产生的事件。

您可以使用 --field-selector 标志进行过滤,获取与特定对象关联的事件。此示例通过匹配事件对象上的 involvedObject.kindinvolvedObject.name 字段,检索 demo-pod Pod 的事件

$ kubectl get events \
    --field-selector involvedObject.kind=Pod \
    --field-selector involvedObject.name=demo-pod
LAST SEEN 	TYPE  	REASON  	OBJECT       	MESSAGE
1m    		   Normal	Created 	pod/demo-pod 	Created container demo-pod
1m        	Normal	Started 	pod/demo-pod 	Started container demo-pod

您可以通过将 involvedObject.kind 字段替换为您要查找的对象类型名称(例如 DeploymentReplicaSetJob)来修改此示例,以支持任何其他对象。

事件在理解导致特定问题的行动序列方面是无价的。几乎所有与对象相关的行动都会显示在列表中,从成功创建容器到失败的作业、镜像拉取错误以及低内存状况。

Kubernetes 将事件视为瞬时记录,它们在发生后很快会自动清除。在大多数情况下,事件仅在一小时后就被删除。您应该使用基于代理的数据收集器将事件流式传输到可观测性解决方案(例如 Grafana)。这将使您能够在事件发生很久之后检索、搜索和归档事件,为未来的故障排除提供另一个参考点。

容器化应用指标

重要的是与您的集群健康状况监控您的容器化工作负载。创建自己的应用内指标 API,导出兼容 Prometheus 的数据,将使您能够使用您的可观测性解决方案抓取性能统计信息。

Prometheus 为 Go、Java/Scala、Python、Ruby 和 Rust 提供了官方客户端库。大多数其他流行语言也有社区支持的选项。这些库让您可以在应用程序实例上使用 HTTP 端点定义和暴露自定义应用程序指标。

例如,您可能想要跟踪执行特定业务功能所需的时间,例如处理登录或完成支付交易。Prometheus 简化了这些持续时间的测量,并将其暴露为您可以抓取的指标,从而最大程度地减少您需要编写的代码量。

花时间对您的工作负载进行插桩可以增强可观测性,让您能够在应用程序级别分析性能。最终,对用户而言最重要的是处理应用程序功能所需的时间,而不是绝对的 CPU 消耗或集群利用率。跟踪业务特定度量指标的趋势可以发现改善用户体验的机会,并让您在性能问题升级到节点级别或集群级别之前发现它们。

总结

与传统的部署解决方案相比,Kubernetes 包含更多活动部件,需要一种全新的监控和可观测性方法。除了基本的日志记录、应用健康状况和资源利用率指标外,您还需要评估 Kubernetes 控制平面内各个组件的性能。

在本文中,我们探讨了创建全面的 Kubernetes 监控解决方案时必须考虑的组件。专注于上面列出的领域将提供洞察力,揭示您的集群及其工作负载的内部运行情况。您将能够早期识别正在出现的问题,以及改进和增强集群使用的新机会。

在 Grafana Cloud 中开始 Kubernetes 监控

无论您是推出新变更的应用程序开发人员,还是寻求更好方法来排查基础设施事件的 SRE,亦或是维护运行集群的裸金属服务器的 DevOps 管理员,Grafana Labs 都能提供帮助。选择Kubernetes 监控,这是适用于各种 Kubernetes 用途的完整解决方案,提供开箱即用的 Kubernetes 基础设施指标、日志和 Kubernetes 事件访问,以及预置的仪表盘和告警。包括慷慨的永久免费套餐用户在内,所有 Grafana Cloud 用户均可使用 Kubernetes 监控。

准备好开箱即用的 Kubernetes 监控了吗?