kubernetes之计算机资源管理

当你编排一个pod的时候,你也可以可选地指定每个容器需要多少CPU和多少内存(RAM).当容器请求特定的资源时,调度器可以更好地根据资源请求来确定把pod调度到哪个节点上.当容器请求限制特定资源时,特定节点会以指定方式对容器的资源进行限制.

对于资源请求和资源限制的区别,可以查看QoS

资源类型

CPU和RAM都是资源类型,资源类型有一个基本单位.CPU资源通过单位核数来指定,内存通过单位字节来指定.它们和api资源不同.api资源,例如pod和service是kubernetes api server可以读取和修改的对象.

pod和容器的资源请求与资源限制

pod里的每一个容器都可以指一个或多个以下内容:

spec.containers[].resources.limits.cpu

spec.containers[].resources.limits.memory

spec.containers[].resources.requests.cpu

spec.containers[].resources.requests.memory

尽管请求和限制只能通过单个的容器来指定,但是我们通常说pod的资源请求和资源限制,这样更方便.Pod对于某一特定资源的请求(或限制)是pod里单个容器请求资源的和.

CPU的意义

对cpu资源的请求和限制用单位cpu来衡量,一个cpu在kubernetes里和以下任意一个是等价的:

1 AWS vCPU

1 GCP Core

1 Azure vCore

1 IBM vCPU

在祼机因特尔超线程处理器上一个超线程

带小数的请求也是允许的.一个指定spec.containers[].resources.requests.cpu值为0.5的容器会被确保分配1个cpu的一半资源.值0.1和100m是等价的,可以读作100 millicpu,也有人读作100 millicores,实际上意义是一样的.请求资源的值为0.1将会被api转换为100m,请求的精度比1m更小是不允许的,因此100m一个较优的选择.CPU资源的请求总是绝对量,永远不会是一个相对值,值是0.1时对于单核cpu,双核cpu或者甚至48核cpu都是一样的.

内存的意义

对内存资源的请求/限制用字节来衡量.你可以使用一个纯整数或者定点整数带上E, P, T, G, M, K这些后缀,你也可以使用2的幂次方的:Ei, Pi, Ti, Gi, Mi, Ki来表示,比如以下表示的量相等

128974848, 129e6, 129M, 123Mi

以下定义的pod包含两个容器,每一个都请求0.25cpu和64MiB (226 字节)的内存.每一个都限制0.5cpu和128MIB内存.你可以说pod请求0.5cpu和128MiB内存,限制1cpu和256MiB内存

前面说过,pod的资源请求/限制是pod里的容器资源请求/限制的和

apiVersion: v1 kind: Pod metadata: name: frontend spec: containers: - name: db image: mysql env: - name: MYSQL_ROOT_PASSWORD value: "password" resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - name: wp image: wordpress resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" kubernetes如何调度有资源请求的pod

当你创建一个pod,kubernetes会选择一个节点来运行.对于每种资源类型,不论是cpu还是内存,节点可以提供给pod的都是有上限的.对于每种资源,调度器都会确保被调度的pod的请求的总和小于节点的承载能力.请注意即便节点上的cpu或者内存的使用率非常低,但是如果容量检测失败,调度器仍然可能拒绝把某一pod放到指定节点上.这确保后来资源使用增多时不会出现资源短缺的情况.

有资源限制的pod如何运行

当kubelete启动了pod的容器,它会把cpu和内存的限制传入到容器的runtime里

当使用的是docker时:

spec.containers[].resources.requests.cpu的值被转换为核数值,它也可能是小数,乘1024.这个值和2两者较大的一个会被作为--cpu-shares标识的值传入docker run命令

spec.containers[].resources.limits.cpu被转换为millicore值并且乘以100.结果值是容器每100毫秒可用的cpu时间的总和.

注意默认的时间段配额是100毫秒,最小配额是1毫秒.

spec.containers[].resources.limits.memory被转换为整数,然后作为--momory标识的值传入docker run命令.

如果一个容器超过了它的资源限制,则它可能会被终止.如果它是可重启的(根据pod编排时重启策略),则kubelete会重启它,就像对待其它运行时错误一样.

一个容器可能会被允许或者不被允许超过超过它的cpu限制.但是超过cpu资源限制时它不会被杀掉.

问题处理 pod挂起,event消息是:failedScheduling

如果调度器找不到任何可以放置pod的节点,pod一直是未调度状态找到一个合适的节点.调度器每当找不到合适节点来放置pod,就会产生一个事件,信息如下

kubectl describe pod frontend | grep -A 3 Events Events: FirstSeen LastSeen Count From Subobject PathReason Message 36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others

上面的示例中,由于节点的cpu资源不足,名称为frontend的pod调度失败.类似的错误提示也可能是由于内存资源不足(PodExceedsFreeMemory).一般地,如果类似这样的消息出现,可以进行以下尝试:

集群中添加更多节点

终止一些非必须进程来为挂起的pod腾出资源

检测确保pod小于node,比如节点的容量是cpu:1,如果pod请求的是cpu:1.1将永远不会被调度.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgwjw.html