管理容器资源

当你指定圆荚体,您可以选择指定每个资源a的多少容器的需求。最常用的资源是CPU和内存(RAM);有别人。

指定资源时请求对于Pod中的容器,调度器使用此信息来决定将Pod放置在哪个节点上。指定资源时限度对于容器,kubelet强制执行这些限制,以便不允许运行的容器使用超过您设置的限制的资源。库贝雷也至少保留了请求特定于该容器要使用的系统资源的数量。

要求和限制

如果运行Pod的节点有足够的可用资源,则容器可以(也允许)使用比其更多的资源请求为该资源指定。但是,容器不能使用超过其资源的资源限度

例如,如果你设置内存对于一个容器,如果该容器处于一个调度到一个节点的Pod中,该节点的内存为8GiB,没有其他Pod,那么容器可以尝试使用更多的RAM。

如果你设置内存限制该容器的4GiB, kubelet(和容器运行时)执行限制。运行时阻止容器使用超过配置的资源限制。例如:当容器中的进程试图消耗超过允许的内存量时,系统内核将终止尝试分配的进程,并出现内存不足(OOM)错误。

限制可以是被动实现的(系统一旦看到违规就会进行干预),也可以是强制实现的(系统防止容器超过限制)。不同的运行时可以以不同的方式实现相同的限制。

资源类型

中央处理器内存都是一个资源类型.资源类型有一个基本单元。CPU表示计算处理,单位为Kubernetes cpu. 内存是以字节为单位指定的。如果您使用的是Kubernetes v1.14或更新版本,则可以指定巨大的页面资源。大页面是特定于linux的特性,节点内核分配的内存块比默认页面大小大得多。

例如,在一个默认页面大小为4KiB的系统上,您可以指定一个限制,hugepages-2Mi: 80米. 如果容器尝试分配超过40个2MiB的巨大页面(总共80个MiB),则分配失败。

CPU和内存统称为计算资源,或资源.计算资源是可以请求、分配和消耗的可度量的数量。它们不同于API参考资料.API资源,如Pods和服务是可以通过Kubernetes API服务器读取和修改的对象。

Pod和Container的资源请求和限制

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

  • spec.containers [] .resources.limits.cpu
  • spec.containers [] .resources.limits.memory
  • spec.containers [] .resources.limits.hugepages——<大小>
  • spec.containers[].resources.requests.cpu
  • spec.containers [] .resources.requests.memory
  • spec.containers[].resources.requests.hugepages-

尽管请求和限制只能在单个容器上指定,但是讨论Pod资源请求和限制是很方便的。一个豆荚资源请求/限制对于特定的资源类型,是Pod中每个容器的资源请求/限制的总和。

Kubernetes的资源单位

CPU的意义

CPU资源的限制和请求以cpu单位。一个cpu,在Kubernetes中,相当于1个vCPU/芯对于云提供商和1 hyperthread在裸金属英特尔处理器上。

允许部分请求。装有spec.containers[].resources.requests.cpu属于0.5保证的CPU数量是请求1个CPU的一半。表达式0.1等于表达式100米,可以理解为“100毫普”。有些人说“100毫微粒”,这被理解为是同一个意思。一个带小数点的请求,比如0.1,转换为100米通过API,精度优于1米是不允许的。为此,表单100米可能是首选。

CPU总是作为绝对量而不是相对量被请求;0.1是单核、双核或48核机器上相同数量的CPU。

记忆的意义

限制和要求内存以字节为单位。你可以用一个普通的整数或者一个固定的数字来表达记忆,用这些后缀:E, P, T, G, M, k。你也可以用等价的2的幂:Ei, Pi, Ti, Gi, Mi, Ki。例如,以下表示大致相同的值:

128974848, 129e6, 129M, 123Mi

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

apiVersionv1种类圆荚体元数据的名字前端规范容器-的名字应用程序形象images.my company.example/app:v4资源请求内存“64米”cpu“250”限制内存“128米”cpu“500”-的名字日志聚合器形象images.my-company.example / log-aggregator: v6资源请求内存“64米”cpu“250”限制内存“128米”cpu“500”

