管理容器的计算资源

    CPUmemory 都是 资源类型。资源类型具有基本单位。CPU 的单位是 core,memory 的单位是 byte。

    CPU和内存统称为计算资源,也可以称为资源。计算资源的数量是可以被请求、分配和消耗的可测量的。它们与 API 资源 不同。 API 资源(如 Pod 和 )是可通过 Kubernetes API server 读取和修改的对象。

    Pod 和 容器的资源请求和限制

    Pod 中的每个容器都可以指定以下的一个或者多个值:

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

    尽管只能在个别容器上指定请求和限制,但是我们可以方便地计算出 Pod 资源请求和限制。特定资源类型的Pod 资源请求/限制是 Pod 中每个容器的该类型的资源请求/限制的总和。

    CPU 的含义

    CPU 资源的限制和请求以 cpu 为单位。

    Kubernetes 中的一个 cpu 等于:

    • 1 AWS vCPU
    • 1 GCP Core
    • 1 Azure vCore
    • 1 Hyperthread 在带有超线程的裸机 Intel 处理器上

    允许浮点数请求。具有 spec.containers[].resources.requests.cpu 为 0.5 的容器保证了一半 CPU 要求 1 CPU的一半。表达式 0.1 等价于表达式 100m,可以看作 “100 millicpu”。有些人说成是“一百毫 cpu”,其实说的是同样的事情。具有小数点(如 0.1)的请求由 API 转换为100m,精度不超过 1m。因此,可能会优先选择 100m 的形式。

    CPU 总是要用绝对数量,不可以使用相对数量;0.1 的 CPU 在单核、双核、48核的机器中的意义是一样的。

    内存的限制和请求以字节为单位。您可以使用以下后缀之一作为平均整数或定点整数表示内存:E,P,T,G,M,K。您还可以使用两个字母的等效的幂数:Ei,Pi,Ti ,Gi,Mi,Ki。例如,以下代表大致相同的值:

    下面是个例子。

    以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: frontend
    5. spec:
    6. containers:
    7. - name: db
    8. image: mysql
    9. resources:
    10. requests:
    11. cpu: "250m"
    12. limits:
    13. memory: "128Mi"
    14. cpu: "500m"
    15. - name: wp
    16. image: wordpress
    17. resources:
    18. requests:
    19. memory: "64Mi"
    20. cpu: "250m"
    21. limits:
    22. memory: "128Mi"
    23. cpu: "500m"

    具有资源请求的 Pod 如何调度

    当您创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。每个节点具有每种资源类型的最大容量:可为 Pod 提供的 CPU 和内存量。调度程序确保对于每种资源类型,调度的容器的资源请求的总和小于节点的容量。请注意,尽管节点上的实际内存或 CPU 资源使用量非常低,但如果容量检查失败,则调度程序仍然拒绝在该节点上放置 Pod。当资源使用量稍后增加时,例如在请求率的每日峰值期间,这可以防止节点上的资源短缺。

    具有资源限制的 Pod 如何运行

    当使用 Docker 时:

    • spec.containers[].resources.requests.cpu 的值将转换成 millicore 值,这是个浮点数,并乘以1024,这个数字中的较大者或2用作 命令中的 --cpu-shares 标志的值。
    • spec.containers[].resources.limits.cpu 被转换成 millicore 值。被乘以 100000 然后 除以 1000。这个数字用作 docker run 命令中的 标志的值。[--cpu-quota ] 标志被设置成了 100000,表示测量配额使用的默认100ms 周期。如果 [--cpu-cfs-quota] 标志设置为 true,则 kubelet 会强制执行 cpu 限制。从 Kubernetes 1.2 版本起,此标志默认为 true。
    • spec.containers[].resources.limits.memory 被转换为整型,作为 docker run 命令中的 --memory 标志的值。

    如果容器超过其内存限制,则可能会被终止。如果可重新启动,则与所有其他类型的运行时故障一样,kubelet 将重新启动它。

    如果一个容器超过其内存请求,那么当节点内存不足时,它的 Pod 可能被逐出。

    容器可能被允许也可能不被允许超过其 CPU 限制时间。但是,由于 CPU 使用率过高,不会被杀死。

    要确定容器是否由于资源限制而无法安排或被杀死,请参阅疑难解答]部分。

    Pod 的资源使用情况被报告为 Pod 状态的一部分。

    如果为集群配置了可选监控,则可以从监控系统检索 Pod 资源的使用情况。

    疑难解答

    如果调度器找不到任何该 Pod 可以匹配的节点,则该 Pod 将保持不可调度状态,直到找到一个可以被调度到的位置。每当调度器找不到 Pod 可以调度的地方时,会产生一个事件,如下所示:

    在上述示例中,由于节点上的 CPU 资源不足,名为 “frontend” 的 Pod 将无法调度。由于内存不足(PodExceedsFreeMemory),类似的错误消息也可能会导致失败。一般来说,如果有这种类型的消息而处于 pending 状态,您可以尝试如下几件事情:

    1. $ kubectl describe nodes e2e-test-minion-group-4lw4
    2. Name: e2e-test-minion-group-4lw4
    3. [ ... lines removed for clarity ...]
    4. Capacity:
    5. alpha.kubernetes.io/nvidia-gpu: 0
    6. cpu: 2
    7. memory: 7679792Ki
    8. pods: 110
    9. Allocatable:
    10. alpha.kubernetes.io/nvidia-gpu: 0
    11. cpu: 1800m
    12. memory: 7474992Ki
    13. pods: 110
    14. [ ... lines removed for clarity ...]
    15. Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
    16. --------- ---- ------------ ---------- --------------- -------------
    17. kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
    18. kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
    19. kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
    20. kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
    21. kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
    22. Allocated resources:
    23. (Total limits may be over 100 percent, i.e., overcommitted.)
    24. CPU Requests CPU Limits Memory Requests Memory Limits
    25. ------------ ---------- --------------- -------------

    我的容器被终结了

    您的容器可能因为资源枯竭而被终结了。要查看容器是否因为遇到资源限制而被杀死,请在相关的 Pod 上调用 kubectl describe pod

    在上面的例子中,Restart Count: 5 意味着 Pod 中的 simmemleak 容器被终止并重启了五次。

    您可以使用 kubectl get pod 命令加上 -o go-template=... 选项来获取之前终止容器的状态。

    1. [13:59:01] $ kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc
    2. Container Name: simmemleak
    3. LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]

    Kubernetes 1.5 版本中引入不透明整型资源。不透明的整数资源允许集群运维人员发布新的节点级资源,否则系统将不了解这些资源。

    用户可以在 Pod 的 spec 中消费这些资源,就像 CPU 和内存一样。调度器负责资源计量,以便在不超过可用量的同时分配给 Pod。

    注意: 不透明整型资源在 kubernetes 1.5 中还是 Alpha 版本。只实现了资源计量,节点级别的隔离还处于积极的开发阶段。

    不透明整型资源是以 pod.alpha.kubernetes.io/opaque-int-resource- 为前缀的资源。API server 将限制这些资源的数量为整数。有效 数量的例子有 33000m3Ki无效数量的例子有 0.51500m

    申请使用不透明整型资源需要两步。首先,集群运维人员必须在一个或多个节点上通告每个节点不透明的资源。然后,用户必须在 Pod 中请求不透明资源。

    要发布新的不透明整型资源,集群运维人员应向 API server 提交 PATCH HTTP请求,以指定集群中节点的status.capacity 的可用数量。在此操作之后,节点的 status.capacity 将包括一个新的资源。 status.allocatable 字段由 kubelet 异步地使用新资源自动更新。请注意,由于调度器在评估 Pod 适应度时使用节点 status.allocatable 值,所以在使用新资源修补节点容量和请求在该节点上调度资源的第一个 pod 之间可能会有短暂的延迟。

    示例

    这是一个 HTTP 请求,master 节点是 k8s-master,在 k8s-node-1 节点上通告 5 个 “foo” 资源。

    ```bash{% raw %}curl —header “Content-Type: application/json-patch+json” \—request PATCH \—data ‘[{“op”: “add”, “path”: “/status/capacity/pod.alpha.kubernetes.io~1opaque-int-resource-foo”, “value”: “5”}]’ \

    1. **注意:** 在前面的请求中,`~1` patch 路径中 `/` 字符的编码。JSON-Patch 中的操作路径值被解释为 JSON-Pointer。更多详细信息请参阅 [IETF RFC 6901, section 3](https://tools.ietf.org/html/rfc6901#section-3)。
    2. ```yaml
    3. apiVersion: v1
    4. kind: Pod
    5. metadata:
    6. name: my-pod
    7. spec:
    8. containers:
    9. - name: my-container
    10. image: myimage
    11. resources:
    12. requests:

    计划改进

    在 kubernetes 1.5 版本中仅允许在容器上指定资源量。计划改进对所有容器在 Pod 中共享资源的计量,如 。

    在 kubernetes 1.5 版本中仅支持容器对 CPU 和内存的申请和限制。计划增加新的资源类型,包括节点磁盘空间资源和一个可支持自定义资源类型的框架。

    Kubernetes 通过支持通过多级别的 服务质量 来支持资源的过度使用。