Kubernetes: Task: Managing Compute Resources for Containers

5th June 2021 at 1:48pm

Kubernetes 设计了 Compute Resource(计算资源)的概念。与 API Resource(比如 Pod, Service)不同,compute resource 表示一个容器在运行时的资源使用,分为 CPU 和内存两种。每种资源又分为 request 和 limit 两种,比如下面的 deployment:

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"

其中:

  • CPU
    • Limit 的值表示该容器能使用的最多 CPU 时间(应该是通过 cgroup 去限制的)。如果容器的 CPU 使用率很高,容器实现(如 docker)可能会允许容器使用比它的 limit 更多的 CPU,但是 K8S 不会将容器杀掉
    • Request 的值通过转换,会变成 --cpu-share 参数传给 docker
  • 内存
    • Limit 表示能使用的内存上限。容器业务程序使用的量大于 limit 值时,会因为 OOM 被容器内的操作系统杀掉
    • Request 表示 K8S 保证分配给容器使用的内存量。如果业务程序使用的内存大于 request,且 node 节点上资源不足时,容器有可能被 K8S evict

虽然 limit / request 是配置在容器上的,但是 pod 也有这个概念,它的 limit / request 指其中所有容器的总和。

K8S 在选择 node 节点去部署 pod 时,会保证该 node 剩余的容量 大于 pod 所要求的 request,但不要求剩余容量大于 limit。Node capacity 一般由 kubelet 自动上报,但是也可以手动指定,比如你需要预留一部分资源给不被 K8S 管理的进程时。K8S 计算 node 剩余容量时,不会将非 kubelet 管理的资源计算进来,比如你手动 docker run 的容器,或者 node 节点上非容器的进程。

参考