自定义调度之 Kubernetes节点 CPU 精细化调度:cpusets-controller

举报
Kubeservice@董江 发表于 2023/06/27 11:26:53 2023/06/27
【摘要】 基于节点cpu精细化调度:cpusets-controller问:在 Kubernetes 中,运行多个集群节点是否存在隐藏成本?答:是的,因为并非 Kubernetes 节点中的所有 CPU 和 Memory 都可用于运行 Pod。在一个 Kubernetes 节点中,CPU 和 Memory 分为:操作系统Kubelet、CNI、CRI、CSI(+ 系统守护进程)Pods驱逐门槛(Ha...

基于节点cpu精细化调度:cpusets-controller

问:在 Kubernetes 中,运行多个集群节点是否存在隐藏成本?
答:是的,因为并非 Kubernetes 节点中的所有 CPUMemory 都可用于运行 Pod

在一个 Kubernetes 节点中,CPUMemory 分为:

  • 操作系统
  • Kubelet、CNI、CRI、CSI(+ 系统守护进程)
  • Pods
  • 驱逐门槛(Hard Eviction threshold)

Kubelet 原生的CPU Manager 对于每一次Pod调度 bindingNode 时, 都会将计算 Node CPU是否够用

Node预留CPU资源 reservedCPUs(KubeReservedCPUs + SystemReservedCPUs + HardEvictionThresholds )并向上取整,最终最为reserved cpus

虽然,对预留资源做了限制,但对于具体的核没有做到绑核运行。如果需要对Pod进行绑核、亲核部署 就再精细化实现了

场景

如果需要对 kubernetes 中使用 CPU 管理器 进行如下更加精细化管理:

  • 解决在一个容器中可以同时使用独占cpu和共享cpu
  • 支持conatiner级别 core亲和 和 绑核
  • 兼容历史申请资源,优雅cgroup cpu驱逐
  • 独占CPU支持 绑核

解决 传统应用上云,特定业务绑核运行 和 核心业务分级CPU亲和(CPU Arrinity)部署

方案

方案一:kubelet 的 cm上直接扩展

直接在 Kubelet中,添加CPUSets对象中,添加DeviceID 和具体拓扑使用,并记录到CheckPoints文件中。

优势:性能优,并且与Kubelet预分配资源做到协同
缺点:
1)更改原生代码,非云原生;
2)多Kubernetes管理和升级复杂;
3)Kubernetes社区难落地,抽象和迭代困难

方案二:做云原生调度插件,替换/选用 kubelet CPU Manager 逻辑

Cpusets Controller 提供一种 Kubernetes 的设备插件,将 CPU 内核作为可 DeviceKubernetes 调度程序.

支持三种类型的 CPU 管理:

  • CPU独占
  • CPU共享
  • CPU默认(兼容默认cpu方式)

包含 3 个核心组件:

  • device plugin: Kubernetes 标准Device插件,将 CPU 池作为可调度资源无缝集成到 Kubernetes
  • controller: Kubernetes 标准 Informer,确保属于不同 CPU Pooler 的容器始终在物理上相互隔离管理和设置
  • webhook: 准入 Webhook验证, 校验 CPU 池特定的用户请求是否合法

Device Plugin 的工作是通过现有的 Device Plugin APIcpu分配 作为可消耗资源注册给 Kubelet. Device PluginCPU 作为包含物理CPU ID列表的环境变量传递给容器。默认情况下,应用程序可以根据给定的 CPU 列表设置其进程 CPU 亲和力,或者可以将其留给标准的 Linux Completely Fair Scheduler。对于应用程序未实现设置其进程的 CPU 亲和力的功能的边缘情况,CPU Pool提供了代表应用程序设置它的机制。通过将应用程序进程信息配置到其 Pod 规范的注释字段来启用此选择加入功能。

Webhook: 以根据启动二进制文件(安装、环境变量等)的需要来改变 Pod 的规范。

Controller 子组件通过 Linux cpusets 实现容器的完全物理分离。通过 Informer 不断地监视 KubernetesPod API,并在创建 Pod 或更改其状态(例如重新启动等)时触发。 shared 在共享的情况下,或者默认情况下容器没有明确要求任何池化资源。Controller 然后将计算出的集合提供给容器的 cgroupfs 文件系统 (cpuset.cpus) 。

优势:
1)对CPU进一步池化,实现部分绑核能力;
2)对现有的部署不影响
3)特定绑核使用,使大颗粒高性能服务可上云;
缺点:
1)default 与 shared共享问题
2)Kubelet CPU Manager 与 CPUSet Controller协同问题

使用方式

配置

cpuset 池化配置描述

apiVersion: v1
kind: ConfigMap
metadata:
  name: cpuset-configmap
  namespace: kube-system #配置所在文件中
data:
  cpuset-config.yaml: | #池化配置
    pools: 
      exclusive:
        cpus : "2-3"
      shared:
        cpus : "1"
      default:
        cpus: "0"
    nodeSelector:
      name: xxxx
  xxxx.yaml : |
    xxxx: xxxx

