写点什么

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:4411692
用户头像

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

关注

评论 1 条评论

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

一分钟了解深度学习算法

小齐写代码

软件测试/测试开发全日制培训|Pytest跳过用例和失败重试

霍格沃兹测试开发学社

软件测试/测试开发/全日制 |使用Socket.IO实现实时通信

测吧(北京)科技有限公司

测试

使用Terraform部署华为云和kubernetes资源

华为云开发者联盟

开发 华为云 华为云开发者联盟

让代码不再枯燥,变成你的快乐伙伴! -超过200+的python趣味编程系列-完整源码(保证可运行)+执行效果(持续更新ing)

顺顺顺

Python 游戏

Mac电脑版文件启动器:Butler 激活最新版

胖墩儿不胖y

Mac软件 文件启动器

为什么建筑设计师选择网络渲染"效果图"

Renderbus瑞云渲染农场

云渲染 云渲染农场 效果图渲染

左耳听风 - 我对技术的态度「读书打卡 day 02」

Java 工程师蔡姬

读书笔记 程序员 读书 左耳朵耗子

百度搜索exgraph图执行引擎设计与实践

百度Geek说

百度搜索 企业号 1 月 PK 榜 图执行 图执行引擎 DAG执行图

2024第十届上海国际智慧工地展览会

AIOTE智博会

智慧工地展览会 智慧工地展会 智慧工地展

JavaScript 常见错误与异常处理

京东科技开发者

5G之味,在烟火长沙

脑极体

5G

C 语言文件处理全攻略:创建、写入、追加操作解析

小万哥

程序人生 编程语言 软件工程 C/C++ 后端开发

技嘉推出 GEFORCE RTX 40 SUPER 系列显卡

财见

用友全球司库十问(九)|企业为什么需要银企直联?

用友BIP

全球司库

敏捷监控与可观察性

FunTester

软件测试/测试开发/全日制|Pytest如何灵活地运行用例

霍格沃兹测试开发学社

一款完整的单节锂离子电池采用恒定电流/恒定电压线性充电器

芯动大师

软件测试/测试开发/全日制 |解析Web应用中的日志与监控

测吧(北京)科技有限公司

测试

软件测试/测试开发/全日制 |Python全栈开发:构建跨平台、可移植的应用

测吧(北京)科技有限公司

测试

软件测试/测试开发/全日制|pytest如何标记测试用例

霍格沃兹测试开发学社

[大厂实践] DoorDash基于eBPF的监控实践

俞凡

云原生 监控 ebpf 大厂实践

MT7915: Demonstrating the glorious history of wireless communications

wallysSK

Databend 开源周报第 127 期

Databend

漫画IT | 关于你天天用的OS与Git

极狐GitLab

2024年CoinList上第一个项目Subsquid

币离海

Coinlist Subsquid SQD

跨境电商通讯服务

cts喜友科技

通信 通讯

服务器比较常见几个的故障问题

德迅云安全_初启

系统存储架构升级分享 | 京东云技术团队

京东科技开发者

面试官:分布式锁最终解决方案是RedLock吗?为什么?

王磊

Java 面试

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