背景

Koordinator 作为一个踊跃倒退的开源我的项目,自 2022 年 4 月公布 v0.1.0 版本以来,经验了屡次迭代,继续为 Kubernetes 生态系统带来翻新和加强。我的项目的外围是提供混部工作负载编排、混部资源调度、混部资源隔离和混部性能调优的综合解决方案,帮忙用户优化容器性能,并晋升集群资源应用效率。

在过来的版本迭代中,Koordinator 社区一直壮大,曾经失去了包含阿里巴巴、蚂蚁科技、Intel、小米、小红书、爱奇艺、360、有赞、趣玩、美亚柏科、PITS 等知名企业工程师的积极参与和奉献。每一个版本都是在社区共同努力下推动的,反映了我的项目在理论生产环境中解决问题的能力。

明天咱们很快乐的向大家发表,Koordinator v1.4.0 版本正式公布。在本次公布中,Koordinator 引入了 Kubernetes 与 YARN 负载混部、NUMA 拓扑对齐策略、CPU 归一化和冷内存上报等新个性,同时重点加强了弹性配额治理、宿主机非容器化利用的 QoS 治理、重调度防护策略等畛域的性能。这些新增和改良点旨在更好地反对企业级 Kubernetes 集群环境,特地是对于简单和多样化的利用场景。

v1.4.0 版本的公布,将为用户带来更多的计算负载类型反对和更灵便的资源管理机制,咱们期待这些改良可能帮忙用户应答更多企业资源管理挑战。在 v1.4.0 版本中,共有 11 位新退出的开发者参加到了 Koordinator 社区的建设,他们是 @shaloulcy,@baowj-678,@zqzten,@tan90github,@pheianox,@zxh326,@qinfustu,@ikaven1024,@peiqiaoWang,@bogo-y,@xujihui1985,感激期间各位社区同学的积极参与和奉献,也感激所有同学在社区的继续投入。

版本性能个性解读

1.反对 K8s 与 YARN 混部

Koordinator 曾经反对了 K8s 生态内的在离线混部,然而在 K8s 生态外,仍有相当数量的大数据工作运行在传统的 Hadoop YARN 之上。YARN 作为倒退多年的大数据生态下的资源管理零碎,承载了包含 MapReduce、Spark、Flink 以及 Presto 等在内的多种计算引擎。

Koordinator 社区会同来自阿里云、小红书、蚂蚁金服的开发者们独特启动了 Hadoop YARN 与 K8s 混部我的项目 Koordinator YARN Copilot,反对将 Hadoop NodeManager 运行在 kubernetes 集群中,充分发挥不同类型负载错峰复用的技术价值。Koordinator YARN Copilot 具备以下特点:

  • 面向开源生态

基于 Hadoop YARN 开源版本,不波及对 YARN 的侵入式革新;

  • 对立资源优先级和 QoS 策略

YARN NM 应用 Koordinator 的 Batch 优先级资源,遵循 Koordinator QoS 管理策略;

  • 节点级别的资源共享

Koordinator 提供的混部资源,既可被 K8s Pod 应用,也可被 YARN task 应用,不同类型的离线利用可运行在同一节点。

对于 Koordinator YARN Copilot 的具体设计,以及在小红书生产环境的应用状况,请参考往期文章:《Koordinator 助力云原生利用性能晋升:小红书混部技术实际》以及社区官网文档[1]。

2.引入 NUMA 拓扑对齐策略

运行在 Kubernetes 集群中的工作负载日益多样化。尤其是在机器学习等畛域,对于高性能计算资源的需要持续上升。在这些畛域中,不仅须要大量 CPU 资源,还常常须要 GPU 和 RDMA 等其余高速计算资源配合应用;并且,为了获得最佳的性能,这些资源往往须要在同一个 NUMA 节点,甚至同一个 PCIE 中。

Kubernetes 的 Kubelet 提供了 Topology Manager 来治理资源分配的 NUMA 拓扑,试图在 Kubelet 的 Admission 阶段从节点层面对齐多种资源的拓扑。然而,节点组件没有调度器的全局视角以及为 Pod 抉择节点的机会,可能导致 Pod 被调度到无奈满足拓扑对齐策略的节点上,从而导致 Pod 因为 Topology Affinity 谬误无奈启动。

