首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubelet从人门到放弃:拓扑管理(下)

Kubelet从人门到放弃:拓扑管理(下)

作者头像
zouyee
发布2021-03-06 14:01:09
6860
发布2021-03-06 14:01:09
举报
文章被收录于专栏:Kubernetes GOKubernetes GO

友情提示:全文4090多文字,预计阅读时间6分钟

摘要

《Kubelet从入门到放弃系列》将对Kubelet组件由Linux基础知识到源码进行深入梳理。上一篇zouyee带各位看了Kubelet从入门到放弃:拓扑管理(上),其中介绍了拓扑管理,本文将对拓扑管理进行源码深入剖析。

一、源码分析

注:代码逻辑对应版本1.21.0-beta.0

对于拓扑管理器代码分析,我们从两个方面进行:

1)Kubelet初始化时,涉及拓扑管理的相关操作

2)Kubelet运行时,涉及拓扑管理的相关操作,深入分析拓扑管理结构逻辑

1.1 Kubelet初始化

关于Kubelet初始化,我们将以CPU manager结合拓扑管理器的启动图(当前为CPU manager、memory manager、device manager构成资源分配管理器,其属于Container Manager模块的子系统)进行说明。

对于上图的内容,zouyee总结流程如下:

1、在命令行启动部分,Kubelet中调用NewContainerManager构建ContainerManager

2、NewContainerManager函数调用topologymanager.NewManager构建拓扑管理器,否则未启用拓扑管理器,则构建fakeManager

3、NewContainerManager函数分别调用cpu、memory及device提供的NewManager构建相关管理器

4、若拓扑管理特性开启,则拓扑管理器使用AddHintPriovider方法将CPU、memory及device管理器加入管理,上述三种资源分配器,需要实现HintPriovider接口

5、回到命令行启动部分,调用NewMainKubelet(),构建Kubelet结构体

6、构建Kubelet结构体时,将CPU、memory管理器(没有device)跟拓扑管理器封装为InternalContainerLifecycle接口,其实现Pod相关的生命周期资源管理操作,涉及资源分配回收相关的是PreStartContainer、PostStopContainer方法,可参看具体实现。

7、构建Kubelet结构体时,调用AddPodmitHandler将GetAllocateResourcesPodAdmitHandler方法加入到Pod准入插件中,在Pod创建时,资源预分配检查,其中GetAllocateResourcesPodAdmitHandler根据是否开启拓扑管理,决定是返回拓扑管理Admit接口,还是使用cpu、memory及device构成资源分配器,实现Admit接口。

8、构建Kubelet结构体后,调用ContainerManager的Start方法,ContainerManager在Start方法中调用CPU、memory及device管理器的Start方法,其做一些处理工作并孵化一个goroutine,执行reconcileState()

注:关于上述启动流程的代码解释,可以返回Kubelet从入门到放弃:识透CPU管理

1.2 Kubelet运行时

Kubelet运行时,涉及到拓扑管理、资源分配的就是对于Pod处理流程,zouyee总结如下:

1、PodConfig从apiserver、file及http三处接受Pod,调用Updates()返回channel,内容为Pod列表及类型。

2、Kubelet调用Run方法,处理PodConfig的Updates()返回的channel

3、在Run方法内部,Kubelet调用syncLoop,而在syncLoop内部,调用syncLoopIteration

4、在syncLoopIteration中,当configCh(即PodConfig调用的Updates())返回的pod类型为ADD时,执行handler.HandlePodAdditions,在HandlePodAdditions中,处理流程如下:当pod状态为非Termination时,Kubelet遍历admitHandlers,调用Admit方法。

:syncLoopIteration中除了configCh,还有其他channel(plegCh、syncCh、housekeepingCh及livenessManager)其中plegCh、syncCh及livenessManager三类channel中调用的HandlePodAddtion、HandlePodReconcile、HandlePodSyncs及HandlePodUpdates都涉及dispatch方法调用,还记得Kubelet流程中,将CPU管理器、内存管理器跟拓扑管理器封装为InternalContainerLifecycle接口,其实现Pod相关的生命周期资源管理操作,涉及CPU、内存相关的是PreStartContainer方法,其调用AddContainer方法,后续统一介绍。

