乐趣区

关于kubernetes:kubernets-cfs

CFS

CFS(Completely Fair Scheduler) 调度器谋求的是对所有过程的全面偏心,实际上它的做法就是在一个特定的调度周期内,保障所有待调度的过程都能被执行一遍

 过程的运行工夫计算公式为:
过程运行工夫 = 调度周期 * 过程权重 / 所有过程权重之和 
vruntime = 过程运行工夫 * NICE_0_LOAD / 过程权重 = (调度周期 * 过程权重 / 所有过程总权重) * NICE_0_LOAD / 过程权重 = 调度周期 * NICE_0_LOAD / 所有过程总权重 

罕用参数阐明

  • sysctl_sched_latency:示意一段时间内,sched_entity 必定会被调度到一次,也就是一个 sched_entity 调度的最大的延时,2.6.35.13 内核中默认是 6ms。
  • sysctl_sched_min_granularity:示意调度的最小粒度,如果调度的工夫距离小于这个时间段,内核是不会筛选其余 sched_entity 进行调度,这个 2.6.35.13 内核中默认是 2ms。
  • nr_latency:示意在下面的那段最大调度提早中,最多解决的 sched_entity。

CPU cgroup 配置阐明
/sys/fs/cgroup

  • cpu.sched_latency_ns: 调度周期
  • cpu.cfs_period_us: 示意一个 cpu 带宽,单位为微秒。零碎总 CPU 带宽:cpu 外围数 * cfs_period_us
  • cpu.cfs_quota_us: 示意 Cgroup 能够应用的 cpu 的带宽,单位为微秒。cfs_quota_us 为 -1,示意应用的 CPU 不受 cgroup 限度。cfs_quota_us 的最小值为 1ms(1000),最大值为 1s。
  • cpu.shares:cpu.shares 以绝对比例限度 cgroup 的 cpu, 例如: 两个工作再 cgroup 中 share 设置都为 1, 他们有雷同的 cpu 工夫; 如果一个 share 值设置为 2, 那么能够应用 cpu 的工夫就是设置为 1 的 2 倍。(通过 cfs_period_us 和 cfs_quota_us 能够以相对比例限度 cgroup 的 cpu 应用,即 cfs_quota_us/cfs_period_us 等于过程能够利用的 cpu cores,不能超过这个数值。)