为了解决这一问题,Koordinator 将 NUMA 拓扑抉择和对齐的机会放在核心调度器中,从集群级别优化资源之间的 NUMA 拓扑。在本次公布的版本中,Koordinator 将 CPU 资源(蕴含 Batch 资源)的 NUMA 感知调度和 GPU 设施的 NUMA 感知调度作为 alpha 性能反对,整套 NUMA 感知调度疾速演进中。

Koordinator 反对用户通过节点的 Label 配置节点上多种资源的 NUMA 拓扑对齐策略,可配置策略如下:

  • None 是默认策略,不执行任何拓扑对齐。
  • BestEffort 示意节点不严格依照 NUMA 拓扑对齐来分配资源。只有节点的残余总量满足 Pods 的需要,调度器总是能够将这样的节点调配给 Pods。
  • Restricted 示意节点严格依照 NUMA 拓扑对齐来分配资源,即调度器在调配多个资源时必须只抉择雷同的一个或多个 NUMA 节点,否则不应应用该节点;能够应用多个 NUMA 节点。例如,如果一个Pod申请 33C,并且每个 NUMA 节点有 32C,那么它能够被调配应用两个 NUMA 节点。如果这个 Pod 还须要申请 GPU/RDMA,那么它须要位于与 CPU 雷同的 NUMA 节点上。
  • SingleNUMANode 与 Restricted 相似,也是严格依照 NUMA 拓扑对齐,但与 Restricted 不同的是,Restricted 容许应用多个NUMA节点,而 SingleNUMANode 只容许应用一个NUMA 节点。

举例,咱们能够为 node-0 设置策略 SingleNUMANode:

apiVersion: v1kind: Nodemetadata:  labels:    node.koordinator.sh/numa-topology-policy: "SingleNUMANode"  name: node-0spec:  ...

在生产环境中,用户可能曾经开启了 Kubelet 的拓扑对齐策略,这个策略会由 koordlet 更新到 NodeResourceTopologyCRD 对象中的 TopologyPolicies字段。当 Kubelet 的策略和用户在 Node 上设置的策略相冲突时,以 Kubelet 策略为准。Koordinator 调度器根本采纳与 Kubelet Topology Manager 雷同的 NUMA 对齐策略语义,Kubelet 策略 SingleNUMANodePodLevel 和SingleNUMANodeContainerLevel 被映射为 SingleNUMANode。

在为节点配置好 NUMA 对齐策略的前提下,调度器能够为每个 Pod 选出许多个符合条件的 NUMA Node 调配后果。Koordinator 以后反对 NodeNUMAResource 插件配置 CPU 和内存资源的 NUMA Node 调配后果打分策略,包含 LeastAllocated 和 MostAllocated,默认为 LeastAllocated 策略,资源反对配置权重。调度器最终将抉择得分最高的 NUMA Node 调配后果。如下例,咱们配置 NUMA Node 调配后果打分策略为 MostAllocated:

apiVersion: kubescheduler.config.k8s.io/v1beta2kind: KubeSchedulerConfigurationprofiles:  - pluginConfig:      - name: NodeNUMAResource        args:          apiVersion: kubescheduler.config.k8s.io/v1beta2          kind: NodeNUMAResourceArgs          scoringStrategy:  # Here configure Node level scoring strategy            type: MostAllocated            resources:              - name: cpu                weight: 1              - name: memory                weight: 1              - name: "kubernetes.io/batch-cpu"                weight: 1              - name: "kubernetes.io/batch-memory"                weight: 1          numaScoringStrategy: # Here configure NUMA-Node level scoring strategy            type: MostAllocated            resources:              - name: cpu                weight: 1              - name: memory                weight: 1              - name: "kubernetes.io/batch-cpu"                weight: 1              - name: "kubernetes.io/batch-memory"                weight: 1

3.ElasticQuota 再进化