部署使用:

---
apiVersion: v1
kind: Pod
metadata:
  name: cpuset-exclusive
spec:
  containers:
...
    - name: sharedtestcontainer
      image: dongjiang1989/busyloop:latest
      resources:
        limits:
          cmss.cn/shared: '160'
          memory: 100Mi
        requests:
          cmss.cn/shared: '160'
          memory: 100Mi
    - name: exclusivetestcontainer
      image: dongjiang1989/busyloop:latest
      resources:
        limits:
          cmss.cn/exclusive: '1'
          memory: 100Mi
        requests:
          cmss.cn/exclusive: '1'
          memory: 100Mi

具体实现方式

通过 device pluginCPU资源进行扩展注入:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cpuset-configmap
  namespace: kube-system #对集群中各个机器进行cpu划分
data:
  cpuset-xxx-config.yaml: | #池化配置:必须以.yaml结尾的文件
    pools:   # 将cpu可以分为 3类:exclusive、shared 和 default
      exclusive:    # 对于 exclusive 可以继续进行分组
        cpus : "15-23"   
      exclusive_groupx:
        cpus : "24-31"
      exclusive_xxx:
        cpus : "32-63"
      shared:       # 对于 shared 可以继续进行分组
        cpus : "4-7"
      shared_groupx:
        cpus : "8-11"
      default:      # 对于 default 不能继续分组: default类似原生的cpu资源
        cpus: "0-3"
    nodeSelector:
      name: xxxx
  xxxx.yaml : |
    xxxx: xxxx

注意 本身exclusive、shared 和 default类型设计:

  • exclusive独占型cpu:只能将CPU设置[0,1] 区间;shareddefault是共享型cpuCPU设置[0,1000]1000微核
  • exclusive 、shared和 default的 cpus,不建议重叠; 如果重叠,会影响 kernal cpu漂移问题;
  • 池化配置:必须以.yaml结尾的文件
  • exclusive 、shared内部再分组: 需要以exclusive_ 或者 shared_ 作为 prefix
  • 通过 nodeSelector 对相同机器配置相同策略; 内部key-value,并且是关系

效果demo

[root@kcs-cpu-test-m-8mzmj /]#  kubectl describe node  kcs-cpu-test-s-wht2b
Name:               kcs-cpu-test-s-wht2b
...
Capacity:
  cmss.cn/exclusive:  2
  cmss.cn/shared:     1k
  cpu:                4
  ephemeral-storage:  102350Mi
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             15899180Ki
  pods:               128
Allocatable:
  cmss.cn/exclusive:  2
  cmss.cn/shared:     1k
  cpu:                4
  ephemeral-storage:  96589578081
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             15796780Ki
  pods:               128
System Info:
  Machine ID:                 a679d9cff58d494e972f86fccd3e26a9
  System UUID:                A56C5525-47D0-4185-B3D9-2BA12FD70297
  Boot ID:                    c4aae965-044c-4b24-9340-838385a65a6e
  Kernel Version:             4.14.78-300.el7.bclinux.x86_64
  OS Image:                   BigCloud Enterprise Linux For LDK 7 (Core)
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.4.4
  Kubelet Version:            v1.21.5
  Kube-Proxy Version:         v1.21.5
PodCIDR:                      172.19.3.0/24
PodCIDRs:                     172.19.3.0/24
ProviderID:                   ecloud://a56c5525-47d0-4185-b3d9-2ba12fd70297
Non-terminated Pods:          (47 in total)
  Namespace                   Name                                                      CPU Requests  CPU Limits  Memory Requests    Memory Limits      Age
  ---------                   ----                                                      ------------  ----------  ---------------    -------------      ---
  default                     cpusets-test                                              0 (0%)        0 (0%)      200Mi (1%)         200Mi (1%)         31d
  default                     deployment-lvm-687bd58669-4hsdf                           0 (0%)        0 (0%)      0 (0%)             0 (0%)             80d
  default                     example-hotrod-69f444fd9d-fjfpj                           100m (2%)     100m (2%)   100M (0%)          100M (0%)          86d
  default                     nginx-test                                                0 (0%)        0 (0%)      0 (0%)             0 (0%)             51d
  default                     nginx-test-dongjiang                                      0 (0%)        0 (0%)      0 (0%)             0 (0%)             51d
  ....
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests              Limits
  --------           --------              ------
  cpu                3091m (77%)           3722m (93%)
  memory             4607031306240m (28%)  3600398346240m (22%)
  ephemeral-storage  0 (0%)                0 (0%)
  hugepages-1Gi      0 (0%)                0 (0%)
  hugepages-2Mi      0 (0%)                0 (0%)
  cmss.cn/exclusive  1                     1
  cmss.cn/shared     160                   160
Events:              <none>

开源工程

代码工程:https://github.com/kubeservice-stack/cpusets-controller

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。