深入了解Kubernetes资源类型

作者:Erwin Daria    编译:沈建苗

在我们深入了解Kubernetes资源之前,不妨先阐述一下“资源”一词在这里指什么。我们在Kubernetes集群中创建的任何东西都被视为资源:部署(deployment)、pod和服务等。我们在本文中侧重介绍CPU和内存等主要资源,以及暂态存储和扩展资源等其他资源类型。

集群管理的一个方面是将这些资源自动分配给在pod中运行的容器,那样在理想情况下,每个容器都有它所需的资源,不多也不少。

本文侧重介绍集群上运行的容器的逻辑资源。开发人员每天处理的常见Kubernetes资源分这四种:CPU、内存、暂态存储和扩展资源。针对每种资源,我们将介绍如何在Kubernetes中衡量它、介绍如何监控每种特定资源,并强调优化资源使用的一些最佳实践。

不妨深入探讨每一种主要的Kubernetes资源类型。

CPU

Kubernetes集群通常运行在多台机器上,每台机器都有多个CPU核心,组合起来就是可用核心的总数,比如4台机器乘以4个核心,核心总数为16个。

我们不需要使用全部数量的核心。我们可以以1/1000的增量指定CPU核心的任何部分(比如,半个核心或500毫核CPU)。

Kubernetes容器在Linux内核上运行,因此可以指定cGroup以限制资源。Linux调度程序将使用的CPU时间(由内部时间片定义)与设定的限制进行比较,以决定是否在下一个时间片中运行容器。我们可以使用kubectl top命令来查询CPU资源,为pod或节点调用它。

我们可以通过改进算法和编码,或者通过编译器优化,使程序在容器中运行起来更高效,从而优化处理器时间的使用。集群用户对预编译容器的速度或效率并没有太大影响。

内存

Kubernetes集群中的机器也都有内存,加起来就是集群内存总数。比如说,4台机器乘以32GiB就是128GiB。

内核级控制主内存,类似使用cGroup控制CPU时间。如果容器中的例程请求的内存分配量超出硬性限制,就会显示内存不足错误。

优化资源使用在很大程度上取决于应用程序的开发工作。一个步骤是提高垃圾收集频率,以防止基于堆的镜像分配的内存超过硬性限制。同样,kubectl top命令可以提供有关内存使用的信息。

探究CPU和内存

作为第一个深入研究的示例,不妨将流行Web服务器NGINX的三个复制容器部署到本地安装的Kubernetes系统中。我们在只有两个核心和2 GiB内存的笔记本电脑上运行单节点“集群”。

下面的代码定义了这种pod部署,并将十分之一的核心(100毫核CPU)和100 MiB的主内存分配给三个NGINX容器中的每一个。下面的代码还将它们的使用限制为请求值的两倍。

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
 app: nginx
spec:
 replicas: 3
 selector:
 matchLabels:
 app: nginx
 template:
 metadata:
 labels:
 app: nginx
spec:
 containers:
 - name: nginx
 image: nginx
 resources:
 requests:
 cpu: "100m"
 memory: "100Mi"
 limits:
 cpu: "200m"
 memory: "200Mi"
 ports:
 - containerPort: 80

我们可以部署到默认命名空间,就像这样:

kubectl apply -f nginx.yaml

本地集群只有一个节点。使用该命令返回有关它的详细信息:

kubectl describe nodes docker-desktop

在忽略大部分输出内容后,我们可以检查有关资源使用的一些信息:

[...]

Namespace Name CPU. Requests CPU Limits Memory Requests Memory Limits Age

--------- ---- ------------ ---------- --------------- ------------- ---

default nginx-deployment-585bd9cc5f-djql8 100m (5%) 200m (10%) 100Mi (5%) 200Mi (10%) 66s

default nginx-deployment-585bd9cc5f-gz98r 100m (5%) 200m (10%) 100Mi (5%) 200Mi (10%) 66s

default nginx-deployment-585bd9cc5f-vmdnc 100m (5%) 200m (10%) 100Mi (5%) 200Mi (10%) 66s

[...]

Resource Requests Limits

-------- -------- ------

cpu 1150m (57%) 600m (30%)

memory 540Mi (28%) 940Mi (49%)

ephemeral-storage 0 (0%) 0 (0%)

hugepages-1Gi 0 (0%) 0 (0%)

hugepages-2Mi 0 (0%) 0 (0%)