5、在介绍Kubelet启动时,调用AddPodmitHandler将GetAllocateResourcesPodAdmitHandler方法加入到admitHandlers中,因此在调用Admit方法的操作,涉及到拓扑管理的也就是GetAllocateResourcesPodAdmitHandler,那么接下来就接受一下该方法。

6、在Kublet的GetAllocateResourcesPodAdmitHandler方法的处理逻辑为:当启用拓扑特性时,资源分配由拓扑管理器统一接管,如果未启用,则为cpu管理器、内存管理器及设备管理器分别管理,本文只介绍启用拓扑管理器的情况。

7、启用拓扑管理器后,Kublet的GetAllocateResourcesPodAdmitHandler返回的Admit接口类型,由拓扑管理器实现,后续统一介绍。

上述流程即为Pod大致的处理流程,下面介绍拓扑结构初始化、AddContainer及Admit方法。

1)拓扑结构初始化

拓扑结构初始化函数为

pkg/kubelet/cm/topologymanager/topology_manager.go:119
// NewManager creates a new TopologyManager based on provided policy and scope
func NewManager(topology []cadvisorapi.Node, topologyPolicyName string, topologyScopeName string) (Manager, error) {
   // a. 根据cadvisor数据初始化numa信息
   var numaNodes []int
   for _, node := range topology {
      numaNodes = append(numaNodes, node.Id)
   }
   // b. 判断策略为非none时,numa节点数量是否超过8,若超过,则返回错误
   if topologyPolicyName != PolicyNone && len(numaNodes) > maxAllowableNUMANodes {
      return nil, fmt.Errorf("unsupported on machines with more than %v NUMA Nodes", maxAllowableNUMANodes)
   }
   // c. 根据传入policy名称,进行初始化policy
   var policy Policy
   switch topologyPolicyName {

   case PolicyNone:
      policy = NewNonePolicy()

   case PolicyBestEffort:
      policy = NewBestEffortPolicy(numaNodes)

   case PolicyRestricted:
      policy = NewRestrictedPolicy(numaNodes)

   case PolicySingleNumaNode:
      policy = NewSingleNumaNodePolicy(numaNodes)

   default:
      return nil, fmt.Errorf("unknown policy: \"%s\"", topologyPolicyName)
   }
   // d. 根据传入scope名称,以初始化policy结构体初始化scope
   var scope Scope
   switch topologyScopeName {

   case containerTopologyScope:
      scope = NewContainerScope(policy)

   case podTopologyScope:
      scope = NewPodScope(policy)

   default:
      return nil, fmt.Errorf("unknown scope: \"%s\"", topologyScopeName)
   }
   // e. 封装scope,返回manager结构体
   manager := &manager{
      scope: scope,
   }

a. 根据cadvisor数据初始化numa信息

b. 判断策略为非none时,numa节点数量是否超过8,若超过,则返回错误

c. 根据传入policy名称,进行初始化policy

d. 根据传入scope名称,以初始化policy结构体初始化scope

e. 封装scope,返回manager结构体

2) AddContainer

AddContainer实际调用scope的方法位于

pkg/kubelet/cm/topologymanager/scope.go:97
func (s *scope) AddContainer(pod *v1.Pod, containerID string) error {
   s.mutex.Lock()
   defer s.mutex.Unlock()

   s.podMap[containerID] = string(pod.UID)
   return nil
}

该处只做简单字典加入操作。

3)Admit

Admit函数调用位于

pkg/kubelet/cm/topologymanager/topology_manager.go:186

其根据scope类型分别调用不同的实现:

a、container

代码实现位于

pkg/kubelet/cm/topologymanager/scope_container.go:45
func (s *containerScope) Admit(pod *v1.Pod) lifecycle.PodAdmitResult {
   // Exception - Policy : none
   // 1. 策略为none,则跳过
   if s.policy.Name() == PolicyNone {
      return s.admitPolicyNone(pod)
   }
   // 2. 遍历init及常规容器
   for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) {
       // 2.1 计算亲和性,判断是否准入
      bestHint, admit := s.calculateAffinity(pod, &container)
      if !admit {
         return topologyAffinityError()
      }
      // 2.2 记录分配结果
      s.setTopologyHints(string(pod.UID), container.Name, bestHint)
      // 2.3 调用hint provider分配资源
      err := s.allocateAlignedResources(pod, &container)
      if err != nil {
         return unexpectedAdmissionError(err)
      }
   }
   return admitPod()
}

