写点什么

Katalyst v0.5.0 发布:进一步解耦,进一步优化

  • 2024-05-22
    北京
  • 本文字数:5189 字

    阅读完需:约 17 分钟

大小:1.28M时长:07:26
Katalyst v0.5.0 发布:进一步解耦,进一步优化

经过几个月时间的开发测试工作,Katalyst 近日完成了 v0.5.0 版本的发布。在该版本中,我们解耦了 Katalyst 常态混部能力对 kubewharf enhanced kubernetes 的依赖,用户可以在原生 Kubernetes 上安装和使用 Katalyst;另外我们也对上个版本中新加入的资源超分功能做了进一步的优化。期望这个版本可以帮助用户更平滑地使用 Katalyst,实现资源效能提升。


Out-of-Band Resource Manager (ORM)


为了保证业务的 QoS 不受影响,Katalyst 最初在 kubelet 中引入了一个 QoS Resource Manager (QRM) 框架,通过插件化的方式来扩展容器的资源分配策略。虽然该方案在功能上较好地满足了字节跳动内部业务的需求,但 QRM 框架侵入修改了 kubelet,不方便使用和维护。


为此,我们近期对 Katalyst 进行了重构,将 QRM 框架从 kubelet 中解耦出来,实现了一套新的方案叫 ORM。ORM 也就是 Out-of-Band Resource Manager 的缩写,顾名思义就是带外的资源管理框架。



从上面的架构图中可以看到,我们将 QRM 从 kubelet 中移除,在 Katalyst Agent 中新增了一个 ORM 模块。


在注入资源管理策略的 Hook 点的选择上,不同于 QRM,v0.5.0 中新增的 ORM 支持两种模式:NRI 模式(v0.6.0 上线)和旁路异步更新模式。我们在 ORM 中实现了一个 NRI 的 Server,当 Pod 或容器的一些生命周期事件(如 RunPodSandbox/CreateContainer/RemovePodSandbox 等)发生时,containerd 会同步调用 ORM 的 NRI Server,从而实现资源管理策略的注入。此外,对于 containerd 版本比较低的场景,ORM 也提供了一种 Bypass 模式,周期性从旁路异步更新容器的 Cgroup 等配置。


在 NUMA 亲和的实现方式上,因为我们将 QRM 从 kubelet 中解耦出来了,不能再复用 Topology Manager 的撮合能力,因此我们在 ORM 中实现了一个带外的 Topology Manager。此外,解耦之后 kubelet 原生的 PodResources API 返回的数据也和实际的分配情况不一致了,所以我们在 ORM 中也实现了一个带外的 PodResources Server,从而像 Reporter 这样的模块可以从中获取到准确的 CPU 和内存的分配情况,上报到 KCNR CRD 中供调度器感知。


在混部场景下,运行以下命令可以通过 Helm 安装启用了 ORM 的 Katalyst:


helm repo add kubewharf https://kubewharf.github.io/chartshelm repo update
helm install colocation -n katalyst-system --create-namespace kubewharf/katalyst-colocation-orm
复制代码


ORM 相关的配置项在 charts/katalyst/charts/colocation-orm/values.yaml 文件中,主要包括:


katalyst-agent:customArgs:# QRM Plugin 注册的 Socket 路径,改为注册到 ORMqrm-socket-dirs: "/var/lib/katalyst/plugin-socks"


katalyst-agent:  customArgs:    # QRM Plugin 注册的 Socket 路径,改为注册到 ORM    qrm-socket-dirs: "/var/lib/katalyst/plugin-socks"        # Reporter 访问 PodResources API 的 Socket 路径,改为访问 ORM 旁路的 PodResources Server    pod-resources-server-endpoint: "/var/lib/katalyst/pod-resources/kubelet.sock"        # ORM 旁路的 PodResources Server 从何处获取 Device 的分配信息。默认值为 "";可配置为 "kubelet",表示 ORM 从 kubelet 原生的 PodResources Server 获取 Device 的分配信息    orm-devices-provider: "kubelet"         # 如果将 orm-devices-provider 配置为 kubelet,则可通过该配置指定 kubelet 原生的 PodResources Server 的 Socket 路径    orm-kubelet-pod-resources-endpoints: "/var/lib/kubelet/pod-resources/kubelet.sock"        # ORM 旁路的 Topology Manager 的 NUMA 亲和策略,可选值:none / best-effort / restricted / single-numa-node / numeric    topology-policy-name: "none"        # ORM 的资源名映射,比如将 Reclaimed Resources 映射到 cpu、memory 等原生的资源名    orm-resource-names-map: "resource.katalyst.kubewharf.io/reclaimed_millicpu=cpu,resource.katalyst.kubewharf.io/reclaimed_memory=memory"
复制代码


