长期支持版本

    特性介绍

    Pod CPU 优先级

    rubik 支持业务 CPU 优先级配置,针对在/离线业务混合部署的场景,确保在线业务相对离线业务的 CPU 资源抢占。

    前置条件

    • 建议使用 openEuler-22.03以上版本。在上述版本中内核支持针对 cgroup 的 cpu 优先级配置,即 cpu 子系统存在接口 cpu.qos_level。

    CPU 优先级内核接口

    • /sys/fs/cgroup/cpu 目录下容器的 cgroup 中,如/sys/fs/cgroup/cpu/kubepods/burstable/<PodUID>/<container-longid>目录
      • cpu.qos_level:开启 CPU 优先级配置,默认值为 0, 有效值为 0 和-1。
        • 0:标识为在线业务
        • -1:标识为离线业务

    CPU 优先级配置详解

    rubik 会根据 Pod 的 yaml 文件中的注解volcano.sh/preemptable自动配置 cpu.qos_level, 默认为 false。

    annotations:
        volcano.sh/preemptable: true
    
    • true:代表业务为离线业务
    • false:代表业务为在线业务

    Pod 内存优先级

    rubik 支持业务 memory 优先级配置,针对在/离线业务混合部署的场景,确保 OOM 时优先 kill 离线业务。

    前置条件

    • 建议使用 openEuler-22.03以上版本。在上述版本的内核中支持针对 cgroup 的 memory 优先级配置,即 memory 子系统存在接口 memory.qos_level。
    • 开启内存优先级支持:echo 1 > /proc/sys/vm/memcg_qos_enable

    内存优先级内核接口

    • /proc/sys/vm/memcg_qos_enable:开启内存优先级特性,默认值为 0,有效值为 0 和 1。开启命令为:echo 1 > /proc/sys/vm/memcg_qos_enable

      • 0:表示关闭特性
      • 1:表示开启特性。
    • /sys/fs/cgroup/memory 目录下容器的 cgroup 中,如/sys/fs/cgroup/memory/kubepods/burstable/<PodUID>/<container-longid>目录

      • memory.qos_level:开启内存优先级配置,默认值为 0,有效值为 0 和-1。
        • 0:标识为在线业务
        • -1:标识为离线业务

    内存优先级配置详解

    rubik 会根据 Pod 的 yaml 文件中的注解volcano.sh/preemptable自动配置 memory.qos_level,参考CPU 优先级配置详解

    dynCache 访存带宽和 LLC 限制

    rubik 支持业务的 Pod 访存带宽(memory bandwidth)和 LLC(Last Level Cache)限制,通过限制离线业务的访存带宽/LLC 使用,减少其对在线业务的干扰。

    前置条件

    • cache/访存限制功能仅支持物理机,不支持虚拟机。

      • x86 物理机,需要 OS 支持且开启 intel RDT 的 CAT 和 MBA 功能,内核启动项 cmdline 需要添加rdt=l3cat,mba
      • ARM 物理机,需要 OS 支持且开启 mpam 功能,内核启动项需要添加mpam=acpi
    • 由于内核限制,RDT mode 当前不支持 pseudo-locksetup 模式。

    rubik 新增权限和目录

    • 挂载目录:/sys/fs/resctrl。 rubik 需要读取和设置/sys/fs/resctrl 目录下的文件,该目录需在 rubik 启动前挂载,且需保障在 rubik 运行过程中不被卸载。
    • 权限:SYS_ADMIN. 设置主机/sys/fs/resctrl 目录下的文件需要 rubik 容器被赋有 SYS_ADMIN 权限。
    • namepsace: pid namespace. rubik 需要获取业务容器进程在主机上的 pid,所以 rubik 容器需与主机共享 pid namespace。

    rubik rdt 控制组

    rubik 在 RDT resctrl 目录(默认为 /sys/fs/resctrl)下创建 5 个控制组,分别为 rubik_max、rubik_high、rubik_middle、rubik_low、rubik_dynamic。rubik 启动后,将水位线写入对应控制组的 schemata。其中,low、middle、high 的水位线可在 cacheConfig 中配置;max 控制组为默认最大值,dynamic 控制组初始水位线和 low 控制组一致。

    离线业务 Pod 启动时通过注解volcano.sh/cache-limit设置其 cache level,并被加入到指定的控制组中,如下列配置的 Pod 将被加入 rubik_low 控制组:

    annotations:
        volcano.sh/cache-limit: "low"
    

    rubik dynamic 控制组

    当存在 level 为 dynamic 的离线 Pod 时,rubik 通过采集当前节点在线业务 Pod 的 cache miss 和 llc miss 指标,调整 rubik_dynamic 控制组的水位线,实现对 dynamic 控制组内离线应用 Pod 的动态控制。

    dynCache 内核接口

    • /sys/fs/resctrl: 在该目录下创建 5 个控制组目录,并修改其 schemata 和 tasks 文件。

    dynCache 配置详解

    dynCache 功能相关的配置在cacheConfig中:

    "cacheConfig": {
            "enable": false,
            "defaultLimitMode": "static",
            "adjustInterval": 1000,
            "perfDuration": 1000,
            "l3Percent": {
                "low": 20,
                "mid": 30,
                "high": 50
            },
            "memBandPercent": {
                "low": 10,
                "mid": 30,
                "high": 50
            }
        },
    
    • l3Percent 和 memBandPercent: 通过 l3Percent 和 memBandPercent 配置 low, mid, high 控制组的水位线。

      比如当环境的rdt bitmask=fffff, numa=2时,rubik_low 的控制组将根据 l3Percent low=20 和 memBandPercent low=10 两个参数,将为/sys/fs/resctrl/rubik_low 控制组配置:

      L3:0=f;1=f
      MB:0=10;1=10
      
    • defaultLimitMode: 如果离线 Pod 未指定volcano.sh/cache-limit注解,将根据 cacheConfig 的 defaultLimitMode 来决定 Pod 将被加入哪个控制组:

      • defaultLimitMode 为 static 时,Pod 将被加入到 rubik_max 控制组
      • defaultLimitMode 为 dynamic 时,Pod 将被加入到 rubik_dynamic 控制组
    • adjustInterval: dynCache 动态调整 rubik_dynamic 控制组的间隔时间,单位 ms,默认 1000ms

    • perfDuration: dynCache 性能 perf 执行时长,单位 ms,默认 1000ms

    dynCache 注意事项

    • dynCache 仅针对离线 Pod,对在线业务不生效。
    • 若业务容器运行过程中被手动重启(容器 ID 不变但容器进程 PID 变化),针对该容器的 dynCache 无法生效。
    • 业务容器启动并已设置 dynCache 级别后,不支持对其限制级别进行修改。
    • 动态限制组的调控灵敏度受到 rubik 配置文件内 adjustInterval、perfDuration 值以及节点在线业务 Pod 数量的影响,每次调整(若干扰检测结果为需要调整)间隔在区间【adjustInterval+perfDuration, adjustInterval+perfDuration*Pod 数量】内波动,用户可根据灵敏度需求调整配置项。

    blkio

    Pod 的 blkio 的配置以volcano.sh/blkio-limit注解的形式,在 Pod 创建的时候配置,或者在 Pod 运行期间通过 kubectl annotate 进行动态的修改,支持离线和在线 Pod。

    配置内容为 4 个列表:

    说明
    device_read_bps用于设定设备执行“读”操作字节的上限。该配置为 list,可以对多个 device 进行配置,device 指定需要限制的块设备,value 限定上限值,单位为 byte
    device_read_iops用于设定设备执行“读”操作次数的上限。该配置为 list,可以对多个 device 进行配置,device 指定需要限制的块设备
    device_write_bps用于设定设备执行 “写” 操作次数的上限。该配置为 list,可以对多个 device 进行配置,device 指定需要限制的块设备,value 限定上限值,单位为 byte
    device_write_iops用于设定设备执行“写”操作字节的上限。该配置为 list,可以对多个 device 进行配置,device 指定需要限制的块设备

    blkio 内核接口

    • /sys/fs/cgroup/blkio 目录下容器的 cgroup 中,如/sys/fs/cgroup/blkio/kubepods/burstable/<PodUID>/<container-longid>目录:
      • blkio.throttle.read_bps_device
      • blkio.throttle.read_iops_device
      • blkio.throttle.write_bps_device
      • blkio.throttle.write_iops_device

    配置的 key:value 和 cgroup 的 key:value 的配置规则一致:

    • 写入时会转换成环境 page size 的倍数
    • 只有 minor 为 0 的 device 配置才会生效
    • 如果取消限速,可将值设为 0

    blkio 配置详解

    rubik 开启关闭 blkio 功能:

    rubik 提供 blkio 配置功能的开关,在blkioConfig

    "blkioConfig": {
            "enable": true
    }
    
    • enable: IO 控制模块使能开关, 默认为 false

    Pod 配置样例:

    通过 Pod 的注解配置时可提供四个列表,分别是 write_bps, write_iops, read_bps, read_iops, read_byte.

    • 创建时:在 yaml 文件中

      volcano.sh/blkio-limit: '{"device_read_bps":[{"device":"/dev/sda1","value":"10485760"}, {"device":"/dev/sda","value":"20971520"}],
                      "device_write_bps":[{"device":"/dev/sda1","value":"20971520"}],
                      "device_read_iops":[{"device":"/dev/sda1","value":"200"}],
                      "device_write_iops":[{"device":"/dev/sda1","value":"300"}]}'
      
    • 修改 annotation: 可通过 kubectl annotate 动态修改,如: kubectl annotate --overwrite pods <podname> volcano.sh/blkio-limit='{"device_read_bps":[{"device":"/dev/vda", "value":"211715200"}]}'

    memory

    rubik 中支持多种内存策略。针对不同场景使用不同的内存分配方案,以解决多场景内存分配。

    dynlevel 策略:基于内核 cgroup 的多级别控制。通过监测节点内存压力,多级别动态调整离线业务的 memory cgroup,尽可能地保障在线业务服务质量。

    fssr 策略:基于内核 cgroup 的动态水位线控制。memory.high 是内核提供的 memcg 级的水位线接口,rubik 动态检测内存压力,动态调整离线应用的 memory.high 上限,实现对离线业务的内存压制,保障在线业务的服务质量。

    memory dynlevel 策略内核接口

    • /sys/fs/cgroup/memory 目录下容器的 cgroup 中,如/sys/fs/cgroup/memory/kubepods/burstable/<PodUID>/<container-longid>目录。dynlevel 策略会依据当前节点的内存压力大小,依次调整节点离线应用容器的下列值:

      • memory.soft_limit_in_bytes
      • memory.force_empty
      • memory.limit_in_bytes
      • /proc/sys/vm/drop_caches

    memory dynlevel 策略配置详解

    rubik 提供 memory 的指定策略和控制间隔,在memoryConfig

    "memoryConfig": {
            "enable": true,
            "strategy": "none",
            "checkInterval": 5
       }
    
    • enable 为是否打开该配置的开关

    • strategy 为 memory 的策略名称,现支持 dynlevel/fssr/none,默认为 none。

      • none: 即不设置任何策略,不会对内存进行调整。
      • dynlevel: 动态分级调整策略。
      • fssr: 快压制慢恢复策略。1)rubik 启动时,默认配置所有离线的 memory.high 为总内存的 80%。2)当内存压力增加,可用内存 freeMemory < reservedMemory(预留内存,totalMemory * 5%) 时认为内存紧张,此时压缩所有离线的 memory.high, 压缩量为总内存的 10%,即最新的 memory.high=memory.high-totalMemory * 10%。3)当持续一段时间总内存比较富裕,即可用内存 freeMemory > 3 * reservedMemory(totalMemory * 5%)时认为内存富裕,此时释放总内存的 1%给离线应用,memory.high=memory.high+totalMemory * 1%, 直到 memory free 介于 reservedMemory 与 3 * reservedMemory 之间。
    • checkInterval 为策略的周期性检查的时间,单位为秒,默认为 5。

    memory fssr 策略内核接口

    • /sys/fs/cgroup/memory 目录下容器的 cgroup 中,如/sys/fs/cgroup/memory/kubepods/burstable/<PodUID>/<container-longid>目录。fssr 策略会依据当前节点的内存压力大小,依次调整节点离线应用容器的下列值:
    • memory.high

    memory fssr 策略配置详解

    rubik 提供 memory 的指定策略和控制间隔,在memoryConfig

    "memoryConfig": {
            "enable": true,
            "strategy": "fssr",
            "checkInterval": 5
       }
    
    • enable 为是否打开该配置的开关

    • strategy 为 memory 的策略名称,现支持 dynlevel/fssr/none 两个选项,默认为 none。

      • none: 即不设置任何策略,不会对内存进行调整。
      • dynlevel: 动态分级调整策略。
      • fssr: 快压制慢恢复策略。1)rubik 启动时,默认配置所有离线的 memory.high 为总内存的 80%。2)当内存压力增加,可用内存 freeMemory < reservedMemory(预留内存,totalMemory * 5%) 时认为内存紧张,此时压缩所有离线的 memory.high, 压缩量为总内存的 10%,即最新的 memory.high=memory.high-totalMemory * 10%。3)当持续一段时间总内存比较富裕,即可用内存 freeMemory > 3 * reservedMemory(totalMemory * 5%)时认为内存富裕,此时释放总内存的 1%给离线应用,memory.high=memory.high+totalMemory * 1%, 直到 memory free 介于 reservedMemory 与 3 * reservedMemory 之间。
    • checkInterval 为策略的周期性检查的时间,单位为秒,默认为 5。

    quota burst

    Pod 的 quota burst 的配置以volcano.sh/quota-burst-time注解的形式,在 Pod 创建的时候配置,或者在 Pod 运行期间通过 kubectl annotate 进行动态的修改,支持离线和在线 Pod。

    Pod 的 quota burst 默认单位是 microseconds, 其允许容器的 cpu 使用率低于 quota 时累积 cpu 资源,并在 cpu 利用率超过 quota 时,使用容器累积的 cpu 资源。

    quota burst 内核接口

    • /sys/fs/cgroup/cpu 目录下容器的 cgroup 中,如/sys/fs/cgroup/cpu/kubepods/burstable/<PodUID>/<container-longid>目录,注解的值将被写入下列文件中:

      • cpu.cfs_burst_us
    • 注解volcano.sh/quota-burst-time的值和 cpu.cfs_burst_us 的约束一致:

      • 当 cpu.cfs_quota_us 不为-1,需满足 cpu.cfs_burst_us + cpu.cfs_quota_us <= 2^44-1 且 cpu.cfs_burst_us <= cpu.cfs_quota_us
      • 当 cpu.cfs_quota_us 为-1,cpu.cfs_burst_us 最大没有限制,取决于系统最大可设置的值

    Pod 配置样例

    • 创建时:在 yaml 文件中

      metadata:
        annotations:
          volcano.sh/quota-burst-time : "2000"
      
    • 修改 annotation: 可通过 kubectl annotate 动态修改,如:

      kubectl annotate --overwrite pods <podname> volcano.sh/quota-burst-time='3000'

    基于 iocost 的 io 权重控制

    依赖说明

    rubik 支持通过在 cgroup v1 下的 iocost 控制不同 Pod 的 io 权重分配。因此需要内核支持如下特性:

    • 内核支持 cgroup v1 blkcg iocost
    • 内核支持 cgroup v1 writeback

    rubik 实现说明

    步骤如下

    • 部署 rubik 时,rubik 解析配置并设置 iocost 相关参数
    • rubik 注册检测事件到 k8s api-server
    • Pod 被部署时将 Pod 配置信息等回调到 rubik
    • rubik 解析 Pod 配置信息,并根据 qos level 配置 Pod iocost 权重

    rubik 协议说明

    "nodeConfig": [
            {
                "nodeName": "slaver01",
                "iocostEnable": true,
                "iocostConfig": [
                    {
                        "dev": "sda",
                        "enable": false,
                        "model": "linear",
                        "param": {
                            "rbps": 174610612,
                            "rseqiops": 41788,
                            "rrandiops": 371,
                            "wbps": 178587889,
                            "wseqiops": 42792,
                            "wrandiops": 379
                        }
                    }
                ]
            }
        ]
    
    配置项类型说明
    nodeConfig数组node 节点配置信息
    nodeNamestring要配置的节点名称
    iocostEnablebool该 node 节点是否使用 iocost
    iocostConfig数组针对不同物理磁盘的配置数组,当 iocostEnable 为 true 时会被读取
    devstring物理磁盘名称
    enablebool该物理磁盘是否启用 iocost
    modelstringiocost 的模型名称,linear 为内核自带线性模型
    paramobject该参数针对 model 参数配置,当 model 为 linear 时,下面的参数都是 linear 相关参数
    r(w)bpsint64该物理块设备最大读(写)带宽
    r(w)seqiopsint64该物理块设备最大顺序读(写)iops
    r(w)randiopsint64该物理块设备最大随机读(写)iops

    其他

    • iocost linear 模型相关参数可以通过 iocost_coef_gen.py 脚本获取,可以从link获得。

    • 在 blkcg 根系统文件下存在blkio.cost.qosblkio.cost.model两个文件接口。实现方式和接口说明可以访问 openEuler 内核文档。

    文档捉虫

    “有虫”文档片段

    问题描述

    提交类型 issue

    有点复杂...

    找人问问吧。

    PR

    小问题,全程线上修改...

    一键搞定!

    问题类型
    规范和低错类

    ● 错别字或拼写错误;标点符号使用错误;

    ● 链接错误、空单元格、格式错误;

    ● 英文中包含中文字符;

    ● 界面和描述不一致,但不影响操作;

    ● 表述不通顺,但不影响理解;

    ● 版本号不匹配:如软件包名称、界面版本号;

    易用性

    ● 关键步骤错误或缺失,无法指导用户完成任务;

    ● 缺少必要的前提条件、注意事项等;

    ● 图形、表格、文字等晦涩难懂;

    ● 逻辑不清晰,该分类、分项、分步骤的没有给出;

    正确性

    ● 技术原理、功能、规格等描述和软件不一致,存在错误;

    ● 原理图、架构图等存在错误;

    ● 命令、命令参数等错误;

    ● 代码片段错误;

    ● 命令无法完成对应功能;

    ● 界面错误,无法指导操作;

    风险提示

    ● 对重要数据或系统存在风险的操作,缺少安全提示;

    内容合规

    ● 违反法律法规,涉及政治、领土主权等敏感词;

    ● 内容侵权;

    您对文档的总体满意度

    非常不满意
    非常满意
    提交
    根据您的反馈,会自动生成issue模板。您只需点击按钮,创建issue即可。
    文档捉虫
    编组 3备份