4.8.1 资源需求

下面的是示例中,自主式 Pod 要求为 stress 容器确保 128Mi 的内存及五分之一个CPU核心(200m)资源可用,它运行 stress-ng 镜像启动一个进程(-m 1)进行内存性能压力测试,满载测试时它也会尽可能多的占用CPU资源,另外再启动一个专用的CPU压力测试进程(-c 1)。stress-ng 是一个多功能系统压力测试工具,master/worker 模型,Master 为主进程,负责生成和控制子进程,worker 是负责执行各类特定测试的子进程,例如测试CPU的子进程,以及测试 RAM 的子进程等:

apiVersion: v1
kind: Pod
metadata:
  name: stress-pod
spec:
  containers:
  - name: stress
    image: ikubernetes/stress-ng
    command: ["/usr/bin/stress-ng", "-m 1", "-c 1", "-metrics-brief"]
    resources:
      requests:
        memory: "128Mi"
        cpu: "200m"

上面的配置清单中,其请求使用的 CPU 资源大小为 200m,这意味着一个CPU核心足以确保其以期望的最快方式运行。另外,配置清单中期望使用的内存大小为128Mi,不过其运行时未必会真的用到这么多。考虑到内存为非压缩性资源,其超出指定的大小再运行时存在被 OOM killer 杀死的可能性,于是请求值也应该就是其理想中使用的内存空间上限。

接下来创建并运行此Pod对其资源限制效果尽心检查。需要特别说明的是,笔者当前使用的系统环境中,每个节点的可用 CPU 核心数均为 8,物理内存空间为 16GB:

**[terminal]
**[delimiter $ ]**[command kubectl create -f pod-resources-test.yaml]
pod/stress-pod created

而后在 Pod 资源的容器内运行 top 命令观察其 CPU 及内存资源的占用状态,如下所示,其中 {stress-ng-vm} 是执行内存压测的子进程,它默认使用 256m 的内存空间,{stress-ng-cpu} 是执行 CPU 压测的专用子进程:

**[terminal]
**[delimiter $ ]**[command kubectl exec stress-pod -- top]
Mem: 1731528K used, 6277504K free, 28504K shrd, 2104K buff, 929196K cached
CPU:  55% usr   7% sys   0% nic  37% idle   0% io   0% irq   0% sirq
Load average: 1.42 0.50 0.21 5/390 18
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    8     7 root     R     262m   3%   2  13% {stress-ng-vm} /usr/bin/stress-ng 
    6     1 root     R     6884   0%   1  13% {stress-ng-cpu} /usr/bin/stress-ng
    1     0 root     S     6244   0%   3   0% /usr/bin/stress-ng -m 1 -c 1 --met
......

top 命令的输出结果显示,每个测试进程的CPU占用率为 23%(实际为 12.5%),{stress-ng-vm}的内存占用量为 262m(VSZ),此两项资源占用量都远超其请求的用量,原因是stress-ng会在可用的范围内尽可能多的占用相关资源。两个测试线程分布与两个CPU核心资源充裕,虽然容器的内存用量远超 128M,但它依然可运行。一旦资源紧张时,节点仅保证容器有五分之一各CPU核心可用,对于有着8个核心的节点来说,它的占用率为 2.5%,于是每个进程为 1.25%,多占用的资源会被压缩。内存为非可压缩性资源,所以此Pod在内存资源紧张时可能会因为 OOM 被杀死(killed)。

对于压缩型的资源CPU来说,未定义其请求用量以确保其最小的可用资源时,他可能会被其他的Pod资源压缩至极低的水平,甚至会达到Pod不能被调度运行的境地。而对与非压缩性资源来说,内存资源在任何原因导致的紧缺情况下都有可能导致相关的进程被杀死。因此,在 Kubernetes 系统上运行关键型业务相关的Pod时必须使用requests属性为容器定义资源的确保可用量。

集群中的每个节点都拥有定量的CPU和内存资源,调度 Pod 时,仅那些被请求资源的余量可容纳当前被调度的 Pod 的请求量的节点才可作为目标节点。也就是说,Kubernetes 的调度器会根据容器的 requests 属性中定义的资源需求量来判定哪些节点可接受运行相关的 Pod 资源,而对于一个节点的资源来说,每运行一个 Pod 对象,其 requests 中定义的请求量都要被预留,直到被所有 Pod 对象瓜分完毕为止。

results matching ""

    No results matching ""