资源超分


在 v0.4.0 中,Katalyst 发布了在线超分功能,用户可以为节点池配置超分比来实现整机的资源超售。但实际的集群运营过程中,通过人工进行静态超分比配置会带来一些风险:

  • 由于 Pod 在节点间的扩缩行为以及业务流量的变化,导致配置的超分比不符合预期,节点出现负载过高的问题;

  • 用户在 kubelet 开启了 CPUManager,绑核行为导致共享池的 CPU 资源被过度超分。


针对以上问题,Katalyst 对超分能力进行了扩展,基于节点实时监控指标以及绑定 CPU 数量对超分比进行动态调整,在提升利用率的同时规避过度超分的风险。


动态超分


Katalyst-agent:Katalyst-agent 通过监控组件(malachite)查询节点 pod 实时指标,并根据指标与配置预估节点的超分比,通过 KCNR 进行上报。


Katalyst-controller:Katalyst-controller watch 并缓存 KCNR(实时超分比)与 NOC(用户超分配置),选择更小的超分比计算节点的超分后资源并进行更新。



兼容原生绑核能力


Katalyst-agent:Katalyst-agent 通过查询 kubelet config 获取 CPUManager 的状态,当 CPUManager 开启并且 policy=static 时,katalyst-agent 统计节点所有 pod 独占 CPU 的数量(具有整数型 CPU requests 的 Guaranteed Pod),并通过 KCNR 上报相关信息。


Katalyst-scheduler:Katalyst-scheduler watch 并缓存节点的 KCNR。


当节点 CPUManager 开启并且 policy=static 时,被独占的 CPU 不会被超分,只有共享资源池中的 CPU 会根据超分比进行放大;同时,新调度的 pod 如果需要独占 CPU,其需要占用的 CPU 资源也不允许通过超分比进行放大。



使用


● 部署监控与资源超分组件



helm repo add kubewharf https://kubewharf.github.io/chartshelm repo update
# 部署malachite监控组件helm install malachite -n malachite-system --create-namespace kubewharf/malachite
# 部署katalyst超分组件helm install overcommit -n katalyst-system --create-namespace kubewharf/katalyst-overcommit
复制代码


kubectl get deployment -n katalyst-system
NAME READY UP-TO-DATE AVAILABLEkatalyst-controller 2/2 2 2 katalyst-webhook 2/2 2 2 katalyst-scheduler 2/2 2 2
kubectl get daemonset -n katalyst-systemNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLEkatalyst-agent 3 3 3 3 3
复制代码


可以看到 katalyst-webhook、katalyst-controller、katalyst-scheduler 以及 katalyst-agent 组件被部署完成。


● 使用动态超分


1. 动态超分配置


可在 charts/katalyst/charts/overcommit/values.yaml 中通过 katalyst-agent.customArgs 对节点的动态超分比计算进行配置:



# 通过修改参数为"-overcommit_aware"可以关闭katalyst-agent中的超分计算与上报功能sysadvisor-plugins: "overcommit_aware"
# 动态超分比计算周期,默认每10秒进行一次计算并上报realtime-overcommit-sync-period: "10s"
# 节点CPU目标负载,表示在当前的pod分配情况下,通过超分比将节点预期的CPU负载调整至目标值realtime-overcommit-CPU-targetload: 0.6# 节点内存目标负载,表示在当前的pod分配情况下,通过超分比将节点预期的内存负载调整至目标值realtime-overcommit-mem-targetload: 0.6
# 集群pod预估CPU负载,节点未分配的CPU资源会基于节点当前负载与这个参数进行超分realtime-overcommit-estimated-cpuload: 0.4# 集群pod预估内存负载,节点未分配的内存资源会基于节点当前负载与这个参数进行超分realtime-overcommit-estimated-memload: 0.6
# 计算CPU超分使用的负载指标,支持cpu.usage.containerCPU-metrics-to-gather: "cpu.usage.container"# 计算内存超分使用的负载指标,支持mem.rss.container、mem.usage.container# 默认使用rss内存,建议根据集群内存使用情况进行指标与目标负载的配置memory-metrics-to-gather: "mem.rss.container"
复制代码