为了充沛地利用集群资源、升高管控零碎老本,用户经常将多个租户的负载部署在一个集群中。在集群资源无限的状况下,不同租户之间必然会产生资源争抢。有的租户的负载可能始终被满足,而有的租户的负载始终无奈失去执行。这就产生对公平性的诉求。配额机制是十分天然地保障租户间公平性的形式,给每个租户一个配额,租户能够应用配额内的资源,超过配额的工作将不被调度和执行。然而,简略的配额治理无奈满足租户对云的弹性期待。用户心愿除了配额之内的资源申请能够被满足外,配额之外的资源申请也能够按需地被满足。

在之前的版本中,Koordinator 复用了上游 ElasticQuota 的协定,容许租户设置 Min 表白其肯定要满足的资源诉求,容许设置 Max 限度其最大能够应用的资源和表白在集群资源有余的状况下对集群残余资源的使用权重。另外,Koordinator 察看到,一些租户可能通过 Min 申请了配额,然而理论的工作申请可能并没有充分利用该配额。由此,为了更近一步地进步资源利用率,Koordinator 容许租户间借用/偿还资源。

除了提供弹性的配额机制满足租户按需诉求外,Koordinator 在 ElasticQuota 上减少注解将其组织成树的构造,不便用户表白树形的组织架构。

上图是应用了 Koordinator 弹性配额的集群中常见的 Quota 构造树。Root Quota 是连贯配额与集群中理论资源之间的桥梁。在之前的设计中,Root Quota 只在调度器逻辑中存在,在本次公布中,咱们将 Root Quota 也通过 CRD 的模式裸露给用户,用户能够通过 koordinator-root-quota 这个ElasticQuota CRD 查看 Root Quota 信息。

3.1 引入 Multi QuotaTree

大型集群中的节点的状态是多样的,例如云厂商提供的 ECS VM 会有不同的架构,常见的是 amd64 和 arm64,雷同架构又会有不同品种的机型,而且个别会把节点按可用区划分。不同类型的节点放到同一个 Quota Tree 中治理时,其特有的属性将失落,当用户心愿精细化治理机器的特有属性时,以后的 ElasticQuota 显得不够准确。为了满足用户灵便的资源管理或资源隔离诉求,Koordinator 反对用户将集群中的资源划分为多份,每一份由一个 Quota Tree 来治理,如下图所示:

同时,为了帮忙用户简化治理复杂性,Koordinator 在 v1.4.0 中 引入了 ElasticQuotaProfile 机制,用户能够通过 nodeSelector 疾速的将节点关联到不同的 QuotaTree 中,如下实例所示:

apiVersion: quota.koordinator.sh/v1alpha1kind: ElasticQuotaProfilemetadata:  labels:    kubernetes.io/arch: amd64  name: amd64-profile  namespace: kube-systemspec:  nodeSelector:    matchLabels:      kubernetes.io/arch: amd64 // 筛选 amd64 节点  quotaName: amd64-root-quota   // 匹配的 root quota 名称---apiVersion: quota.koordinator.sh/v1alpha1kind: ElasticQuotaProfilemetadata:  labels:    kubernetes.io/arch: arm64     name: arm64-profile  namespace: kube-systemspec:  nodeSelector:    matchLabels:      kubernetes.io/arch: arm64  // 筛选 arm64 节点  quotaName: arm64-root-quota    // 匹配的 root quota 名称

关联好 QuotaTree 之后,用户在每一个 QuotaTree 中与之前的 ElasticQuota 用法统一。当用户提交 Pod 到对应的 Quota 时,以后依然须要用户实现 Pod NodeAffinity 的治理,以确保 Pod 运行在正确的节点上。将来,咱们会减少一个个性帮忙用户主动治理 Quota 到 Node 的映射关系。

3.2 反对 non-preemptible

Koordinator ElasticQuota 反对把 ElasticQuota 中 min 未应用的局部共享给其余 ElasticQuota 应用从而进步资源利用效率,但当资源缓和时,会通过抢占机制把借用配额的 Pod 抢占驱赶走拿回资源。

在理论生产环境中,有一些在线服务如果从其余 ElasticQuota 中借用了这部分额度,后续又产生了抢占,是可能影响服务质量的。这类工作负载本质上是不能被抢占的。

