<p>当您定义<ahref="http://kubernetes.io/docks/user-guide/pods"target="_blank">Pod</a>的时候可以选择为每个容器指定需要的 CPU 和内存(RAM)大小。当为容器指定了资源请求后,调度器就能够更好的判断出将容器调度到哪个节点上。如果您还为容器指定了资源限制,节点上的资源就可以按照指定的方式做竞争。关于资源请求和限制的不同点和更多资料请参考<ahref="https://git.k8s.io/community/contributors/design-proposals/resource-qos.md"target="_blank">Resource QoS</a>。</p>
<p>CPU和内存统称为<em>计算资源</em>,也可以称为<em>资源</em>。计算资源的数量是可以被请求、分配和消耗的可测量的。它们与<ahref="https://kubernetes.io/docks/api/"target="_blank">API 资源</a>不同。 API 资源(如 Pod 和<ahref="https://kubernetes.io/docks/user-guide/services"target="_blank">Service</a>)是可通过 Kubernetes API server 读取和修改的对象。</p>
<p>尽管只能在个别容器上指定请求和限制,但是我们可以方便地计算出 Pod 资源请求和限制。特定资源类型的Pod 资源请求/限制是 Pod 中每个容器的该类型的资源请求/限制的总和。</p>
<p>CPU 总是要用绝对数量,不可以使用相对数量;0.1 的 CPU 在单核、双核、48核的机器中的意义是一样的。</p>
<p>以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(2<sup>26</sup>字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。您可以说该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。</p>
<h2id="具有资源请求的-pod-如何调度">具有资源请求的 Pod 如何调度</h2>
<p>当您创建一个 Pod 时,Kubernetes 调度程序将为 Pod 选择一个节点。每个节点具有每种资源类型的最大容量:可为 Pod 提供的 CPU 和内存量。调度程序确保对于每种资源类型,调度的容器的资源请求的总和小于节点的容量。请注意,尽管节点上的实际内存或 CPU 资源使用量非常低,但如果容量检查失败,则调度程序仍然拒绝在该节点上放置 Pod。当资源使用量稍后增加时,例如在请求率的每日峰值期间,这可以防止节点上的资源短缺。</p>
<h2id="具有资源限制的-pod-如何运行">具有资源限制的 Pod 如何运行</h2>
<p>当 kubelet 启动一个 Pod 的容器时,它会将 CPU 和内存限制传递到容器运行时。</p>
<p>如果一个容器超过其内存请求,那么当节点内存不足时,它的 Pod 可能被逐出。</p>
<p>容器可能被允许也可能不被允许超过其 CPU 限制时间。但是,由于 CPU 使用率过高,不会被杀死。</p>
<p>Pod 的资源使用情况被报告为 Pod 状态的一部分。</p>
<p>如果为集群配置了<ahref="http://releases.k8s.io//cluster/addons/cluster-monitoring/README.md"target="_blank">可选监控</a>,则可以从监控系统检索 Pod 资源的使用情况。</p>
<h3id="我的-pod-处于-pending-状态且事件信息显示-failedscheduling">我的 Pod 处于 pending 状态且事件信息显示 failedScheduling</h3>
<p>如果调度器找不到任何该 Pod 可以匹配的节点,则该 Pod 将保持不可调度状态,直到找到一个可以被调度到的位置。每当调度器找不到 Pod 可以调度的地方时,会产生一个事件,如下所示:</p>
<pre><codeclass="lang-shell">$ kubectl describe pod frontend | grep -A 3 Events
Events:
FirstSeen LastSeen Count From Subobject PathReason Message
36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
</code></pre>
<p>在上述示例中,由于节点上的 CPU 资源不足,名为“frontend”的 Pod 将无法调度。由于内存不足(PodExceedsFreeMemory),类似的错误消息也可能会导致失败。一般来说,如果有这种类型的消息而处于 pending 状态,您可以尝试如下几件事情:</p>
<p>您的容器可能因为资源枯竭而被终结了。要查看容器是否因为遇到资源限制而被杀死,请在相关的 Pod 上调用<code>kubectl describe pod</code>:</p>
<pre><codeclass="lang-shell">[12:54:41] $ kubectl describe pod simmemleak-hra99
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
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
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
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
</code></pre>
<p>在上面的例子中,<code>Restart Count: 5</code>意味着 Pod 中的<code>simmemleak</code>容器被终止并重启了五次。</p>
<p>您可以使用<code>kubectl get pod</code>命令加上<code>-o go-template=...</code>选项来获取之前终止容器的状态。</p>
<pre><codeclass="lang-Shell">[13:59:01] $ kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc
<p>您可以看到容器因为<code>reason:OOM killed</code>被终止,<code>OOM</code>表示 Out Of Memory。</p>
<p>用户可以在 Pod 的 spec 中消费这些资源,就像 CPU 和内存一样。调度器负责资源计量,以便在不超过可用量的同时分配给 Pod。</p>
<p>不透明整型资源是以<code>pod.alpha.kubernetes.io/opaque-int-resource-</code>为前缀的资源。API server 将限制这些资源的数量为整数。<em>有效</em>数量的例子有<code>3</code>、<code>3000m</code>和<code>3Ki</code>。<em>无效</em>数量的例子有<code>0.5</code>和<code>1500m</code>。</p>
<p>申请使用不透明整型资源需要两步。首先,集群运维人员必须在一个或多个节点上通告每个节点不透明的资源。然后,用户必须在 Pod 中请求不透明资源。</p>
<p>要发布新的不透明整型资源,集群运维人员应向 API server 提交<code>PATCH</code> HTTP请求,以指定集群中节点的<code>status.capacity</code>的可用数量。在此操作之后,节点的<code>status.capacity</code>将包括一个新的资源。<code>status.allocatable</code>字段由 kubelet 异步地使用新资源自动更新。请注意,由于调度器在评估 Pod 适应度时使用节点<code>status.allocatable</code>值,所以在使用新资源修补节点容量和请求在该节点上调度资源的第一个 pod 之间可能会有短暂的延迟。</p>
<p>在 kubernetes 1.5 版本中,一个 CPU 单位在不同的云提供商和同一云提供商的不同机器类型中的意味都不同。例如,在 AWS 上,节点的容量报告为<ahref="http://aws.amazon.com/ec2/faqs/"target="_blank">ECU</a>,而在 GCE 中报告为逻辑内核。我们计划修改 cpu 资源的定义,以便在不同的提供商和平台之间保持一致。</p>
<footerclass="page-footer-ex"><spanclass="page-footer-ex-copyright">© All Rights Reserved </span>          <spanclass="page-footer-ex-footer-update"> updated 2017-09-08 11:16:36 </span></footer>