2. 观察测试节点 KCNR,可以看到增加了超分相关的 annotation 信息


kubectl describe kcnr node1
...Annotations: # 根据负载计算的CPU超分比 katalyst.kubewharf.io/cpu_overcommit_ratio: "1.54" # 根据负载计算的内存超分比 katalyst.kubewharf.io/memory_overcommit_ratio: "1.93" # 节点当前已经绑核的CPU数量 katalyst.kubewharf.io/guaranteed_cpus: "0" # 节点 kubelet CPUManager policy katalyst.kubewharf.io/overcommit_cpu_manager: "static" # 节点 kubelet memoryManager policy katalyst.kubewharf.io/overcommit_memory_manager: "None"...
复制代码


3. 观察 Node 对象,发现相比静态超分场景,节点 annotation 新增了部分超分与资源信息


可以看到,实际超分后的资源量通过节点计算并上报的超分比计算得到。由于该值相比于配置值更小,规避了可能出现的过度超分风险。


apiVersion: v1kind: Nodemetadata:  annotations:    # 节点根据负载计算的CPU超分比    katalyst.kubewharf.io/realtime_cpu_overcommit_ratio: "1.51"    # 节点根据负载计算的内存超分比    katalyst.kubewharf.io/realtime_memory_overcommit_ratio: "1.93"    # 手动配置的 CPU 超分比    katalyst.kubewharf.io/cpu-overcommit-ratio: "2.5"    # 手动配置的 Memory 超分比    katalyst.kubewharf.io/memory-overcommit-ratio: "2.5"    spec:  ...status:  # 超分后的资源量  allocatable:    cpu: 11778m    memory: 56468160982220m  capacity:    cpu: 12080m    memory: 64452751810560m  ...
复制代码


4. 指定节点创建一个高负载 pod,观察节点超分比变化


由于 CPU 负载升高,katalyst-agent 计算得到了更小的超分比,节点可用资源进一步降低,避免更多负载调度到节点上。


apiVersion: v1kind: Podmetadata:  name: testpod1  namespace: katalyst-system...spec:  affinity:    nodeAffinity:      requiredDuringSchedulingIgnoredDuringExecution:        nodeSelectorTerms:        - matchExpressions:          - key: kubernetes.io/hostname            operator: In            values:            - node1  containers:  - name: testcontainer1    image: polinux/stress:latest    command: ["stress"]    args: ["--cpu", "4", "--timeout", "6000"]    resources:      limits:        cpu: 8        memory: 8Gi      requests:        cpu: 4        memory: 8Gi  tolerations:  - effect: NoSchedule    key: test    value: test    operator: Equal
复制代码


kubectl describe kcnr node1
Annotations: # 由于负载升高,katalyst-agent计算得到超分比减小 katalyst.kubewharf.io/cpu_overcommit_ratio: 1.00 katalyst.kubewharf.io/guaranteed_cpus: 0 katalyst.kubewharf.io/memory_overcommit_ratio: 1.93 katalyst.kubewharf.io/overcommit_cpu_manager: static katalyst.kubewharf.io/overcommit_memory_manager: None
复制代码


其他更新


API 扩展

  • CNR 支持 socket-level 设备亲和性上报;

  • SPD 支持扩展 extended-indicator,方便外部系统自定义画像能力。


QoS 增强

  • share-cores with numa-binding 精细化微拓扑分配能力达到生产可用状态。


策略扩展

  • 内存:支持 drop cache、TMO、动态跨 NUMA 迁移内存页、基于 min/max 实现内存保护 等策略;

  • IO:引入 io.cost,io.weight,wbt,根据优先级针对不同负载进行 IO 限速;

  • 基于原生 fake-numa 机制实现自定义 NUMA 调度、分配和内存带宽限制能力。


单机组件

  • metrics-fetcher:和 malachite 解耦,并支持对接 cgroup,kubelet stats 等多种不同的数据源;metrics 增加采集时间戳并支持数据过期检查;

  • reporter:支持实时上报 node-metrics 到 CNR,配合调度器实现基于负载的重调度能力;

  • meta-server:优化单机查询 SPD 频率,避免对 APIServer QPS 过高而引发的稳定性风险;

  • 单机组件 healthz 接口集成各个模块核心功能健康检查,并接入 readiness-check。