如何调度带有资源请求的Pods

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

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

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

使用Docker时:

  • spec.containers[].resources.requests.cpu转换为其核心值(可能是分数),然后乘以1024。此数字或2中的较大值用作——cpu配额国旗的码头工人赛跑命令。

  • spec.containers [] .resources.limits.cpu转换为其millicore值并乘以100。所得值是容器每100ms可以使用的CPU时间总量(以微秒为单位)。在此间隔内,容器不能使用超过其CPU时间份额的时间。

  • spec.containers [] .resources.limits.memory转换为整数,并用作——记忆国旗的码头工人赛跑命令。

如果容器超出其内存限制,则可能终止该容器。如果它是可重新启动的,kubelet将重新启动它,就像处理任何其他类型的运行时故障一样。

如果容器超出了它的内存请求,那么每当节点耗尽内存时,它的Pod很可能会被逐出。

容器可能被允许,也可能不被允许在较长时间内超过其CPU限制。但是,它不会因为CPU占用过多而被杀死。

要确定是否无法调度容器或由于资源限制而终止容器,请参阅故障排除部分

监控计算和内存资源使用情况

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

如果可选监控工具,则Pod资源使用情况可以从度量API直接或从您的监控工具。

本地临时存储

功能状态: Kubernetes v1.10(β)

节点具有本地临时存储,由本地连接的可写设备支持,有时也由RAM支持。“转瞬即逝”意味着没有关于耐久性的长期保证。

POD使用临时本地存储来存储临时空间、缓存和日志。kubelet可以使用本地临时存储为POD提供临时空间来装载emptyDir进入容器。

kubelet也用这种储存方式来储存节点级容器日志、容器映像和运行容器的可写层。

作为一个beta特性,Kubernetes允许您跟踪、保留和限制Pod可以消耗的临时本地存储数量。

本地临时存储的配置

Kubernetes支持两种方式来配置节点上的本地临时存储:

在此配置中,您可以放置所有不同类型的临时本地数据(emptyDir卷、可写层、容器映像、日志)进入一个文件系统。配置kubelet最有效的方法是将该文件系统专用于Kubernetes (kubelet)数据。

kubelet也写节点级容器日志并将其视为短暂的本地存储。

kubelet将日志写入其配置的日志目录中的文件(/var/log默认情况下);并且具有用于其他本地存储数据的基本目录(/var/lib/kubelet默认情况下)。

通常,这两个/var/lib/kubelet/var/log位于系统根文件系统上,而kubelet的设计正是考虑到了这种布局。

您的节点可以有任意多个其他文件系统,而不用于Kubernetes。

您在节点上有一个文件系统,用于运行Pods: logs的临时数据emptyDir卷。您可以将此文件系统用于其他数据(例如:与Kubernetes无关的系统日志);它甚至可以是根文件系统。

kubelet也写节点级容器日志存储到第一个文件系统中,并将其类似于临时本地存储。

您还将使用由不同逻辑存储设备支持的独立文件系统。在这个配置中,您告诉kubelet放置容器映像层和可写层的目录位于第二个文件系统上。

第一个文件系统不包含任何图像层或可写层。

您的节点可以有任意多个其他文件系统,而不用于Kubernetes。

kubelet可以测量它正在使用多少本地存储。它这样做的前提是:

  • LocalStorageCapacityIsolation功能门是启用的(该特性在默认情况下是开启的),以及
  • 您已经使用本地临时存储支持的配置之一设置了节点。

如果您有不同的配置,那么kubelet不会对临时本地存储应用资源限制。

设置本地临时存储的请求和限制

你可以用临时性存储用于管理本地临时存储。Pod的每个容器可以指定以下一个或多个:

  • 规格容器[]。资源。限制。短期储存
  • spec.containers [] .resources.requests.ephemeral-storage

限制和要求临时性存储以字节为单位。您可以将存储空间表示为普通整数或使用以下后缀之一的定点数:E, P, T, G, M, k。您还可以使用等价的2的幂:Ei, Pi, Ti, Gi, Mi, Ki。例如,以下表示大致相同的值:

128974848, 129e6, 129M, 123Mi