[...]

该信息显示CPU和内存使用请求和限制,就像我们的部署对象指定的那样。它还将值显示为最大分配量的百分比。

接下来是该节点的当前总数,再次以绝对值和百分比列出来。这些数字包括在kube-system命名空间中运行的其他一些容器,这里没有显示出来。

上述代码片段的最后三行表示CPU和内存之外的其他类型的资源,该示例中这些资源没有设置请求或限制。

暂态存储

另外一种Kubernetes资源类型是暂态存储。这是在pod生命周期结束后不会存活的挂载存储。Kubernetes经常使用暂态存储来缓存或日志,但从不将其用于重要数据,比如用户记录。我们可以像对待主内存那样请求或限制暂态存储,但它常常不是同样受限制的资源。

那么,在上面的代码片段中,hugepages-1Gi和hugepages-2Mi是什么意思呢?巨页面是Linux内核的一种现代内存功能,用于为进程分配大小可配置的大型主内存页。我们可以这么做以提高效率。

Kubernetes支持将如此大的内存页分配给容器。这些构成了视页大小而定的资源类型,我们可以单独请求页大小。

在指定请求或限制时,我们设置的是内存总量,而不是页数。

limits:
hugepages-2Mi: "100Mi"
hugepages-1Gi: "2Gi"Here, we limit the number of 2 MiB pages to 50 and the number of 1 GiB pages to 2.

扩展资源

集群用户还可以使用扩展资源类型来定义自己的资源类型(按照集群或节点)。一旦我们定义了类型,并指定了可用单元,就可以使用请求和限制,就像我们使用的内置资源一样。

比如:

limits:
cpu: "200m"
myproject.com/handles: 100

该设置将容器限制为一个核心的20%和我们项目的100个句柄。

资源请求和限制

注意,资源请求和限制是我们讨论的暂态存储和扩展资源的关键。这是由于最终用户可以在应用程序的部署清单中指定资源请求和限制,该清单对Kubernetes应如何处理容器或pod明确了一些规则。

请求表明了容器应该拥有多少资源。它们帮助调度程序根据请求的资源量和那些节点上的可用资源,将pod分配给节点。

限制用于表明对容器可以使用多少资源设置了硬性上限,在操作系统层面执行。请求和限制是可选的,但如果我们不指定限制,容器可以使用节点的大部分资源,这可能会带来负面的成本或性能影响。因此,我们须谨慎行事。

请记住:虽然一个pod可能包含多个容器,但通常每个pod只有一个容器。我们将资源分配给容器,但pod的所有容器耗用节点层面的公共资源池。

考虑服务质量

到目前为止我们描述的资源系统是管理计算资源的一种相当简单的方法。Kubernetes还提供了简单的服务质量(QoS)系统。

QoS描述了技术系统在硬件有限的情况下,在保持最佳总体质量的同时提供不同服务级别的方法。Kubernetes QoS系统为pod分配三个级别中的一个:有保证(Guaranteed)、突发式(Burstable)和尽力(BestEffort)。参阅Kubernetes说明文档(https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/),了解如何分配这些级别及它们如何影响pod调度。

在pod的生命周期内,Guaranteed级别提供了请求和限制的资源,不多也不少,适合在恒定负载下运行的监控系统等应用。

Burstable服务级别适合基本使用模式的pod:由于需求增加,这些pod使用的资源有时超过基准。这个级别非常适合数据库或Web服务器,它们的负载取决于入站请求的数量。

最后,BestEffort并不保证资源可用性。因此,它最适合批处理作业之类需要时可以重复的应用,或者非任务关键型的暂存环境。

结论

Kubernetes集群维护CPU时间、内存、暂态存储和扩展资源等硬件资源,并将它们分配给运行中的容器。借助请求和限制体系,运维人员可以根据单个容器定制资源分配,然后让Kubernetes系统将它们适当地分配给节点。

扩展资源使我们能够定义自己的资源类型,并以类似的方式使用它们。Kubernetes还根据请求和限制,为pod分配服务质量级别。然后,它使用这些级别做出调度和终止决策。

Kubernetes资源优化对于兼顾成本和最终用户体验至关重要。不过要注意的是,使用本文的方法手动分配参数可能费时、费钱又难以扩展。

参考链接:https://thenewstack.io/understanding-kubernetes-resource-types/

K8S中文社区微信公众号

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址