中心组件

  • controller(s):支持 transformed-informer 机制优化中心组件内存占用;

  • recommender:原生规格推荐推荐能力增强并实现和 vpa 体系的集成;

  • KCMAS:支持根据 metric label 进行分组聚合查询;


此外,也修复了 goroutine 泄漏、gRPC 连接泄漏,nil allocation-info 导致 panic 等若干问题。


非常期待更多开发者和用户能加入到 Katalyst 开源社区中,和我们一起交流和探讨在离线混部以及资源效能的相关话题。如需开源交流,添加字节跳动云原生小助手,加入云原生社群:

2024-05-22 11:4411658
用户头像

发布了 21 篇内容, 共 10.8 次阅读, 收获喜欢 13 次。

关注

评论 1 条评论

发布
用户头像
下文待读
2024-06-03 13:29 · 广东
回复
没有更多了
发现更多内容

在华为P50 Pro中,听到AI异构通信的朱弦三叹

脑极体

牛掰!“基础-中级-高级”Java程序员面试集结,看完献出我的膝盖

Java 编程 面试 IT 计算机

云原生的能源数据管理平台方案|EMQ 映云科技&华为云联合直播内容回顾

EMQ映云科技

华为云 能源 Cloud 碳中和 emq

Qunar 酒店 NodeJS 覆盖率收集实践

Qunar技术沙龙

大前端 nodejs Node JavaScrip

替换及重置Homebrew默认源以及M1安装

一个大红包

8月日更

狂刷《Java权威面试指南(阿里版)》,冲击“金九银十”有望了

Java 程序员 架构 面试 大厂

前端基础五之jQuery基础

ベ布小禅

8月日更

2021年8月数据库流行度排行:数据库道路漫漫其修远兮,为用户创造核心价值是正道

墨天轮

数据库 TiDB oceanbase 国产数据库 达梦

如何在Android 8.0以下高效地复用图片?

爱奇艺技术产品团队

android 开发 图片存储

厉害!GitHub星标70K阿里大佬手写的Spring Boot实战手册真不错

Java 编程 程序员 架构 计算机

腾讯、阿里纷纷看好的NFT,能否成为拯救区块链的良药?

CECBC

DevOps 调查第十年,如何借助工具实现落地?

飞算JavaAI开发助手

DevOps 基础软件 自动化平台

从头到尾没有一句废话!阿里Redis神级手册,从基础到源码

Java redis 编程 面试 阿里

凭借一份“面试真经pdf”,我四面字节跳动,拿下1-2级offer

Java 程序员 面试 后端 计算机

Activiti数据库表结构

金陵老街

netty系列之:netty中的懒人编码解码器

程序那些事

Java Netty nio 程序那些事

赋能数据中心绿色低碳 浪潮云洲有实招

云计算

Go 让 Apache APISIX 如虎添翼

API7.ai 技术团队

Apache 开源 插件 APISIX Go 语言

排查指南 | 两个案例学会从埋点排查 iOS 离线包

蚂蚁集团移动开发平台 mPaaS

mPaaS

「古老」茶产业碰上「年轻」区块链,能否擦出新火花?

CECBC

租房市场是流动的么?

escray

生活记录 8月日更 搜房记 租房

“性能混合架构”了解了吗?英特尔Alder Lake惊艳来袭

科技新消息

浅谈云上攻防——Kubelet访问控制机制与提权方法研究

腾讯安全云鼎实验室

k8s 云安全

千字真言,字字珠玑,我的Golang学习笔记,赤诚分享

奔着腾讯去

Go 语言

进化十多年,四足机器人的网红属性有改变吗?

脑极体

腾讯「小借条」引发的思考:区块链+的商业模式让各企业争先恐后的奥秘

CECBC

Apache APISIX 在 Airwallex 的应用 | 专访 Airwallex 技术平台负责人李杨

API7.ai 技术团队

Apache 开源 案例分享 api 网关 APISIX

一周信创舆情观察(8.9~8.15)

统小信uos

DevOps如何攻克研发流程六大痛点?

BoCloud博云

字节大牛的1850页Leetcode刷题笔记外泄!用实力折服众人

Java 程序员 字节跳动 面试 算法

字节架构师离职后,熬夜整理55W字Java面试手册,逆风翻盘进阿里

Java 编程 程序员 架构 面试

Katalyst v0.5.0 发布:进一步解耦,进一步优化_字节跳动_字节跳动云原生_InfoQ精选文章