为了实现这个机制,Koordinator v1.4.0 引入了新的 API,用户只须要在 Pod 上申明 quota.scheduling.koordinator.sh/preemptible: false 示意这个 Pod 不能够被抢占。

调度器调度时发现 Pod 申明了不可抢占,那么此类 Pod 的可用配额的下限不能超过 min,所以这里也须要留神的是,启用该能力时,一个 ElasticQuota 的 min 须要设置的正当,并且集群内有相应的资源保障。

这个个性不会毁坏原有的行为。

apiVersion: v1kind: Podmetadata:  name: pod-example  namespace: default  labels:    quota.scheduling.koordinator.sh/name: "quota-example"    quota.scheduling.koordinator.sh/preemptible: falsespec:...

3.3 其它改良

  1. Koordinator Scheduler 过来反对跨 Namespace 应用同一个 ElasticQuota 对象,但有一些场景下,心愿只被一个或者多个无限的 Namespace 能够共享同一个对象,为了反对这个场景,用户能够在 ElasticQuota 上减少 annotation quota.scheduling.koordinator.sh/namespaces,对应的值为一个 JSON 字符串数组。
  2. 性能优化:过来的实现中,当 ElasticQuota 发生变化时,ElasticQuota 插件会重建整棵 Quota 树,在 v1.4.0 版本中做了优化。
  3. 反对疏忽 Overhead:当 Pod 应用一些平安容器时,个别是在 Pod 中申明 Overhead 示意平安容器本身的资源开销,但这部分资源老本最终是否归于终端用户承当取决于资源售卖策略。当冀望不必用户承当这部分老本时,那么就要求 ElaticQuota 疏忽 overhead。在 v1.4.0 版本中,能够开启 featureGate ElasticQuotaIgnorePodOverhead 启用该性能。

4.CPU 归一化

随着 Kubernetes 集群中节点硬件的多样化,不同架构和代数的 CPU 之间性能差别显著。因而,即便 Pod 的 CPU 申请雷同,理论取得的计算能力也可能大不相同,这可能导致资源节约或利用性能降落。CPU 归一化的指标是通过标准化节点上可调配 CPU 的性能,来保障每个 CPU 单元在 Kubernetes 中提供的计算能力在异构节点间保持一致。

为了解决该问题,Koordinator 在 v1.4.0 版本中实现了一套反对 CPU 归一化机制,依据节点的资源放大策略,调整节点上可调配的 CPU 资源数量,使得集群中每个可调配的 CPU 通过缩放实现算力的基本一致。整体的架构如下图所示:

CPU 归一化分为两个步骤:

  1. CPU 性能评估,计算不同 CPU 的性能基准,能够参考工业级性能评测规范 SPEC CPU[2],这部分 Koordinator 我的项目未提供;
  2. 配置 CPU 归一化系数到 Koordinator,调度零碎基于归一化系数来调度资源,这部分 Koordinator 提供。

将 CPU 归一化比例信息配置到 koord-manager 的 slo-controller-config 中,配置示例如下:

apiVersion: v1kind: ConfigMapmetadata:  name: slo-controller-config  namespace: koordinator-systemdata:  cpu-normalization-config: |    {      "enable": true,      "ratioModel": {         "Intel(R) Xeon(R) Platinum 8269CY CPU @ 2.50GHz": {           "baseRatio": 1.29,           "hyperThreadEnabledRatio": 0.82,           "turboEnabledRatio": 1.52,           "hyperThreadTurboEnabledRatio": 1.0         },         "Intel Xeon Platinum 8369B CPU @ 2.90GHz": {           "baseRatio": 1.69,           "hyperThreadEnabledRatio": 1.06,           "turboEnabledRatio": 1.91,           "hyperThreadTurboEnabledRatio": 1.20         }      }    }  # ...

对于配置了 CPU 归一化的节点,Koordinator 通过 Webhook 拦挡 Kubelet 对 Node.Status.Allocatable 的更新以实现 CPU 资源的缩放,最终在节点上呈现出归一后的 CPU 资源可调配量。

5.改良的重调度防护策略

