k8s在1.16 Alpha (v1.16) 版本提供了Topology Manager(/kubernetes/enhancements/blob/master/keps/sig-node/),网上对这个模块的分析不是很多,基本上没有。之前对numa-aware resource allocation研究比较多,结合k8s官方文档,在这里也学习一下k8s是怎么处理numa问题的。分析错误或者不到位,还请各位大佬指教。所有的代码都在pkg/kubelet/cm/topologymanager目录下面。
Topology Manager模块诞生的背景:随着单个服务器节点内的处理器数量和硬件加速器越来越多,怎样优化延迟敏感型的高性能并行计算应用的性能成为了一个巨大的挑战。在K8S中,topologymanager就是这样一个组件用来优化容器中应用在高性能服务器上的性能。topology manager是kubelet的一个组件,为其他的组件充当着一个底层拓扑信息的来源,以便在资源分配的时候实现拓扑结构上的对齐。注意topology manager不是单独起作用的,它和CPU manager,device manager共同为pod分配资源,优化资源访问。
Topology Manager模块的工作原理:
kubernets官方文档里面对Topology Manager的解释是:topology manager从Hint Providers中以bitmask的形式接受NUMA拓扑信息(Topology Hint),包括当前可用的NUMA节点和倾向的资源分配指示。Topology manager策略对提供的hint进行一系列操作以后将所有的hint决定汇聚起来,得出一个最佳的hint(bestHint)。通过配置的策略(policy),主机节点可以选择接受或者拒绝pod。
要清晰的理解这段解释需要回答以下几个问题:(由于NUMA是常见的计算机系统架构,这里默认读者具有一定的体系架构知识,就不做展开了)
- 什么是Hint Provider和Topology Hint?
- topologymanager有哪些策略,是怎样对这些hint进行操作后得到最佳的分配结果的呢?
- 分配结果是怎样最后被kubelet所执行的呢?
第一个问题其实是我们搞懂topology manager的基本。
这里面涉及到一系列的结构体和接口。首先HintProvider的定义是:HintProvider为一些遵循NUMA本地性同时期望得到全局最优资源对齐的组件提供接口。它提供了一个方法
type HintProvider interface {
// GetTopologyHints returns a map of resource names to a list of possible
// concrete resource allocations in terms of NUMA locality hints. Each hint
// is optionally marked "preferred" and indicates the set of NUMA nodes
// involved in the hypothetical allocation. The topology manager calls
// this function for each hint provider, and merges the hints to produce
// a consensus "best" hint. The hint providers may subsequently query the
// topology manager to influence actual resource assignment.
GetTopologyHints(pod , container ) map[string][]TopologyHint
}
这个方法的返回值是资源名到一列关于NUMA本地性的资源分配的映射。通过这个方法可以得到所有pod的container的TopologyHints,topology manager对每一个hintprovide都会调用这个方法,然后得到合并hint信息产生一个一致的最优的hint。
Topology Hint就是hintprovider(CPU manager,Devices manager等)提供的最基本的hint信息,我们先来看一下它的结构体定义:
type TopologyHint struct {
NUMANodeAffinity
// Preferred is set to true when the NUMANodeAffinity encodes a preferred
// allocation for the Contain