cpu.stat
蕴含了上面三项统计后果

  • nr_periods:示意过来了多少个 cpu.cfs_period_us 外面配置的工夫周期
  • nr_throttled:在下面的这些周期中,有多少次是受到了限度(即 cgroup 中的过程在指定的工夫周期中用光了它的配额)
  • throttled_time: cgroup 中的过程被限度应用 CPU 继续了多长时间 (纳秒

调度阐明

有如下系统配置状况:

  • CFS 调度周期为 10ms,失常负载状况下,过程 ready 队列外面的过程在每 10ms 的距离内都会保障被执行一次
  • CFS 重调配周期为 100ms,用于保障一个过程的 limits 设置会被反映在每 100ms 的重调配周期内能够占用的 CPU 工夫数,在多核零碎中,limit 最大值能够是 CFS 重调配周期 *CPU 核数
  • 该执行过程队列只有过程 A 和过程 B 两个过程
  • 过程 A 和 B 定义的 CPU share 占用都一样,所以在系统资源缓和的时候能够保障 A 和 B 过程都能够占用可用 CPU 资源的一半
  • 定义的 CFS 重调配周期都是 100ms
  • 过程 A 在 100ms 内最多占用 50ms,过程 B 在 100ms 内最多占用 20ms

阐明

  • 在后面的 4 个 CFS 调度周期内,过程 A 和 B 因为 share 值是一样的,所以每个 CFS 调度内 (10ms),过程 A 和 B 都会占用 5ms
  • 在第 4 个 CFS 调度周期完结的时候,在本 CFS 重调配周期内,过程 B 曾经占用了 20ms,在剩下的 8 个 CFS 调度周期即 80ms 内,过程 B 都会被限流,始终到下一个 CFS 重调配周期内,过程 B 才能够持续占用 CPU
  • 在第 5 - 7 这 3 个 CFS 调度周期内,因为过程 B 被限流,所以过程 A 能够齐全领有这 3 个 CFS 调度的 CPU 资源,占用 30ms 的执行工夫,这样在本 CFS 重调配周期内,过程 A 曾经占用了 50ms 的 CPU 工夫,在前面剩下的 3 个 CFS 调度周期即前面的 30ms 内,过程 A 也会被限流,始终到下一个 CFS 重调配周期内,过程 A 才能够持续占用 CPU

kubernetes 基于 CFS 进行 CPU 治理

假如 pod 的资源定义为

    resources:
      limits:
        cpu: 500m
        memory: 512Mi
      requests:
        cpu: 200m
        memory: 100Mi

查看 pod 对应的 cgroup 信息

  • 通过 docker 确定对应的 id

    85cb54d5b4-9c6kv 为 pod 中的关键字段
    docker ps |grep  85cb54d5b4-9c6kv
    
     {
            "Id": "38abd5a4414774a87e6c509913b03694411ad921f5b6ee8901fd7dfcf0afebd7",
            "Created": "2021-11-17T07:22:44.873699016Z",
            xxxxx
           "CgroupParent": "/kubepods/burstable/pod3b5332a9-b208-4236-b07b-da447f9fff8c",
    }

    其中 Id 和 CgroupParent 是查找 cgroup 的要害信息
    下面得悉 CgroupParent=/kubepods/burstable/pod3b5332a9-b208-4236-b07b-da447f9fff8c。那么在宿主机上的 cgroup 目录为 /sys/fs/cgroup/cpu/kubepods/${CgroupParent}

  • 查看宿主机目录

    ls /sys/fs/cgroup/cpu/kubepods/burstable/pod3b5332a9-b208-4236-b07b-da447f9fff8c
    38abd5a4414774a87e6c509913b03694411ad921f5b6ee8901fd7dfcf0afebd7  cgroup.procs   cpuacct.usage_all         cpuacct.usage_percpu_user  cpu.cfs_period_us  cpu.rt_runtime_us  notify_on_release
    a2a521da5284c7ad9a0aca61bf470454f4d71b0d1ce18ea64dbab8ac107c9f06  cpuacct.stat   cpuacct.usage_percpu      cpuacct.usage_sys          cpu.cfs_quota_us   cpu.shares         tasks
    cgroup.clone_children                                             cpuacct.usage  cpuacct.usage_percpu_sys  cpuacct.usage_user         cpu.rt_period_us   cpu.stat

    下面为 pod 级别的 cgroup 文件,但一个 pod 是至多有两个个容器一个利用容器和 pause 容器,所以外面有两个文件夹,文件夹名称为 docker inspect xxxx 里看到的第一行 id 字段, 就是下面的 38abd5a4414774a87e6c509913b03694411ad921f5b6ee8901fd7dfcf0afebd7

  • 查看 cgroup 信息

    cat cpu.cfs_period_us
    100000
    cat cpu.shares
    204
    cat cpu.cfs_quota_us
    50000
    
    1. limits 次要用以申明应用的最大的 CPU 核数。通过设置 cfs_quota_us 和 cfs_period_us。比方 limits.cpu=500m,则 cfs_quota_us=50000(cfs_period_us 值个别都应用默认的 100000),cfs_quota_us/cpu.cfs_period_us = 0.5
    2. request 则次要用以申明最小的 CPU 核数。一方面则体现在设置 cpushare 上。比方 request.cpu=200m,则 cpushare=1024*0.2=204.8

CPU 限流问题

 告警主题: CPUThrottlingHigh
告警级别: warning
告警类型: CPUThrottlingHigh
故障实例: 
告警详情: 27% throttling of CPU in namespace kube-system for container kube-proxy in pod kube-proxy-9pj9j.
触发工夫: 2020-05-08 17:34:17

揣测起因: 某些特定的 CFS 重调配周期内,kube-proxy 的 CPU 占用率超过了给它调配的 limits
比方:
假如 pod 的资源定义为

    resources:
      requests:
        memory: "512Mi"
        cpu: "200m"
      limits:
        memory: "512Mi"
        cpu: "200m"

limits 配置只有 200ms,这就意味着在默认的 100ms 的 CFS 重调度周期内,它只能占用 20ms,所以在特定忙碌场景会有问题; 解决方案就是将 CPU limits 进步

退出移动版