Pod 迁徙是一个简单的过程,波及审计、资源分配、利用启动等步骤,并且与利用降级、扩大场景以及集群管理员的资源操作和保护操作混合在一起。因而,如果同时有大量 Pods 正在进行迁徙,可能会对系统的稳定性产生影响。此外,如果同一工作负载的许多 Pods 同时被迁徙,也会影响利用的稳定性。此外,如果同时迁徙多个作业中的 Pods,可能会造成惊群效应。因而,咱们心愿程序解决每个作业中的 Pods。

Koordinator 在之前提供的 PodMigrationJob 性能中曾经提供了一些防护策略来解决上述问题。在 v1.4.0 版本中,Koordinator 将之前的防护策略加强为仲裁机制。当有大量的 PodMigrationJob 能够被执行时,由仲裁器通过排序和筛选,来决定哪些 PodMigrationJob 能够失去执行。

排序过程如下:

  • 依据迁徙开始工夫与以后工夫的距离进行排序,距离越小,排名越高。
  • 依据 PodMigrationJob 的 Pod 优先级进行排序,优先级越低,排名越高。
  • 依照工作负载扩散 Jobs,使得同一作业中的 PodMigrationJobs 凑近。
  • 如果作业中已有 Pods 正在迁徙,则该 PodMigrationJob 的排名更高。

筛选过程如下:

  • 依据工作负载、节点、命名空间等对 PodMigrationJob 进行分组和筛选。
  • 查看每个工作负载中正在运行状态的 PodMigrationJob 数量,达到肯定阈值的将被排除。
  • 查看每个工作负载中不可用正本的数量是否超出了最大不可用正本数,超出的将被排除。
  • 查看指标 Pod 所在节点上正在迁徙的 Pod 数量是否超过单个节点的最大迁徙量,超出的将被排除。

6.冷内存上报

为晋升零碎性能,内核个别尽可能不让应用程序申请的页面缓存闲暇,而是尽可能将其调配给应用程序。尽管内核调配了这些内存,然而利用可能不再拜访,这些内存被称为冷内存。

Koordinator 在 1.4 版本中引入冷内存上报性能,次要为将来冷内存回收性能打下基础。冷内存回收次要用于应答两个场景:

  • 对于规范的 Kubernetes 集群,当节点内存水位过高时,突发的内存申请容器导致系统间接内存回收,操作系统的间接内存回收触发时会影响曾经运行容器的性能,如果回收不及时极其场景可能触发整机 oom。放弃节点内存资源的绝对闲暇,对晋升运行时稳定性至关重要。
  • 在混部场景中,高优先级应用程序申请但未应用的资源能够被低优先级应用程序回收利用。对内存而言,操作系统未回收的内存,是不能被 Koordinator 调度零碎看到的。为了进步混部资源效率,回收容器未应用的内存页面能够进步整机的资源利用效率。

Koordlet 在 Collector Plugins 中增加了一个冷页面回收器,用于读取由 kidled(Anolis 内核)、kstaled(Google)或 DAMON(Amazon)导出的 cgroup 文件 memory.idle_stat。该文件蕴含页面缓存中的冷页面信息,并存在于 memory 的每个层次结构中。目前 koordlet 曾经对接了 kidled 冷页面收集器并提供了其余冷页面收集器接口。

在收集冷页面信息后,冷页面回收器将把收集到的指标(例如节点、Pod 和容器的热页面使用量和冷页面大小)存到 metriccache 中,最初该数据会被上报到 NodeMetric CRD 中。

用户能够通过 NodeMetric 启用冷内存回收和配置冷内存收集策略,以后提供了 usageWithHotPageCache、usageWithoutPageCache 和 usageWithPageCache 三种策略,更多的细节详见社区设计文档[3]。

7.非容器化利用的 QoS 治理

在企业容器化过程中,除了曾经运行在 K8s 上的利用,可能还会存在一些非容器化的利用运行在主机上。为了更好兼容企业在容器化过程这一过渡态,Koordinator 开发了节点资源预留机制,能够在尚未容器化的利用预留资源并赋予特定的 QoS 个性。与 Kubelet 提供的资源预留配置不同,Koordinator 次要指标是解决这些非容器化利用与容器化利用运行时的 QoS 问题,整体的计划如下图所示:

目前,应用程序须要依照标准将过程启动到对应的 cgroup 中,Koordinator 未实现主动的 cgroup 搬迁工具。针对宿主机非容器化利用,反对 QoS 如下:

  • LS (Latency Sensitive)

1.CPU QoS(Group Identity):利用依照标准将过程运行在 cgroup 的 cpu 子系统中,koordlet 依据 CPU QoS 的配置 resource-qos-config 为其设置 Group Identity 参数;
2.CPUSet Allocation:利用依照标准将过程运行在 cgroup 的 cpu 子系统中,koordlet 将为其设置 cpu share pool 中的所有 CPU 外围。

  • BE (Best-effort)

1.CPU QoS(Group Identity):利用依照标准将过程运行在 cgroup 的 cpu 子系统中,koordlet 依据 CPU QoS 的配置为其设置 Group Identity 参数。

对于宿主机利用 QoS 治理的具体设计,能够参考社区文档[4],后续咱们将陆续减少其余 QoS 策略对宿主机利用的反对。

8.其它个性

除了上述新个性和性能加强外,Koordinator 在 v1.4.0 版本还做了一些如下的 bugfix 和优化:

  • RequiredCPUBindPolicy

精细化 CPU 编排反对 Required 的 CPU 绑定策略配置,示意严格依照指定的 CPU 绑定策略调配 CPU,否则调度失败。

  • CICD

Koordinator 社区在 v1.4.0 提供了一套 e2e 测试的 Pipeline;提供了 ARM64 镜像。

  • Batch 资源计算策略优化

反对了 maxUsageRequest 的计算策略,用于更激进地超卖高优资源;优化了节点上短时间大量 Pod 启停时,Batch allocatable 被低估的问题;欠缺了对 hostApplication、thirdparty allocatable、dangling pod used 等非凡状况的思考。

  • 其它

利用 libpfm4&perf group 优化 CPI 采集、SystemResourceCollector 反对自定义的过期工夫配置、BE Pod 反对依据 evictByAllocatable 策略计算CPU 满足度、Koordlet CPUSetAllocator 修复了对于 LS 和 None Qos 的 Pod 的过滤逻辑、RDT 资源管制反对取得 sandbox 容器的 task IDs 等。

通过 v1.4.0 Release[5]页面,能够看到更多蕴含在 v1.4.0 版本的新增性能。

将来打算

在接下来的版本中,Koordinator 目前布局了以下性能:

  • Core Scheduling

在运行时侧,Koordinator 开始摸索下一代 CPU QoS 能力,通过利用 Linux Core Scheduling 等内核机制,加强的物理核维度的资源隔离,升高混部的安全性危险,相干工作详见 Issue #1728[6]。

  • 设施联结调配

在 AI 大模型分布式训练场景中,不同机器 GPU 之间通常须要通过高性能网卡互相通信,且 GPU 和高性能网卡就近调配的时候性能更好。Koordinator 正在推动反对多种异构资源的联结调配,目前曾经在协定上和调度器调配逻辑上反对联结调配;单机侧对于网卡资源的上报逻辑正在摸索中。

更多信息,敬请关注 Milestone v1.5.0[7]。

结语

最初,咱们非常感激 Koordinator 社区的所有贡献者和用户,是您们的积极参与和宝贵意见让 Koordinator 不断进步。咱们期待您持续提供反馈,并欢送新的贡献者退出咱们的行列。

相干链接:

[1] 社区官网文档

https://koordinator.sh/zh-Hans/docs/next/designs/koordinator-...

[2] SPEC CPU

https://www.spec.org/cpu2017/

[3] 设计文档

https://github.com/koordinator-sh/koordinator/blob/main/docs/proposals/koordlet/20230728-support-cold-memory-compute.md

[4] 社区文档

https://koordinator.sh/zh-Hans/docs/next/user-manuals/host-ap...

[5] v1.4.0 Release

https://github.com/koordinator-sh/koordinator/releases/tag/v1.4.0

[6] Issue #1728

https://github.com/koordinator-sh/koordinator/issues/1728

[7] Milestone v1.5.0

https://github.com/koordinator-sh/koordinator/milestone/14

作者:乔普

原文链接

本文为阿里云原创内容,未经容许不得转载。