容器资源自愈-深入了解其益处和最佳实践 (容器资源限制)
前言
容器作为一种新的资源类型,已经应用于各大公司,G行也不例外。容器的轻量化特性使得它能够在故障发生时快速进行重建,将对业务的影响降到最低,我们通常称它为自愈。容器自愈本质
谈到容器自愈,为什么说是通过Pod自愈实现的呢?Pod是一组(一个或多个)容器,这些容器共享Pod的存储、网络、以及运行容器的声明。且Pod是K8s(即Kubernetes)的最小部署管理计算单元。 当K8s判定Pod出现问题且需要被杀死的时候,会在运转正常且资源充足的Node节点重建完成,从而完成自愈。Pod状态判定
应用程序可能因多种原因而变得不可靠,例如:暂时失联、配置错误、应用程序错误、硬件故障、资源紧张等。那么如何检测运行着应用程序的pod健康状态是好还是坏呢,K8s是通过探针来检查的,探针有三种:ReadinessProbe、StartupProbe及LivenessProbe。- ReadinessProbe(就绪)探针:用于判断容器服务是否可用(即是否为ready状态),只有Ready状态的Pod才可以接收服务请求。
- StartupProbe(启动)探针:适用于应用程序启动缓慢、网络访问延迟等场景,相应造成容器启动缓慢的情况。
- LivenessProbe(存活)探针:用于判断容器是否存活①(即是否为running状态),如果探针检测到容器不健康,则Kubelet将杀死这个容器,并根据容器的重启策略(重启策略后面会说)做相应的处理。
![容器](https://tyye.cn/zb_users/theme/tpure/style/images/lazyload.png)
- HTTPGetAction通过容器的IP地址、端口号及路径调用httpget方法,如果相应的状态码大于等于200且小于400,则认定容器是健康状态。
- TCPSocketAction通过容器的IP地址和端口号执行tcp检查,如果能够建立tcp连接,则表明容器健康。
- ExecAction在容器内部运行一个命令,如果返回码为0,则表示容器健康,否则表示不健康。
Pod重启策略
知道如何检查Pod的健康状态了,如果不健康,该如何进行重启呢?这里就需要说到Pod的重启策略(restartPolicy)了。重启策略应用于Pod内的所有容器,由Pod所处的Node上的Kubelet进行判断和重启操作。 当某个容器异常退出或者健康检查失败时,Kubelet会根据重启策略的设置来决定是否重启容器。以下为三种重启策略:- Always:无论容器退出是否异常,都会重新启动容器。
- OnFailure:只有当容器异常退出时,才会重新启动容器。
- Never:容器退出后不会重新启动。
G行定制化重启策略
对于不同的重启资源需求,G行实现了自己的定制化重启策略,支持以下功能:- 支持容器级重启策略,使Pod的重启策略可以针对不同的容器指定不同的值。
- 支持根据容器的退出状态码进行重启,例如只重启因内存不足而被杀死的容器。
- 支持根据容器的健康状态进行重启,例如只重启健康检查失败的容器。
总结
容器自愈机制是K8s的一项重要功能,它可以确保容器在故障发生时快速恢复,从而提高系统的可用性和稳定性。本文详细介绍了容器自愈的实现原理、Pod状态判定、重启策略以及G行定制化重启策略,希望能对读者理解容器自愈机制有所帮助。Kubectl scale 命令最佳实践
云和安全管理服务专家新钛云服 祝祥翻译
kubectl scale是帮助我们管理 Kubernetes 部署的众多工具之一。在本文中我们将 了解如何使用此工具以及最佳使用实践 。
kubectl scale 命令通过调整正在运行的容器的数量来立即缩放应用程序。这是增加部署副本数量的最快、最简单的方法,可用于应对服务高峰以及日常维护变更。
在本文中, 我们将了解如何使用 kubectl scale来 扩展一个简单的 Kubernetes Deployment ,同时,我们还将更深入的了解该命令相关的各种参数。最终形成 kubectl scale 的最佳实践,以及一些用于调整 Kubernetes 副`本数的替代方法 。
kubectl scale 用于更改Kubernetes deployment, replica set, replication controller和 statefulset 等对象的副本数码。当我们增加副本数时,Kubernetes将启动新的Pod来扩我们的服务。降低副本数将导致 Kubernetes 优雅地终止一些 pod,从而释放集群资源。
我们可以运行 kubectl scale 来手动调整应用程序的副本数,以响应不断变化的服务容量需求。增加的流量负载可以通过增加副本数来处理,提供更多的应用程序实例来服务用户流量。当业务突发降低的时候,可以减少副本的数量。这有助于通过避免使用不需要的资源来降低成本。
kubectl scale 最基本的用法是这样的:
执行此命令将调整名为demo-deployment 的部署,使其拥有三个正在运行的副本。我们可以通过替换其名称而不是部署来定位不同类型的资源:
现在我们将看一个使用 kubectl scale 扩展部署的完整示例。这是一个定义简单部署的 YAML 文件:
将此 YAML 保存到工作目录中的 。接下来,使用kubectl将部署添加到我们的集群:
现在运行 kubectl get pods 命令来查看已为部署创建的 pod:
单个副本不足以用于生产应用程序。如果托管 pod 的节点出于任何原因离线,我们可能会遇到停机时间。使用 kubectl scale 增加副本数以提供更多空间:
重复 kubectl get pods 命令以确认部署已成功扩容:
现在有五个 Pod 正在运行。从AGE列可以看到scale命令保留了原来的 pod 并新增了 4 个。
经过进一步思考,我们可能会决定此应用程序不需要五个副本。它只运行一个静态 NGINX Web 服务器,因此每个用户请求的资源消耗应该很低。再次使用scale命令来降低副本数并避免浪费集群容量:
重复 kubectl get pods 命令:
Kubernetes 已将两个正在运行的 pod 标记为终止。这会将正在运行的副本计数减少到请求的三个 pod。选择要驱逐的 pod 会被发送一个SIGTERM(信号并允许优雅地终止(。停止后,它们将从 pod 列表中删除。
有时我们可能想要扩展资源,但前提是已经有特定数量的副本在运行。这可以避免意外覆盖以前的副本,例如集群中其他用户所做的更改。
在命令中包含 --current-replicas 标志可以达到效果:
此示例将展示deployment扩展到五个副本,但前提是当前有三个副本正在运行。 --current -replicas 值始终完全匹配;我们不能将条件表示为“小于”或“大于”特定计数。
当我们提供多个名称作为参数时,kubectl scale 命令可以一次缩放多个资源。每个资源都将缩放到由 --replicas 标志设置的相同副本计数。
此命令将应用程序和数据库deployment扩展到每个五个副本。
我们可以通过提供 --all 标志来扩展特定类型的每个资源,例如此示例以扩展默认命名空间中的所有部署:
这会选择当前活动命名空间内的每个匹配资源。缩放的对象显示在命令的输出中。
我们可以对使用 --selector 标志缩放的对象进行精细控制。这我们可以使用标准选择语法根据对象的标签(过滤对象。这是一个使用 app-name=demo-app 标签扩展所有部署的示例:
--timeout 标志设置 Kubectl 在放弃缩放操作之前将等待的时间。默认情况下,没有等待期。该标志接受可读的时间值,例如5m或1h:
如果无法立即完成缩放更改,这可以让我们避免长时间的终端挂起。尽管 kubectl scale 是一个命令式命令,但在将新 pod 调度到节点时,对缩放的更改有时可能需要几分钟才能完成。
使用 kubectl scale 通常是扩展工作负载的最快、最可靠的方法。但是,为了安全操作,需要记住一些最佳实践。如下所示:
首先将 字段更改为我们所需的新副本数:
现在对修改后的文件重复 kubectl apply 命令:
kubectl scale 的另一个替代方案是 Kubernetes 对自动缩放的支持。配置此机制允许 Kubernetes 根据 CPU 使用率和网络活动等指标在配置的最小值和最大值之间自动调整副本计数。
kubectl scale命令是扩展 Kubernetes deployments, replica sets, replication controllers以及stateful sets的通用方式。它在每次调用时以一个或多个对象为目标,并对其进行缩放,以便运行指定数量的 pod。
我们可以选择设置条件,因此只有在存在特定数量的现有副本时才会更改比例,从而避免在错误方向上意外调整大小。
同时我们也希望能够遵循一些本文所提到的最佳时实践,从而平稳,可靠的实现资源的扩缩容。
*原文:
了解Kubernetes资源类型
在深入研究Kubernetes资源之前,让我们先澄清一下“资源”一词在这里指的是什么。我们在Kubernetes集群中创建的任何东西都被视为一种资源:部署、pod、服务等。在本文中,我们将重点介绍CPU和内存等主要资源,以及暂态存储和扩展资源等其他资源类型。
集群管理的一个方面是将这些资源自动分配给在pod中运行的容器,这样,理想情况下,每个容器都有它所需的资源(但没有更多)。
在本文中,我们将重点介绍集群上运行的容器的逻辑资源。我们将分析开发人员每天使用的四种常见Kubernetes资源:CPU、内存、暂态存储和扩展资源。对于每种资源,我们将 探索 如何在Kubernetes中衡量它,回顾如何监控每种特定资源,并强调优化资源使用的一些最佳实践。
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
name: nginx-deployment
replicas: 3
matchLabels:
containers:
- name: nginx
image: nginx
resources:
memory: 100Mi
memory: 200Mi
- containerPort: 80
我们可以这样部署到默认命名空间:
kubectl apply -f
本地集群只有一个节点。使用此命令可返回有关它的详细信息:
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支持将如此大的页面分配给容器。这些构成了我们可以单独请求的每个页面大小的资源类型。
在指定请求或限制时,我们设置的是内存总量,而不是页数。
hugepages-2Mi: 100Mi
hugepages-1Gi: 2GiHere, we limit the number of 2 MiB pages to 50 and the number of 1 GiB pages to 2.
扩展资源
集群用户还可以使用扩展资源类型定义自己的资源类型(每个集群或节点)。一旦定义了类型并指定了可用单元,我们就可以使用请求和限制,就像我们目前使用的内置资源一样。
例如:
/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资源优化对于平衡成本和最终用户体验至关重要。然而,使用本文的方法手动分配参数可能会非常耗时、昂贵,而且难以扩展。
原文链接:
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。