在深入研究Kubernetes资源之前,让我们先澄清一下“资源”一词在这里指的是什么。我们在Kubernetes集群中创建的任何东西都被视为一种资源:部署、pod、服务等。在本文中,我们将重点介绍CPU和内存等主要资源,以及暂态存储和扩展资源等其他资源类型。
集群管理的一个方面是将这些资源自动分配给在pod中运行的容器,这样,理想情况下,每个容器都有它所需的资源(但没有更多)。
在本文中,我们将重点介绍集群上运行的容器的逻辑资源。我们将分析开发人员每天使用的四种常见Kubernetes资源:CPU、内存、暂态存储和扩展资源。对于每种资源,我们将探索如何在Kubernetes中衡量它,回顾如何监控每种特定资源,并强调优化资源使用的一些最佳实践。
CPU
Kubernetes集群通常运行在多台机器上,每台机器都有多个CPU核。它们加起来就是可用内核的总数。
我们不需要使用所有的内核。我们可以以1/1000的增量指定CPU核心的任何部分(例如,半个核心或500百万CPU)。
Kubernetes容器在Linux内核上运行,这允许指定cGroup来限制资源。Linux调度器将使用的CPU时间(由内部时间片定义)与定义的限制进行比较,以决定是否在下一个时间片中运行容器。我们可以使用kubectl top命令查询CPU资源,为pod或节点调用它。
我们可以通过改进算法和编码,或者通过编译器优化,使程序在容器中运行更加高效,从而优化处理器时间的使用。集群用户对预编译容器的速度或效率没有太大影响。
内存
Kubernetes集群中的每台机器也都有内存,加起来就是集群的总数。内核级控制主内存,类似于使用cGroup的CPU时间。如果容器中的例程请求的内存分配超出了硬限制,则表示内存不足错误。
优化资源使用在很大程度上取决于应用程序的开发工作。一个步骤是提高垃圾收集频率,以防止基于堆的镜像分配的内存超过硬限制。同样,kubectl top命令可以提供有关内存使用的信息。
探索CPU和内存
作为我们的第一个深入示例,让我们将流行web服务器NGINX的三个复制容器部署到本地Kubernetes安装中。我们在笔记本电脑上运行一个单节点“集群”,它只有两个内核和2 GiB的内存。
下面的代码定义了这种pod部署,并将十分之一的核心(100 milli-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系统命名空间中运行的一些其他容器,我们在这里没有显示这些容器,因此上面的输出中没有包含差异。
上面代码段的最后三行表示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。
在pod的生命周期内,Guaranteed级别提供了所需且有限的资源,适合在恒定负载下运行的监控系统等应用。
Burstable服务级别适用于具有基本使用模式的pod,由于需求增加,这些pod的使用模式有时会超过基线。这个级别非常适合数据库或web服务器,它们的负载取决于传入请求的数量。
BestEffort不保证资源可用性。因此,它最适合于批处理作业之类的应用程序,它们可以在需要时重复,或者适合于非任务关键型的暂存环境。
结论
Kubernetes集群维护CPU时间、内存、暂态存储和扩展资源等硬件资源,并将它们分配给正在运行的容器。通过一个请求和限制系统,运维人员可以根据单个容器定制资源分配,然后让Kubernetes系统将它们适当地分配给节点。
扩展资源使我们能够定义自己的资源类型,并以类似的方式使用它们。Kubernetes还根据请求和限制将服务质量指定给pod。然后,它使用这些名称来制定计划和终止决策。
Kubernetes资源优化对于平衡成本和最终用户体验至关重要。然而,使用本文的方法手动分配参数可能会非常耗时、昂贵,而且难以扩展。
原文链接:
https://thenewstack.io/understanding-kubernetes-resource-types/