Linux内核CFS CPU使用率解析及Kubernetes相关技术问询
首先明确两个核心机制的边界:
- CFS的
sched_latency_ns是用来控制单次调度的最大时间片,确保进程不会长时间霸占CPU,维持调度公平性。 - Kubernetes的毫核(millicores)限制是通过cgroup的
cpu.cfs_quota_us和cpu.cfs_period_us实现的,它约束的是指定周期内进程能使用的总CPU时间,和单次调度时间片是两个层面的控制。
针对你的疑问:当cgroup限制为100毫核(0.1核心),且sched_latency_ns=10ms时,任务的单次执行时间不会直接被限制为1ms,而是由两个规则共同约束:
CFS的时间片计算
假设该cgroup下只有一个任务,CFS原本会根据sched_latency_ns给它分配最大10ms的单次时间片(因为没有其他进程竞争,总权重等于该进程权重)。但如果cgroup有CPU限制,这个时间片会被进一步约束。cgroup的总时间限制
100毫核对应默认cpu.cfs_period_us=100000(100ms)的情况下,cpu.cfs_quota_us=10000(10ms)——意思是每100ms周期内,该cgroup下所有进程总共只能用10ms CPU时间。
如果任务在一个周期内已经用完了10ms配额,不管CFS的时间片还有多少,都会被强制挂起(throttle),直到下一个周期开始。
举个实际场景:
如果你的任务是CPU密集型,且cgroup限制100毫核,那么它的执行模式会是:连续运行10ms,然后被挂起90ms,重复这个循环。而单次运行的10ms是符合CFS的sched_latency_ns=10ms设置的,并没有被压缩到1ms。
只有当cgroup下有多个进程竞争时,CFS才会把cgroup的10ms配额按进程权重分配给每个进程,这时候单个进程的单次时间片才会小于10ms。比如两个权重相同的进程,每个在周期内最多用5ms,单次时间片也会被CFS控制在5ms以内(受sched_latency_ns的约束,如果latency是10ms,那每个进程的时间片就是5ms)。
总结:
cgroup的毫核限制是周期总时间的约束,而CFS的sched_latency_ns是单次调度时间片的约束。两者共同作用时,单次执行时间取两者计算结果的较小值,但不会直接因为100毫核就把单次时间片压到1ms——除非是多个进程在cgroup内竞争配额,或者你手动调整了cpu.cfs_period_us到10ms(这时候quota=1ms,单次时间片才会被限制在1ms)。
内容的提问来源于stack exchange,提问作者Ronaldo Lanhellas

