在Kubernetes中,有两种资源类型,CPU和内存,它们也称为计算资源。CPU资源以核为单位计算,内存则以字节为单位计算。

在创建Pod时,默认是没有对资源进行限制的,所以好的实践方式是预估好资源的需求,提前为Pod进行资源分配,另外限制Pod能请求的资源的最大数。

CPU和内存的分配标准

在cpu的分配上,我们可以使用 10.50.1 这样的表达来分配,它们分别代表1个核,0.5个核,0.1个核,它们也等同于: 1000m500m100mm 代表millicpu的意思。cpu都是绝对值,所以不管在多少核的机器上,它们的意义都是一样的。

内存的单位是字节,我们可以使用纯数字,也可以用数字带上单位来表示,像:E, P, T, G, M, K,甚至是更高的单位:Ei, Pi, Ti, Gi, Mi, Ki等,比如:

1
1048576128M,256Mi

如何指定资源

要对Pod进行资源分配,可以下面所列出来的Pod的配置中指定:

  • spec.containers[].resources.requests.cpu
  • spec.containers[].resources.requests.memory
  • spec.containers[].resources.limits.cpu
  • spec.containers[].resources.limits.memory

每个Container需要的资源可能是不同的,所以资源的配置是针对Container。前两者是对资源的请求,它们知道了Container需要的资源,从而决定Pod分配到哪个节点上。后两者是对资源的限制,它们指明了Container能获取到的最大资源数。

注意:资源的请求,并非代表着节点当前的实际运行负载,所以当一个结点具体负载并不高,而Pod却报出资源不足而失败的错误,两者并不冲突,因为request代表的是资源的预留,而非具体的使用。

下面是一个使用的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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"

Pod中有两个Container,他们都申请了0.25cpu和64MB内存,最大限制为0.5cpu和128MB内存。所以Pod总共需要的资源为:0.5cpu和128MB内存,最大限制为1cpu和256MB内存。

应用完上面的例子后,通过查看kubectl describe nodes <your-node>,可以看到资源的申请和限制:

1
2
3
4
5
6
7
8
9
10
11
12
13
[ ...其它信息... ]
Non-terminated Pods: (34 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
[ ...其它Pod... ]
default frontend 500m (10%) 1 (20%) 128Mi (1%) 256Mi (3%)
[ ...其它Pod... ]
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 4580m (91%) 39800m (796%)
memory 5678746112 (68%) 6701770Ki (83%)

在资源信息的最下面是总的资源请求和限制信息。

当请求资源大于剩余资源时

由于k8s对Pod的调度依赖于资源请求,假如出现Pod申请的资源大于集群中任一Node节点的剩余资源时,Pod将无法被调度而一直处于Pending状态。假设是CPU资源不足了,我们对Pod进行describe可以得到:

1
2
3
4
Events:
Reason Message
------ -------
FailedScheduling No nodes are available that match all of the following predicates:: Insufficient cpu (3).

信息是很明确的:Insufficient cpu,cpu资源不足。
这个时候,我们需要考虑如何调整资源,让Pod能够成功被调度。

参考

Managing Compute Resources for Containers
Assign CPU Resources to Containers and Pods