b、pod

代码位于

pkg/kubelet/cm/topologymanager/scope_pod.go:45
func (s *podScope) Admit(pod *v1.Pod) lifecycle.PodAdmitResult {
   // Exception - Policy : none
   // 1. 策略为none,则跳过
   if s.policy.Name() == PolicyNone {
      return s.admitPolicyNone(pod)
   }
  // 2 计算亲和性,判断是否准入
   bestHint, admit := s.calculateAffinity(pod)
   if !admit {
      return topologyAffinityError()
   }
    // 3. 遍历init及常规容器
   for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) {
      // 3.1 记录分配结果
      s.setTopologyHints(string(pod.UID), container.Name, bestHint)
      // 3.2 调用hint provider分配资源
      err := s.allocateAlignedResources(pod, &container)
      if err != nil {
         return unexpectedAdmissionError(err)
      }
   }
   return admitPod()
}

具体说明见代码注释,需要说明的是scope为container与pod的区别主要在计算亲和性,判断是否准入的阶段,同样也反应了scope与container的粒度,后续重点介绍calculateAffinity方法。

下面zouyee带各位总结一下拓扑管理器的Admit逻辑。

拓扑管理器为组件定义Hint Providers的接口,以发送和接收拓扑信息,CPU、memory及device都实现该接口,拓扑管理器调用AddHintPriovider加入到管理器,其中拓扑信息表示可用的 NUMA 节点和首选分配指示的位掩码。拓扑管理器策略对所提供的hint执行一组操作,并根据策略获取最优解;如果存储了与预期不符的hint,则该建议的优选字段设置为 false。所选建议可用来决定节点接受或拒绝 Pod 。之后,hint结果存储在拓扑管理器中,供Hint Providers进行资源分配决策时使用。

对于上述两种作用域(container及pod)的calculateAffinity通用流程,汇总如下(忽略计算亲和性的差异):

对于上图的内容,zouyee总结流程如下:

1. 遍历容器中的所有容器(scope为pod跟container的差别,上面已经说明)

2. 对于每个容器,针对容器请求的每种拓扑感知资源类型(例如gpu-vendor.com/gpu、nic-vendor.com/nic、cpu等),从一组HintProviders中获取TopologyHints。

3. 使用选定的策略,合并收集到的TopologyHints以找到最佳hint,该hint可以在所有资源类型之间对齐资源分配。

4. 循环返回hintHintProviders集合,指示他们使用合并的hint来分配他们管理的资源。

5. 如果上述步骤中的任一个失败或根据所选策略无法满足对齐要求,Kubelet将不会准入该pod。

下面zouyee根据下图依次介绍拓扑管理器涉及的结构体。

a. TopologyHints

拓扑hint对一组约束进行编码,记录可以满足给定的资源请求。目前,我们唯一考虑的约束是NUMA对齐。定义如下:

type TopologyHint struct {
    NUMANodeAffinity bitmask.BitMask
    Preferred bool
}

NUMANodeAffinity字段表示可以满足资源请求的NUMA节点个数的位掩码,是bitmask类型。例如,在2个NUMA节点的系统上,可能的掩码包括:

{00}, {01}, {10}, {11}

Preferred是用来管理NUMANodeAffinity是否生效的布尔类型,如果Preferred为true那么当前的亲和度有效,如果为false那么当前的亲和度无效。使用best-effort策略时,在生成最佳hint时,优先hint将优先于非优先hint。使用restricted和single-numa-node策略时,将拒绝非优先hint。

HintProvider为每个可以满足该资源请求的NUMA节点的掩码生成一个TopologyHint。如果掩码不能满足要求,则将其省略。例如,当被要求分配2个资源时,HintProvider可能在具有2个NUMA节点的系统上提供以下hint。这些hint编码代表的两种资源可以都来自单个NUMA节点(0或1),也可以各自来自不同的NUMA节点。

{01: True}, {10: True}, {11: False}

当且仅当NUMANodeAffinity代表的信息可以满足资源请求的最小NUMA节点集时,所有HintProvider才会将Preferred字段设置为True。

{0011: True}, {0111: False}, {1011: False}, {1111: False}

如果在其他容器释放资源之前无法满足实际的首选分配,则HintProvider返回所有Preferred字段设置为False的hint列表。考虑以下场景:

1. 当前,除2个CPU外的所有CPU均已分配给容器

2. 剩余的2个CPU在不同的NUMA节点上

3. 一个新的容器请求2个CPU

在上述情况下,生成的唯一hint是{11:False}而不是{11:True}。因为可以从该系统上的同一NUMA节点分配2个CPU(虽然当前的分配状态,还不能立即分配),在可以满足最小对齐方式时,使pod进入失败并重试部署总比选择以次优对齐方式调度pod更好。

b. HintProviders

目前,Kubernetes中仅有的HintProviders是CPUManager、MemoryManager及DeviceManager。拓扑管理器既从HintProviders收集TopologyHint,又使用合并的最佳hint调用资源分配。HintProviders实现以下接口:

type HintProvider interface {
    GetTopologyHints(*v1.Pod, *v1.Container) map[string][]TopologyHint
    Allocate(*v1.Pod, *v1.Container) error
}

注意:GetTopologyHints返回一个map [string] [] TopologyHint。这使单个HintProvider可以提供多种资源类型的hint。例如,DeviceManager可以返回插件注册的多种资源类型。

当HintProvider生成hint时,仅考虑如何满足系统上当前可用资源的对齐方式。不考虑已经分配给其他容器的任何资源。

例如,考虑图1中的系统,以下两个容器请求资源:

# Container0
spec:
    containers:
    - name: numa-aligned-container0
      image: alpine
      resources:
          limits:
              cpu: 2
              memory: 200Mi
              gpu-vendor.com/gpu: 1
              nic-vendor.com/nic: 1
# Container1spec:    containers:    - name: numa-aligned-container1      image: alpine      resources:          limits:              cpu: 2              memory: 200Mi              gpu-vendor.com/gpu: 1              nic-vendor.com/nic: 1
# Container1
spec:
    containers:
    - name: numa-aligned-container1
      image: alpine
      resources:
          limits:
              cpu: 2
              memory: 200Mi
              gpu-vendor.com/gpu: 1
              nic-vendor.com/nic: 1

如果Container0是要在系统上分配的第一个容器,则当前三种拓扑感知资源类型生成以下hint集:

cpu: {{01: True}, {10: True}, {11: False}}
gpu-vendor.com/gpu: {{01: True}, {10: True}}
nic-vendor.com/nic: {{01: True}, {10: True}}

已经对齐的资源分配:

{cpu: {0, 1}, gpu: 0, nic: 0}

在考虑Container1时,上述资源假定为不可用,因此将生成以下hint集:

cpu: {{01: True}, {10: True}, {11: False}}
gpu-vendor.com/gpu: {{10: True}}
nic-vendor.com/nic: {{10: True}}

分配的对齐资源:

{cpu: {4, 5}, gpu: 1, nic: 1}

注意:HintProviders调用Allocate的时,并未采用合并的最佳hint, 而是通过TopologyManager实现的Store接口,HintProviders通过该接口,获取生成的hint:

type Store interface {
    GetAffinity(podUID string, containerName string) TopologyHint
}
c. Policy.Merge

每个策略都实现了合并方法,各自实现如何将所有HintProviders生成的TopologyHint集合合并到单个TopologyHint中,该TopologyHint用于提供已对齐的资源分配信息。

// 1. bestEffort
func (p *bestEffortPolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) {
  filteredProvidersHints := filterProvidersHints(providersHints)
  bestHint := mergeFilteredHints(p.numaNodes, filteredProvidersHints)
  admit := p.canAdmitPodResult(&bestHint)
  return bestHint, admit
}
// 2. restrict
func (p *restrictedPolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) {
  filteredHints := filterProvidersHints(providersHints)
  hint := mergeFilteredHints(p.numaNodes, filteredHints)
  admit := p.canAdmitPodResult(&hint)
  return hint, admit
}
// 3. sigle-numa-node
func (p *singleNumaNodePolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) {
   filteredHints := filterProvidersHints(providersHints)
   // Filter to only include don't cares and hints with a single NUMA node.
   singleNumaHints := filterSingleNumaHints(filteredHints)
   bestHint := mergeFilteredHints(p.numaNodes, singleNumaHints)

   defaultAffinity, _ := bitmask.NewBitMask(p.numaNodes...)
   if bestHint.NUMANodeAffinity.IsEqual(defaultAffinity) {
      bestHint = TopologyHint{nil, bestHint.Preferred}
   }

   admit := p.canAdmitPodResult(&bestHint)
   return bestHint, admit
}