在下面的示例中,Pod有两个容器。每个容器都有一个2GiB本地临时存储请求。每个容器的本地临时存储限制为4GiB。因此,Pod有4GB本地临时存储的请求,以及8GiB本地临时存储的限制。

apiVersionv1种类圆荚体元数据的名字前端规范容器-的名字应用程序形象images.my company.example/app:v4资源请求临时性存储“2 gi”限制临时性存储“4 gi”volumeMounts-的名字短暂的山径“/ tmp”-的名字日志聚合器形象images.my-company.example / log-aggregator: v6资源请求临时性存储“2 gi”限制临时性存储“4 gi”volumeMounts-的名字短暂的山径“/ tmp”-的名字短暂的emptyDir{}

如何安排具有临时存储请求的POD

当您创建Pod时,Kubernetes调度程序会为Pod选择一个运行节点。每个节点都可以为Pods提供最大数量的本地临时存储。有关更多信息,请参见节点可分配

调度程序确保调度container的资源请求之和小于节点的容量。

临时存储消耗管理

如果kubelet将本地临时存储作为资源管理,那么kubelet将在以下情况下度量存储使用情况:

  • emptyDir卷,除了tmpfsemptyDir
  • 保存节点级日志的目录
  • 可写集装箱层

如果Pod使用了比您允许的更短暂的存储,kubelet会设置一个驱逐信号来触发Pod驱逐。

对于容器级隔离,如果容器的可写层和日志使用量超过其存储限制,kubelet会将Pod标记为退出。

对于豆荚级别的隔离,kubelet通过对豆荚中容器的限制进行求和来计算出豆荚的总体存储限制。在本例中,如果所有容器和Pod的本地临时存储使用量之和emptyDir卷超过Pod的总体存储限制,然后kubelet也将Pod标记为驱逐。

kubelet支持不同的方法来衡量Pod存储的使用:

kubelet执行定期的、定时的检查来扫描每个节点emptyDir卷、容器日志目录和可写容器层。

扫描测量使用了多少空间。

功能状态: Kubernetes v1.15(α)

项目配额是一个操作系统级别的特性,用于管理文件系统上的存储使用。使用Kubernetes,您可以启用项目配额来监控存储使用情况。确保文件系统支持emptyDir节点上的卷提供了项目配额支持。例如,XFS和ext4fs提供项目配额。

Kubernetes使用项目id从1048576.正在使用的id在/etc/projects/etc/projid.如果该范围内的项目id用于系统上的其他用途,则必须在/etc/projects/etc/projid这样Kubernetes就不用它们了。

配额比目录扫描更快、更准确。当一个目录被分配给一个项目时,在该目录下创建的所有文件都会在该项目中创建,而内核只需跟踪该项目中的文件使用了多少块。
如果创建和删除了一个文件,但是它有一个打开的文件描述符,那么它将继续占用空间。配额跟踪记录准确的空间,而目录扫描忽略被删除文件使用的存储空间。

如果要使用项目配额,应:

  • 启用LocalStorageCapacityIsolationFSQuotaMonitoring=true功能门使用特征门字段库贝莱构型或者是——feature-gates命令行标志。

  • 确保根文件系统(或可选的运行时文件系统)启用了项目配额。所有XFS文件系统都支持项目配额。对于ext4文件系统,您需要在文件系统未挂载时启用项目配额跟踪特性。

    对于ext4, /dev/block-device没有挂载sudo tune2fs -O project -Q prjquota /dev/block-device . sudo tune2fs -O project
  • 确保根文件系统(或可选的运行时文件系统)在安装时启用了项目配额。对于XFS和ext4fs,将命名挂载选项prjquota

扩展的资源

扩展资源是外部的完全限定资源名称www.amasoeur.com域。它们允许集群运营商发布广告,并允许用户使用非kubernetes内置的资源。

使用扩展资源需要两个步骤。首先,集群操作符必须发布扩展资源。其次,用户必须请求pod中的扩展资源。

管理扩展的资源

节点级扩展资源

节点级扩展资源绑定到节点。

设备插件管理的资源

看到设备插件了解如何在每个节点上公布设备插件管理的资源。

