• Managing Compute Resources for Containers(管理容器的计算资源)
    • Resource types(资源类型)
    • Resource requests and limits of Pod and Container(Pod和容器资源的最小需求与最大限制)
    • Meaning of CPU(CPU的含义)
    • Meaning of memory(内存的含义)
    • How Pods with resource requests are scheduled(如何调度带有request的Pods)
    • How Pods with resource limits are run(带有资源limit的Pod是如何运行的)
    • 监控计算资源使用情况(Monitoring compute resource usage)
    • Troubleshooting(故障排查)
      • My Pods are pending with event message failedScheduling
      • My Container is terminated
    • Local ephemeral storage (alpha feature)(ephemeral-storage,本地临时存储(Alpha功能))
      • Requests and limits setting for local ephemeral storage(local ephemeral storage的request和limit设置)
      • How Pods with ephemeral-storage requests are scheduled(如何调度设置了ephemeral-storage request的Pod)
      • How Pods with ephemeral-storage limits run(如何运行设置了ephemeral-storage limit的Pod)
    • Opaque integer resources (alpha feature) (不透明的整数资源(alpha特征))
    • Extended Resources(扩展资源)
    • Planned Improvements(计划改进)
    • What’s next
    • 原文

    Managing Compute Resources for Containers(管理容器的计算资源)

    译者按:本节中,笔者将request翻译成最小需求,limit翻译成最大限制。由于出现的次数太多,故而绝大多数地方直接不翻译了,大家可以当做术语来阅读。

    指定 Pod 时,可选择指定每个容器需要多少CPU和内存(RAM)。当容器指定了最小资源需求时,Scheduler可对Pod调度到哪个Node上进行更好的决策。当容器具有指定的资源限制时,可以指定的方式,处理Node上资源的争抢。有关资源的最小需求和最大限制之间的差异的更多信息,请参阅 Resource QoS 。

    Resource types(资源类型)

    CPU内存都是资源类型 。资源类型有基本单元。CPU以核心为单位指定,内存以字节为单位指定。

    CPU和内存统称为计算资源 ,也可称为资源 。 计算资源是可以请求、分配和消费的,可测量的数量。它们与 API resources 。 API资源(如Pods和 Services 是可通过Kubernetes API Server读取和修改的对象。

    Resource requests and limits of Pod and Container(Pod和容器资源的最小需求与最大限制)

    Pod的每个容器可指定以下一个或多个:

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

    尽管只能在每个容器上指定request和limit,但这样既可方便地算出Pod资源的request和limit。特定资源类型的Pod resource request/limit是Pod中每个容器该类型资源的request/limit的总和。

    Meaning of CPU(CPU的含义)

    CPU资源的request和limit以cpu为单位。在Kubernetes中,一个cpu相当于:

    • 1 AWS vCPU
    • 1 GCP Core
    • 1 Azure vCore
    • 1 Hyperthread on a bare-metal Intel processor with Hyperthreading

    允许小数。具有 spec.containers[].resources.requests.cpu=0.5 的容器,保证其所需的CPU资源是需要1cpu 容器资源的一半。表达式 0.1 等价于表达式 100m ,可看作“100millicpu”。有些人说“100 millicore”,表达的也是一个意思。具有小数点的请求(如 0.1 ,会由API转换为 100m ,精度不超过 1m

    CPU始终被要求作为绝对数量,从不作为相对数量;0.1在单核、双核或48核机器中,表示的是相同数量的CPU。

    Meaning of memory(内存的含义)

    memory 的request和limit以字节为单位。可使用整数或定点整数来表示内存,并使用如下后缀之一:E、P、T、G、M、K;也可使用:Ei,Pi,Ti ,Gi,Mi,Ki。 例如,以下代表大致相同的值:

    1. 128974848, 129e6, 129M, 123Mi

    如下是一个例子。如下Pod有两个容器。每个容器都有0.25 cpu和64MiB(226字节)内存的request。 每个容器的内存限制为0.5 cpu和128MiB。你可以说Pod有0.5 cpu和128 MiB内存的request,有1 cpu和256MiB内存的limit。

    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. memory: "64Mi"
    12. cpu: "250m"
    13. limits:
    14. memory: "128Mi"
    15. cpu: "500m"
    16. - name: wp
    17. image: wordpress
    18. resources:
    19. requests:
    20. memory: "64Mi"
    21. cpu: "250m"
    22. limits:
    23. memory: "128Mi"
    24. cpu: "500m"

    How Pods with resource requests are scheduled(如何调度带有request的Pods)

    当您创建一个Pod时,Kubernetes Scheduler将为Pod选择一个Node。对于各种资源类型,每个Node都有最大容量:可为Pod提供的CPU和内存量。Scheduler确保对于每种资源类型,调度到该Node的所有容器的request之和小于该Node的容量。请注意,尽管Node上的实际内存或CPU资源使用量非常低,但如果容量检查失败,那么Scheduler仍会拒绝在该Node上放置一个Pod。这样可在资源使用稍后增加时,例如在请求的高峰期,防止Node上的资源短缺。

    How Pods with resource limits are run(带有资源limit的Pod是如何运行的)

    当kubelet启动Pod的容器时,它将CPU和内存限制传递到容器运行时。

    使用Docker时:

    • spec.containers[].resources.requests.cpu 转换为其核心值,该值可能是小数,乘以1024。该数字中的较大值或2用作 docker run 命令中 --cpu-shares 的值。

    • spec.containers[].resources.limits.cpu 转换为其millicore值并乘以100。结果值是容器每100ms可以使用的CPU时间总量。 在此间隔期间,容器不能占用超过其CPU时间的份额。

      注意 :默认配额期限为100ms。 CPU配额的最小分辨率为1ms。

    • spec.containers[].resources.limits.memory 会被转换为一个整数,并用作 docker run命令中 --memory 标志的值。

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

    如果一个容器超出其内存request,那么当Node内存不满足要求时,Pod可能会被逐出。

    容器可能被允许或不允许长时间超过其CPU limit。 然而,即使CPU使用量过大,容器也不会被杀死。

    要确定容器是否由于资源limit而无法调度或被杀死,请参阅 Troubleshooting 部分。

    监控计算资源使用情况(Monitoring compute resource usage)

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

    如果为集群配置了 optional monitoring ,那么即可从监控系统查询Pod资源的使用情况。

    Troubleshooting(故障排查)

    My Pods are pending with event message failedScheduling

    如果Scheduler找不到任何Pod能够匹配的Node,则Pod将保持unscheduled状态。每当调度程序找不到地方调度Pod时,会产生一个事件,如下所示:

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

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

    • 向集群添加更多Node。
    • 终止不需要的Pod,为处于pending的Pod腾出空间。
    • 检查Pod是否不大于所有Node。例如,如果所有Node的容量为 cpu: 1 ,那么request = cpu: 1.1 的Pod将永远不会被调度。

    可使用 kubectl describe nodes 命令检查Node的容量和数量。 例如:

    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. Non-terminated Pods: (5 in total)
    16. Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
    17. --------- ---- ------------ ---------- --------------- -------------
    18. kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
    19. kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
    20. kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
    21. kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
    22. kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
    23. Allocated resources:
    24. (Total limits may be over 100 percent, i.e., overcommitted.)
    25. CPU Requests CPU Limits Memory Requests Memory Limits
    26. ------------ ---------- --------------- -------------
    27. 680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)

    由如上输出可知,如果一个Pod的request超过1120mCPU或6.23Gi内存,它将不适合该Node。

    通过查看 Pods 部分,可查看哪些Pod占用Node上的空间。

    译者按:CPU 1120m是这么算的:1800m(Allocatable) - 680m(Allocated)。同理,内存是7474992Ki - 1070Mi

    Pods所用的资源量必须小于Node容量,因为系统守护程序需要使用一部分资源。 allocatable 字段 NodeStatus 给出了Pod可用的资源量。有关更多信息,请参阅 Node Allocatable Resources 。

    可配置 resource quota 功能,从而限制能够使用的资源总量。 如果与Namespace一起使用,则可防止一个团队占用所有资源。

    My Container is terminated

    由于资源不足,容器可能会被终止。要查看容器是否因为资源限制而被杀死,请在感兴趣的Pod上调用 kubectl describe pod

    1. [12:54:41] $ kubectl describe pod simmemleak-hra99
    2. Name: simmemleak-hra99
    3. Namespace: default
    4. Image(s): saadali/simmemleak
    5. Node: kubernetes-node-tf0f/10.240.216.66
    6. Labels: name=simmemleak
    7. Status: Running
    8. Reason:
    9. Message:
    10. IP: 10.244.2.75
    11. Replication Controllers: simmemleak (1/1 replicas created)
    12. Containers:
    13. simmemleak:
    14. Image: saadali/simmemleak
    15. Limits:
    16. cpu: 100m
    17. memory: 50Mi
    18. State: Running
    19. Started: Tue, 07 Jul 2015 12:54:41 -0700
    20. Last Termination State: Terminated
    21. Exit Code: 1
    22. Started: Fri, 07 Jul 2015 12:54:30 -0700
    23. Finished: Fri, 07 Jul 2015 12:54:33 -0700
    24. Ready: False
    25. Restart Count: 5
    26. Conditions:
    27. Type Status
    28. Ready False
    29. Events:
    30. FirstSeen LastSeen Count From SubobjectPath Reason Message
    31. Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
    32. Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine
    33. Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
    34. Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
    35. Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a

    在上述示例中, Restart Count: 5 表示Pod中的 simmemleak 容器已终止并重启了5次。

    可使用 kubectl get pod-o go-template=... 选项来获取先前终止的Containers的状态:

    1. [13:59:01] $ kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99
    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]]

    您可以看到容器由于 reason:OOM Killed 而终止,其中OOM代表Out Of Memory。

    Local ephemeral storage (alpha feature)(ephemeral-storage,本地临时存储(Alpha功能))

    Kubernetes 1.8版本引入了一种新的资源,用于管理本地临时存储的ephemeral-storage。 在每个Kubernetes Node中,kubelet的根目录(默认 /var/lib/kubelet )和日志目录( /var/log )存储在Node的根分区上。 此分区也可由Pod通过EmptyDir Volume、容器日志、镜像层以及容器可写层等进行共享和使用。

    该分区是“短暂的”,应用程序不能对此分区的性能SLA(例如磁盘IOPS)有期望。 Local ephemeral storage管理仅适用于根分区;镜像层和可写层的可选分区超出了Local ephemeral storage的范围。

    注意:如果使用可选的运行时分区,根分区将不会保存任何镜像层或可写层。

    译者按:

    SLA:https://baike.baidu.com/item/SLA/2957862

    IOPS:https://baike.baidu.com/item/IOPS/3105194

    系统SLA和监控流程:http://www.doc88.com/p-9082091179407.html

    Requests and limits setting for local ephemeral storage(local ephemeral storage的request和limit设置)

    Pod的每个容器可指定以下一个或多个:

    • spec.containers[].resources.limits.ephemeral-storage
    • spec.containers[].resources.requests.ephemeral-storage

    ephemeral-storage 的request和limit以字节为单位。可使用整数或定点整数来表示内存,并使用如下后缀之一:E、P、T、G、M、K。也可使用:Ei,Pi,Ti ,Gi,Mi,Ki。 例如,以下代表大致相同的值:

    1. 128974848, 129e6, 129M, 123Mi

    例如,以下Pod有两个容器。每个容器有一个2GiB的local ephemeral storage的request。每个容器的local ephemeral storage的limit是4GiB。因此,Pod有4GiB的local ephemeral storage的request,limit为8GiB。

    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. ephemeral-storage: "2Gi"
    12. limits:
    13. ephemeral-storage: "4Gi"
    14. - name: wp
    15. image: wordpress
    16. resources:
    17. requests:
    18. ephemeral-storage: "2Gi"
    19. limits:
    20. ephemeral-storage: "4Gi"

    How Pods with ephemeral-storage requests are scheduled(如何调度设置了ephemeral-storage request的Pod)

    当您创建一个Pod时,Kubernetes Scheduler将为Pod选择一个Node。每个Node具有能够为Pod提供的local ephemeral storage最大量值。(有关详细信息,请参见 “Node Allocatable” 。Scheduler确保调度的容器的资源需求总和小于Node的容量。

    How Pods with ephemeral-storage limits run(如何运行设置了ephemeral-storage limit的Pod)

    对于容器级别的隔离,如果容器可写层和日志的使用超出其存储限制,则该Pod将被驱逐。对于Pod级别的隔离,如果所有容器的local ephemeral storage使用量的综合超过限制,则Pod将被驱逐,同理,Pod的EmptyDir也是如此。

    Opaque integer resources (alpha feature) (不透明的整数资源(alpha特征))

    废弃通知:Kubernetes v1.8 开始,该特性已被 deprecated 。

    既已废弃,就没有翻译的必要了。多抱半小时老婆吧。该功能的替代品是Extended Resources。

    Extended Resources(扩展资源)

    Kubernetes 1.8版引入了Extended Resources。Extended Resources是 kubernetes.io 域名之外的完全资格的资源名称。Extended Resources允许集群运营商发布新的Node级别的资源,否则系统将无法识别这些资源。 Extended Resources数量必须是整数,不能过大。

    用户可像CPU和内存一样使用Pod spec中的Extended Resources。 Scheduler负责资源计算,以便分配给Pod的资源部超过可用的资源量。

    API Server将Extended Resources的数量限制为整数,例如 3Ki3Ki 是有效的,0.51500m 是无效的。

    注意:扩展资源替代 Opaque Integer Resources 。 用户可使用 kubernetes.io/ 域名之外的任何域名前缀,而非以前的 pod.alpha.kubernetes.io/opaque-int-resource- 前缀。

    使用Extended Resources需要两步。首先,集群操作员必须在一个或多个Node上发布per-node Extended Resource。第二,用户必须在Pod中请求Extended Resource。

    要发布新的Extended Resource,集群操作员应向API Server提交 PATCH HTTP请求,从而指定集群中Node的 status.capacity 。在此操作之后,Node的 status.capacity 将包含一个新的资源。 status.allocatable 字段由kubelet异步地使用新资源自动更新。请注意,由于Scheduler在评估Pod适应度时,会使用Node的status.allocatable值,所以在 使用新资源PATCH到Node容量 和 第一个Pod请求该Node上资源 之间可能会有短暂的延迟。

    示例:

    如下是一个示例,显示如何使用 curl 构建一个HTTP请求,该请求在Node k8s-node-1 (Master是k8s-master )上发布了5个“example.com/foo”资源。

    1. curl --header "Content-Type: application/json-patch+json" \
    2. --request PATCH \
    3. --data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5"}]' \
    4. http://k8s-master:8080/api/v1/nodes/k8s-node-1/status

    注意 :在上述请求中, ~1 是PATCH路径中字符 / 的编码。 JSON-Patch中的操作路径值被拦截为JSON指针。 有关更多详细信息,请参阅 IETF RFC 6901, section 3 。

    要在Pod中使用Extended Resource,请将资源名称作为 spec.containers[].resources.requests map中key。

    注意:Extended resources不能提交过大的值,因此如果request和limit都存在于容器spec中,则两者必须相等。

    TODO:这是什么意思?

    只有当所有资源的request都满足时(包括cpu、内存和任何Extended Resources),Pod才会被调度。只要资源的request无法被任何Node满足,Pod将保持在 PENDING 状态。

    示例:

    下面的Pod有如下request:2 cpus和1“example.com/foo”(extended resource)。

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: my-pod
    5. spec:
    6. containers:
    7. - name: my-container
    8. image: myimage
    9. resources:
    10. requests:
    11. cpu: 2
    12. example.com/foo: 1

    Planned Improvements(计划改进)

    Kubernetes 1.5仅允许在容器上指定资源量。计划对Pod中所有容器共享资源的计费进行改进,例如 emptyDir volumes 。

    Kubernetes 1.5仅支持容器级别的CPU/内存的request/limit。 计划添加新的资源类型,包括node disk space resource和用于添加自定义 resource types 的框架。

    Kubernetes通过支持多层的 Quality of Service 支持overcommitment of resources。

    overcommitment of resources:笔者理解就是资源超售。

    Quality of Service在部分K8s文档上也被简写成QoS。

    在Kubernetes 1.5中,对于不同云提供商,或对于同一个云提供商中的不同机器类型,一个CPU单位表达的是不同的意思。 例如,在AWS上,Node的容量在 ECUs 中报告,而在GCE中报告为逻辑内核。我们计划修改cpu资源的定义,从而使得在提供商和平台之间更一致。

    What’s next

    • 掌握 assigning Memory resources to containers and pods 的实践经验。
    • 掌握 assigning CPU resources to containers and pods 的实践经验。
    • Container
    • ResourceRequirements

    原文

    https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/