从上述三种分配策略,可以发现Merge方法的一些类似流程:

1. filterProvidersHints

2. mergeFilteredHints

3. canAdmitPodResult

其中filterProvidersHints位于

pkg/kubelet/cm/topologymanager/policy.go:62
func filterProvidersHints(providersHints []map[string][]TopologyHint) [][]TopologyHint {
   // Loop through all hint providers and save an accumulated list of the
   // hints returned by each hint provider. If no hints are provided, assume
   // that provider has no preference for topology-aware allocation.
   var allProviderHints [][]TopologyHint
   for _, hints := range providersHints {
      // If hints is nil, insert a single, preferred any-numa hint into allProviderHints.
      if len(hints) == 0 {
         klog.Infof("[topologymanager] Hint Provider has no preference for NUMA affinity with any resource")
         allProviderHints = append(allProviderHints, []TopologyHint{{nil, true}})
         continue
      }

      // Otherwise, accumulate the hints for each resource type into allProviderHints.
      for resource := range hints {
         if hints[resource] == nil {
            klog.Infof("[topologymanager] Hint Provider has no preference for NUMA affinity with resource '%s'", resource)
            allProviderHints = append(allProviderHints, []TopologyHint{{nil, true}})
            continue
         }

         if len(hints[resource]) == 0 {
            klog.Infof("[topologymanager] Hint Provider has no possible NUMA affinities for resource '%s'", resource)
            allProviderHints = append(allProviderHints, []TopologyHint{{nil, false}})
            continue
         }

         allProviderHints = append(allProviderHints, hints[resource])
      }
   }
   return allProviderHints
}

遍历所有的HintProviders,收集并存储hint。如果HintProviders没有提供任何hint,那么就默认为该provider没有任何资源分配。最终返回allProviderHints.

其中mergeFilteredHints位于

pkg/kubelet/cm/topologymanager/policy.go:95
// Merge a TopologyHints permutation to a single hint by performing a bitwise-AND
// of their affinity masks. The hint shall be preferred if all hits in the permutation
// are preferred.
func mergePermutation(numaNodes []int, permutation []TopologyHint) TopologyHint {
  // Get the NUMANodeAffinity from each hint in the permutation and see if any
  // of them encode unpreferred allocations.
  preferred := true
  defaultAffinity, _ := bitmask.NewBitMask(numaNodes...)
  var numaAffinities []bitmask.BitMask
  for _, hint := range permutation {
    // Only consider hints that have an actual NUMANodeAffinity set.
    if hint.NUMANodeAffinity == nil {
      numaAffinities = append(numaAffinities, defaultAffinity)
    } else {
      numaAffinities = append(numaAffinities, hint.NUMANodeAffinity)
    }

    if !hint.Preferred {
      preferred = false
    }
  }

  // Merge the affinities using a bitwise-and operation.
  mergedAffinity := bitmask.And(defaultAffinity, numaAffinities...)
  // Build a mergedHint from the merged affinity mask, indicating if an
  // preferred allocation was used to generate the affinity mask or not.
  return TopologyHint{mergedAffinity, preferred}
}


func mergeFilteredHints(numaNodes []int, filteredHints [][]TopologyHint) TopologyHint {
   // Set the default affinity as an any-numa affinity containing the list
   // of NUMA Nodes available on this machine.
   defaultAffinity, _ := bitmask.NewBitMask(numaNodes...)

   // Set the bestHint to return from this function as {nil false}.
   // This will only be returned if no better hint can be found when
   // merging hints from each hint provider.
   bestHint := TopologyHint{defaultAffinity, false}
   iterateAllProviderTopologyHints(filteredHints, func(permutation []TopologyHint) {
      // Get the NUMANodeAffinity from each hint in the permutation and see if any
      // of them encode unpreferred allocations.
      mergedHint := mergePermutation(numaNodes, permutation)
      // Only consider mergedHints that result in a NUMANodeAffinity > 0 to
      // replace the current bestHint.
      if mergedHint.NUMANodeAffinity.Count() == 0 {
         return
      }

      // If the current bestHint is non-preferred and the new mergedHint is
      // preferred, always choose the preferred hint over the non-preferred one.
      if mergedHint.Preferred && !bestHint.Preferred {
         bestHint = mergedHint
         return
      }

      // If the current bestHint is preferred and the new mergedHint is
      // non-preferred, never update bestHint, regardless of mergedHint's
      // narowness.
      if !mergedHint.Preferred && bestHint.Preferred {
         return
      }

      // If mergedHint and bestHint has the same preference, only consider
      // mergedHints that have a narrower NUMANodeAffinity than the
      // NUMANodeAffinity in the current bestHint.
      if !mergedHint.NUMANodeAffinity.IsNarrowerThan(bestHint.NUMANodeAffinity) {
         return
      }

      // In all other cases, update bestHint to the current mergedHint
      bestHint = mergedHint
   })

   return bestHint
}