其他资源

要发布一个新的节点级扩展资源,集群操作符可以提交一个色斑中指定可用数量的HTTP请求地位、能力对于集群中的一个节点。此操作后,节点的地位、能力将包括一个新的资源。的可分配状态字段由kubelet异步使用新资源自动更新。请注意,由于调度程序使用节点可分配状态值时,在用新资源修补节点容量和第一个请求在该节点上调度资源的Pod之间可能存在一个短延迟。

例子:

下面是一个示例,演示如何使用卷曲形成一个HTTP请求,在节点上播发五个“example.com/foo”资源k8s-node-1是谁的主k8s-master

旋度,头“内容类型:应用程序/ json-patch + json”——请求补丁——数据({“人事处”:“添加”,“路径”:“/地位/能力/ example.com ~ 1 foo”、“价值”:“5”}]”http://k8s-master:8080/api/v1/nodes/k8s-节点1/状态

集群级别扩展资源

集群级扩展资源不绑定到节点。它们通常由调度程序扩展程序管理,后者处理资源消耗和资源配额。

中指定由调度程序扩展程序处理的扩展资源调度策略配置

例子:

调度器策略的以下配置表明,集群级扩展资源“example.com/foo”由调度器扩展程序处理。

  • 只有当Pod请求“example.com/foo”时,调度器才向调度器扩展器发送Pod。
  • ignoredByScheduler字段指定调度程序不检查其中的“example.com/foo”资源PodFitsResources谓词。
“类型”“政策”“apiVersion”“v1”“填充剂”: [{“urlPrefix”“< extender-endpoint >”“bindVerb”“绑定”“managedResources”: [{“名称”“example.com/foo”“ignoredByScheduler”符合事实的}]}}

消耗扩展资源

用户可以使用Pod规范中的扩展资源,如CPU和内存。调度器负责对资源进行核算,以便同时分配给Pods的资源不超过可用的数量。

API服务器将扩展资源的数量限制为整数。的例子有效的量是3.3000米3吻.的例子无效的量是0.51500米

要在Pod中使用扩展资源,请将资源名作为键包含在spec.containers [] .resources.limits映射到容器规范中。

只有在满足所有资源请求(包括CPU、内存和任何扩展资源)的情况下,Pod才会被调度。花苞还在等待状态,只要资源请求不能被满足。

例子:

下面的Pod请求2个cpu和1个“example.com/foo”(一个扩展资源)。

apiVersionv1种类圆荚体元数据的名字我的豆荚规范容器-的名字我的容器形象我的形象资源请求cpu2example.com/foo1限制example.com/foo1

PID限制

进程ID (PID)限制允许kubelet的配置来限制给定Pod可以使用的PID数量。看到Pid限制获取信息。

故障排除

我的pod挂起事件消息failedScheduling

如果调度程序找不到任何可以放置Pod的节点,则Pod将保持未调度状态,直到找到位置为止。每当调度程序无法找到Pod的位置时,都会生成一个事件,如下所示:

kubectl描述荚果前端| grep -A3.事件
事件:FirstSeen LastSeen Count From subbobject PathReason Message 36s 5s 6 {scheduler} FailedScheduling失败,原因是PodExceedsFreeCPU和可能的其他原因

在前面的示例中,由于节点上的CPU资源不足,名为“前端”的Pod无法调度。类似的错误消息也可能表示由于内存不足(PodExceedsFreeMemory)而导致失败。通常,如果Pod挂起了此类消息,可以尝试以下几种方法:

  • 向集群中添加更多节点。
  • 终止不需要的pod,为挂起的pod腾出空间。
  • 检查Pod是否大于所有节点。例如,所有节点的容量为cpu: 1,然后是一个Pod,请求为cpu: 1.1永远不会被安排。

您可以查看节点的容量和分配的数量kubectl描述节点命令例如:

Kubectl描述节点e2e-test-node-pool-4lw4
名称:e2e-test-node-pool-4lw4[…为清晰起见删除的线路…]容量:cpu:2内存:76792KI吊舱:110可分配:cpu:1800m内存:747474992KI吊舱:110[…为清晰起见删除的线路…]非端接吊舱:(共5个)名称空间名称CPU请求CPU限制内存请求内存限制-------------------------kube system fluentd-gcp-v1.38-28bv1 100m(5%)0(0%)200Mi(2%)200Mi(2%)kube系统kube-dns-3297075139-61lj3 260m(13%)0(0%)100Mi(1%)170Mi(2%)kube系统kube-proxy-e2e-test-。。。100m(5%)0(0%)0(0%)0(0%)kube系统监控-XDB-grafana-v4-Z11200m(10%)200m(10%)200m(10%)600Mi(8%)600Mi(8%)kube系统节点-问题-检测器-v0.1-fj7m3 20m(1%)200m(10%)20Mi(0%)100Mi(1%)分配的资源:(总限额可能超过100%,即超额承诺。)CPU请求CPU限制内存请求内存限制---------------680m(34%)400m(20%)920Mi(11%)1070Mi(13%)

在前面的输出中,您可以看到,如果Pod请求超过1120m cpu或6.23Gi的内存,那么它将不能安装在节点上。

通过查看豆荚节中,可以看到哪些Pods占用了节点上的空间。

Pods可用的资源数量小于节点容量,因为系统守护进程使用一部分可用资源。的可分配的领域NodeStatus给出pod可用的资源量。有关更多信息,请参见节点可分配资源

资源配额特性可以配置为限制可消耗的资源总量。如果与名称空间一起使用,可以防止一个团队占用所有资源。

我的集装箱被终止了

您的容器可能会因为资源匮乏而终止。要检查容器是否因为达到资源限制而被终止,请调用库贝特吊舱在感兴趣的Pod上:

Kubectl描述pod simmemleak-hra99
名称:simmemleak-hra99命名空间:default Image(s): saadali/simmemleak Node: kubernetes-node-tf0f/10.240.216.66 Labels: Name =simmemleak Status: Running Reason: Message: IP: 10.244.2.75 Replication Controllers: simmemleak (1/1 replicas created) Containers: simmemleak: Image: saadali/simmemleak Limits: cpu: 100m memory: 50Mi State: Running Started:Tue, 07 july 2015 12:54:41 -0700 Last terminate State: Terminated Exit Code: 1 Started: friday, 07 july 2015 12:54:30 -0700 Finished: friday, 07 july 2015 12:54:33 -0700 Ready: False Restart Count: 5 Conditions: Type Status Ready False Events:FirstSeen LastSeen Count From subbobjectpath Reason Message Tue, 07 jul2015 12:53:51 -0700 Tue, 07 jul2015 12:53:51 -0700 1 {scheduler} scheduled Successfully assigned simmemleake -hra99 to kubernetes-node-tf0f Tue, 07 jul2015 12:53:51 -0700 Tue,1 {kubelet kubernetes-node-tf0f}隐式required container POD pulled POD container image "k8 .gcr.io/pause:0.8.0" already present on machine07年7月2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f}隐式地要求容器POD创建创建码头工人id 6 a41280f516d星期二,07年7月2015 12:53:51 -0700星期二,07年7月2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f}隐式地要求容器舱开始从码头工人id 6 a41280f516d星期二开始,07年7月2015 12:53:51 -0700星期二,7 7 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created使用docker id 87348f12526a创建

在上面的例子中重新启动数:5表明,simmemleak花苞中的容器被终止并重新启动了五次。

你可以叫kubectl得到豆荚- o go-template =…获取以前终止的容器状态的选项:

kubectl获得pod-o go模板{{range.status。containerStatuses}}{{“容器名称:“}}{{. Name}}{{“\ r \ nLastState:“}}{{.lastState}}{{结束}}’simmemleak-hra99
容器名称:simmemleak LastState:map[终止:map[退出代码:137原因:OOM终止开始日期:2015-07-07T20:58:43Z完成日期:2015-07-07T20:58:43Z容器ID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]

您可以看到容器被终止的原因是原因:伯父死亡,在那里伯父表示内存不足。

接下来是什么

最后修改于2021年8月05日凌晨3:38太平洋标准时间:更新资源管理以提到CPU时间的度量(9ca04a101)