我对两个参数之间的关系感到困惑:cgroup的requests
和cpu.shares
,一旦部署了Pod,就会更新。根据我到目前为止所做的阅读,cpu.shares
在试图获得消耗CPU的机会时反映了某种优先级。这是一个相对值。
那么我的问题是,为什么kubernetes在调度时会将CPU的request
值视为绝对值?当涉及到CPU进程时,将根据其优先级(根据CFS机制)获得要执行的时间片。据我所知,没有所谓给出这样数量的CPU(1CPU、2CPU等)。那么,如果cpu.share
值被认为是任务的优先级,为什么kubernetes会考虑精确的请求值(例如:1500米、200米)来查找节点呢?
如果我弄错了,请纠正我。谢谢
从主问题和评论中回答您的问题:
那么我的问题是,为什么kubernetes在调度时会将CPU的
request
值视为绝对值?
据我所知,没有所谓给出这样数量的CPU(1CPU、2CPU等)。因此,如果
cpu.share
值被认为是任务的优先级,为什么kubernetes会考虑精确的请求值(例如:1500米、200米)来查找节点?
这是因为请求中的十进制CPU值总是转换为以毫为单位的值,比如0.1等于100m,可以读作"0";一亿cpu";或";一百毫核";。这些单位是特定于Kubernetes:
允许部分请求。具有
spec.containers[].resources.requests.cpu
或0.5
的容器的CPU数量保证是要求1个CPU的容器的一半。表达式0.1
等效于表达式100m
;一亿cpu";。有些人说"一百毫核";,这被理解为相同的意思。API将具有小数点的请求(如0.1
)转换为100m
,并且不允许精度小于1m
。出于这个原因,形式100m
可能是优选的。
CPU总是作为绝对量请求,而不是作为相对量;0.1是单核、双核或48核机器上相同数量的CPU。
基于上述内容,请记住,您可以通过指定cpu: 1.5
或cpu: 1500m
来指定使用节点的1.5 CPU。
只想知道降低cgroups中的
cpu.share
值(部署后由k8s修改)会影响进程的cpu功耗。例如,假设A、B容器分配了1024、2048个共享。因此,可用资源将按1:2的比例分配。那么,对于两个容器,它是否与我们将cpu.share配置为10、20相同。仍然是1:2
让我们明确一点——比率是一样的,但值不同。cpu.shares
中的1024和2048表示在Kubernetes资源中定义的cpu: 1000m
和cpu: 2000m
,而10和20表示cpu: 10m
和cpu: 20m
。
假设集群节点基于Linux操作系统。那么,kubernetes如何确保将请求值提供给容器呢?最终,操作系统将使用cgroup中可用的配置来分配资源,对吧?它修改cgroup的
cpu.shares
值。所以我的问题是,k8s修改了哪些文件来告诉操作系统将100m
或200m
赋予容器?
是的,你的想法是正确的。让我更详细地解释一下。
通常在Kubernetes节点上,根cgroup下有三个cgroup,命名为切片:
k8s使用
cpu.share
文件来分配CPU资源。在这种情况下,根cgroup继承4096个CPU共享,这些共享是可用CPU功率的100%(1核=1024;这是固定值)。根cgroup根据children的cpu.share
按比例分配其份额,他们对自己的children也这样做,依此类推。在典型的Kubernetes节点中,根cggroup下有三个cgroup,即system.slice
、user.slice
和kubepods
。前两个用于为关键系统工作负载和非k8s用户空间程序分配资源。最后一个kubepods
是由k8s创建的,用于将资源分配给pod。
要检查哪些文件被修改,我们需要转到/sys/fs/cgroup/cpu
目录。在这里,我们可以找到名为kubepods
的目录(这是上面提到的切片之一),pod的所有cpu.shares
文件都在这里。在kubepods
目录中,我们可以找到另外两个文件夹——besteffort
和burstable
。值得一提的是,Kubernetes有三个QoS类:
- 保证
- 可爆破的
- 竭尽全力
每个pod都有一个指定的QoS类,根据它是哪个类,该pod位于相应的目录中(除非有保证,否则具有该类的pod是在kubepods
目录中创建的)。
例如,我正在创建一个定义如下的pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
selector:
matchLabels:
app: test-deployment
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: test-deployment
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
resources:
requests:
cpu: 300m
- name: busybox
image: busybox
args:
- sleep
- "999999"
resources:
requests:
cpu: 150m
根据前面提到的定义,这个pod将分配Qos类Burstable
,因此它将在/sys/fs/cgroup/cpu/kubepods/burstable
目录中创建。
现在我们可以检查这个吊舱的cpu.shares
设置:
user@cluster /sys/fs/cgroup/cpu/kubepods/burstable/podf13d6898-69f9-44eb-8ea6-5284e1778f90 $ cat cpu.shares
460
这是正确的,因为一个吊舱需要300米,第二个吊舱需要150米,它是通过乘以1024来计算的。对于每个容器,我们也有子目录:
user@cluster /sys/fs/cgroup/cpu/kubepods/burstable/podf13d6898-69f9-44eb-8ea6-5284e1778f90/fa6194cbda0ccd0b1dc77793bfbff608064aa576a5a83a2f1c5c741de8cf019a $ cat cpu.shares
153
user@cluster /sys/fs/cgroup/cpu/kubepods/burstable/podf13d6898-69f9-44eb-8ea6-5284e1778f90/d5ba592186874637d703544ceb6f270939733f6292e1fea7435dd55b6f3f1829 $ cat cpu.shares
307
如果你想阅读更多关于Kubrenetes CPU管理的内容,我建议你阅读以下内容:
- Kubernetes中的CPU限制和积极的节流
- 控制节点上的CPU管理策略
- Kubernetes资源限制和内核cgroups
- 如何演化Kubernetes资源管理模型