mergeFilteredHints函数处理流程如下所示:

1. 通过cadvisor传递的NUMA节点数生成bitmask

2. 设置 bestHint := TopologyHint{defaultAffinity, false}如果没有符合条件的hint,返回该hint

3. 取每种资源类型生成的TopologyHints的交叉积

4. 对于交叉中的每个条目,每个TopologyHint的NUMA亲和力执行位计算。在合并hint中将此设置为NUMA亲和性。

5. 如果条目中的所有hint都将Preferred设置为True,则在合并hint中的Preferred设置为True。

6. 如果条目中存在Preferred设置为False的hint,则在合并hint中的Preferred设置为False。如果其NUMA亲和性节点数量全为0,则在合并hint中的Preferred设置为False。接上文的分配说明,Container0的hint为:

cpu: {{01: True}, {10: True}, {11: False}}
gpu-vendor.com/gpu: {{01: True}, {10: True}}
nic-vendor.com/nic: {{01: True}, {10: True}}

上面的算法将产生的交叉积及合并后的hint:

生成合并的hint列表之后,将根据Kubelet配置的拓扑管理器分配策略来确定哪个为最佳hint。

一般流程如下所示:

1. 根据合并hint的“狭窄度”进行排序。狭窄度定义为hint的NUMA相似性掩码中设置的位数。设置的位数越少,hint越窄。对于在NUMA关联掩码中设置了相同位数的hint,设置为最低位的hint被认为是较窄的。

2. 根据合并hint的Preferred字段排序。Preferred为true的hint优于Preferred为true的hint。

3. 为Preferred选择具有最佳设置的最窄hint。

在上面的示例中,当前支持的所有策略都将使用hint{01:True}以准入该Pod。

二、社区动向

2.1 已知问题

拓扑管理器所能处理的最大 NUMA 节点个数是 8。若 NUMA 节点数超过 8, 枚举可能的 NUMA 亲和性而生成hint时会导致数据爆炸式增长。

调度器不支持资源拓扑功能,当调度至该节点,但因为拓扑管理器的原因导致在该节点上调度失败。

2.2 功能特性

a. hugepage的numa应用

如前所述,当前仅可用于TopologyManager的三个HintProvider是CPUManager、MemoryManager(1.20+新增)及DeviceManager。但是,目前也正在努力增加对hugepage的支持,TopologyManager最终将能够在同一NUMA节点上分配内存,大页,CPU和PCI设备。

b. 调度

当前,TopologyManager不参与Pod调度决策,仅充当Pod Admission控制器,当调度器将Pod调度到某节点后,TopologyManager才判定应该接受还是拒绝该pod。但是可能会因为节点可用的NUMA对齐资源而拒绝pod,这跟调度系统的决定相悖。

那么我们如何解决这个问题呢?当前Kubernetes调度框架提供实现framework架构,调度算法插件化,可以实现诸如NUMA对齐之类的调度插件。

d. Pod对齐策略

如前所述,单个策略通过Kubelet命令行应用于节点上的所有Pod,而不是根据Pod进行自定义配置。

当前实现该特性最大的问题是,此功能需要更改API才能在Pod结构或其关联的RuntimeClass中表达所需的对齐策略。

三、参考资料

1. https://kubernetes.io/blog/2020/04/01/kubernetes-1-18-feature-topoloy-manager-beta/

2.https://kubernetes.io/docs/tasks/administer-cluster/topology-manager/

3.https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/

4.https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/topology-manager.md

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DCOS 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • a. TopologyHints
  • b. HintProviders
  • c. Policy.Merge
  • b. 调度
  • d. Pod对齐策略
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档