本文已发布一年多。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已过时。
使用节点仪表板可视化 Kubelet 性能
自本文发布以来,节点性能仪表板已退役且不再可用。
此退役发生在 2019 年初,是 kubernetes/contrib
仓库废弃的一部分。
在 Kubernetes 1.4 中,我们引入了一个新的节点性能分析工具,称为 节点性能仪表板,用于以更丰富的细节可视化和探索 Kubelet 的行为。这个新特性将使 Kubelet 开发者更容易理解和改进代码性能,并允许集群维护者根据提供的服务水平目标 (SLO) 设置配置。
背景
Kubernetes 集群由主节点和工作节点组成。主节点管理集群状态,工作节点负责运行和管理 Pod 的实际工作。为此,在每个工作节点上,一个名为 Kubelet 的二进制程序会监控 Pod 配置的任何变化,并采取相应的行动以确保容器成功运行。Kubelet 的高性能,例如与新 Pod 配置快速收敛的低延迟以及低资源使用的高效内务管理,对于整个 Kubernetes 集群至关重要。为了衡量这一性能,Kubernetes 使用端到端 (e2e) 测试来持续监控最新版本中加入新特性后的基准变化。
Kubernetes SLO 由以下基准定义 :
* API 响应能力:所有 API 调用中有 99% 在不到 1 秒内返回。
* Pod 启动时间:99% 的 Pod 及其容器(已预拉取镜像)在 5 秒内启动。
在 1.4 版本发布之前,我们仅在集群级别衡量和定义这些指标,这带来了其他因素可能影响结果的风险。除此之外,我们还希望有更多与性能相关的 SLO,例如特定机器类型上允许的最大 Pod 数量,从而最大化集群的利用率。为了正确进行测量,我们希望引入一组仅针对节点性能的孤立测试。此外,我们的目标是从新的测试中收集 Kubelet 更精细的资源使用和操作跟踪数据。
数据收集
自 1.4 版本以来,节点特定的密度和资源使用测试已添加到 e2e-node 测试集中。资源使用由一个独立的 cAdvisor Pod 测量,以实现灵活的监控间隔(与 Kubelet 集成的 cAdvisor 相比)。性能数据,例如延迟和资源使用百分比,记录在持久的测试结果日志中。测试还记录时间序列数据,例如 Pod 的创建时间、运行时间以及实时资源使用情况。Kubelet 操作的跟踪数据记录在其日志中,与测试结果一起存储。
节点性能仪表板
自 Kubernetes 1.4 以来,我们一直在持续构建最新的 Kubelet 代码并运行节点性能测试。数据由我们新的性能仪表板收集,地址为 node-perf-dash.k8s.io。图 1 提供了仪表板的预览。你可以通过选择一个测试来开始探索,既可以使用测试短名称的下拉列表(区域 (a)),也可以逐个选择测试选项(区域 (b))。测试详细信息会显示在区域 (c) 中,其中包含来自 Ginkgo(Kubernetes 使用的 Go 测试框架)的完整测试名称。然后在区域 (d) 中选择节点类型(镜像和机器)。
| | | 图 1. 在节点性能仪表板中选择要显示的测试。 |
“构建版本 (BUILDS)”页面展示了不同构建版本的性能数据(图 2)。图表包括 Pod 启动延迟、Pod 创建吞吐量以及 Kubelet 和运行时(当前为 Docker)的 CPU/内存使用情况。通过这种方式,可以轻松监控随着新特性提交而发生的性能变化。
| | | 图 2. 不同构建版本的性能数据。 |
比较不同的节点配置
比较不同配置之间的性能总是很有趣的,例如比较不同机器类型、不同 Pod 数量的启动延迟,或者比较承载不同 Pod 数量的资源使用情况。仪表板提供了方便的方式来完成此操作。只需点击测试选择菜单右上角的“比较它 (Compare it)”按钮(图 1 中的区域 (e))。选定的测试将添加到“比较 (COMPARISON)”页面中的比较列表,如图 3 所示。一系列构建版本的数据被聚合成一个单一值,以方便比较,并以柱状图显示。
| | | 图 3. 比较不同的测试配置。 |
时间序列和跟踪:深入性能数据
Pod 启动延迟是 Kubelet 的一个重要指标,尤其是在每个节点创建大量 Pod 时。使用仪表板,你可以看到延迟的变化,例如创建 105 个 Pod 时的情况,如图 4 所示。当你看到高度变化的线条时,你可能会认为方差是由于不同的构建版本造成的。然而,由于这里的这些测试是针对相同的 Kubernetes 代码运行的,我们可以得出结论,方差是由于性能波动引起的。当我们比较构建版本 #162 和 #173 的 99% 延迟时,方差接近 40 秒,这是非常大的。要深入探究波动的原因,我们来看看“时间序列 (TIME SERIES)”页面。
| | | 图 4. 创建 105 个 Pod 时的 Pod 启动延迟。 |
具体查看构建版本 #162,我们可以看到 Pod 创建延迟图表中绘制的跟踪数据(图 5)。每条曲线是一个累积直方图,表示已到达特定跟踪探针的 Pod 操作数量。跟踪 Pod 的时间戳可以从性能测试中收集,也可以通过解析 Kubelet 日志获取。目前我们收集以下跟踪数据:
- "create" (测试中): 测试通过 API 客户端创建 Pod;
- "running" (测试中): 测试从 API 服务器监视 Pod 是否正在运行;
- "pod_config_change": Kubelet SyncLoop 检测到 Pod 配置变化;
- "runtime_manager": 运行时管理器开始创建容器;
- "infra_container_start": Pod 的 infra 容器启动;
- "container_start": Pod 的容器启动;
- "pod_running": Pod 正在运行;
- "pod_status_running": 状态管理器更新正在运行的 Pod 的状态;
时间序列图表显示,状态管理器更新 Pod 状态花费了很长时间(“running”的数据未显示,因为它与“pod_status_running”重叠)。我们发现此延迟是由于 Kubelet 对 API 服务器的每秒查询次数 (QPS) 限制(默认为 5)引起的。意识到这一点后,我们在额外的测试中发现,通过增加 QPS 限制,“running”曲线逐渐与“pod_running”收敛,从而显著降低了延迟。因此,之前的 e2e 测试 Pod 启动结果反映了 Kubelet 和上传状态时间的总延迟,Kubelet 的性能因此被低估了。
| | | 图 5. 使用构建版本 #162 数据的时间序列页面。 |
此外,通过比较构建版本 #162(图 5)和构建版本 #173(图 6)的时间序列数据,我们发现 Pod 启动延迟的性能波动实际上发生在更新 Pod 状态期间。构建版本 #162 有几个滞后的“pod_status_running”事件,具有较长的延迟尾部。这为将来的优化提供了有用的思路。
| | | 图 6. 构建版本 #173 的 Pod 启动延迟。 |
将来,我们计划使用 Kubernetes 中具有固定日志格式的事件来更方便地收集跟踪数据。这样就不需要提取现有的日志条目,你可以直接在 Kubelet 内部插入你自己的跟踪探针,并获得每个环节的细分延迟。
在“跟踪 (TRACING)”页面中,你可以查看不同构建版本之间任意两个探针之间的延迟,如图 7 所示。例如,选择“pod_config_change”作为开始探针,选择“pod_status_running”作为结束探针,就可以看到 Kubelet 在持续构建过程中的延迟变化,且不包含状态更新的开销。通过这个特性,开发者能够监控 Kubelet 内部特定代码部分的性能变化。
| | | 图 7. 绘制任意两个探针之间的延迟。 |
未来工作
节点性能仪表板是一个全新的特性。它仍处于积极开发的 Alpha 版本阶段。我们将持续优化数据收集和可视化,为开发者和集群维护者提供更多测试、指标和工具。
请加入我们的社区,帮助我们构建 Kubernetes 的未来!如果你对节点或性能测试特别感兴趣,可以通过在我们的 Slack 频道与我们聊天或参加我们每周二太平洋时间上午 10 点在此 SIG-Node Hangout 举行的会议来参与。
- 下载 Kubernetes
- 在 GitHub 上参与 Kubernetes 项目
- 在 Stack Overflow 上提问(或回答问题)
- 在 Slack 上与社区联系
- 在 Twitter 上关注我们 @Kubernetesio 获取最新更新