10 Kubernetes性能技巧

强烈推介IDEA2021.1.3破解激活,IntelliJ IDEA 注册码,2021.1.3IDEA 激活码  

ubernetes是一个可扩展的高性能引擎,可以在服务器环境中协调容器。默认情况下,它是高度优化的,并且可以在合适的基础架构中很好地扩展。

默认情况下,它也不那么自以为是,并且有很多自定义项可供最终用户定义。这种灵活性使Kubernetes可以覆盖许多不同的用例并更快地进入市场,从而使其非常受欢迎。

由于服务器成本会迅速增加,因此您必须找到提高基础架构利用率并降低成本以充分利用环境的方法。在本文中,我们将为您提供10条提示,以帮助您从Kubernetes发行版中压缩效率和性能的每一点。

Kubernetes性能最佳实践

1个定义部署资源

Kubernetes大规模地编排容器,这种机制的核心是将Pod高效地调度到节点中。您实际上可以通过指定资源约束来帮助Kubernetes调度程序执行此操作。

换句话说,您可以定义请求限制资源,例如CPU,内存或Linux HugePages。

例如,假设您有一个充当电子邮件发件人服务的Java微服务,因此它主要处理网络请求。您可以分配以下资源配置文件:


resources: requests: memory: 1Gi cpu: 250m limits: memory: 2.5Gi cpu: 750m

 

如果要在Go中实现相同的应用程序,则将使用一组不同的资源约束(通常与内存相关):

resources:
   requests:
     memory: 128m
     cpu: 250m
   limits:
     memory: 1Gi
     cpu: 750m

 

那么,CPU和内存是什么意思呢?这取决于不同的提供商之间存在不同类型的CPU和不同类型的存储芯片。例如,至强CPU更适合服务器环境,而DDR4芯片具有更高的读/写吞吐量。您还可以选择对特定部署使用CPU或内存密集型节点,以便Kubernetes可以适当地安排它们。

最终,当您在部署描述符中明确定义资源需求时,调度程序可以更轻松地确保将每个资源分配给最佳可用节点,这将提高运行时性能。

2靠近客户部署集群

Kubernetes管理的群集节点的地理位置与客户端经历的延迟密切相关。

例如,托管位于欧洲Pod的节点将为该地区的客户提供更快的DNS解析时间和更短的延迟。

但是,在这里和那里生成Kubernetes集群之前,您需要设计一个谨慎的计划来处理多区域Kubernetes集群。每个提供者在可用于提供最佳故障容忍度的区域上都有限制。例如,AKS可以使用此区域列表,而GKE提供了针对多区域区域集群的选项,每个选项都有其自己的优缺点列表。

如果您发现当前流量有问题,或者为某些服务提供了优先级路由,那么从本地启动然后扩展很重要。这将使您有更多时间来确定向客户提供内容时的主要瓶颈。

3选择更好的永久存储和服务质量

就像有不同种类的CPU和内存芯片一样,也有不同种类的持久性存储硬件。例如,SSD提供比HDD更好的读/写性能,而NVMe SSD在繁重的工作负载下甚至更好。

Kubernetes 有许多不同类型的持久卷可用,它们具有很好的可扩展性,对存储的看法也较少。

一些Kubernetes提供者使用服务质量级别扩展了持久卷声明模式定义。这意味着它们优先考虑特定部署的卷读/写配额,从而在某些情况下提供更好的吞吐量。

总的来说,每个人都同意更好的硬件可以提供更好的性能,但重要的是要意识到,在大多数情况下,性能的阶数是一个常数c。因此,如果您要从SSD升级到NVMe,您会期望读/写操作的百分比有所增加,但是您不会期望网络延迟有所不同。

4配置节点关联

并非所有节点都在同一硬件上运行,也不是所有Pod都需要运行CPU密集型应用程序。Kubernetes可以通过Node AffinityPod Affinity获得节点Pod的专业化

当您拥有适合CPU密集型操作的节点时,您希望将它们与CPU密集型应用程序配对以最大程度地节省精力。为此,您可以使用具有指定标签的nodeSelector

例如,假设您有两个节点:一个节点的CPUType = HIGHCORE提供较高的CPU核心数和频率,另一个节点的MemoryType = HIGHMEMORY提供最高和最快的可用内存。

最简单的方法是在spec部分中添加以下选择器,以将POD部署发布到HIGHCORE

…
nodeSelector:
	CPUType: HIGHCORE

 

执行此操作的一种更具表达性但又特定的方法是使用spec部分中的亲和力字段的nodeAffinity。当前有两种选择:

  • requiredDuringSchedulingIgnoredDuringExecution:这是一个硬选择,调度程序将仅将Pod部署到特定节点(其他地方则没有)。
  • preferredDuringSchedulingIgnoredDuringExecution:这是一个软首选项,这意味着调度程序将尝试部署到指定的节点,如果不可行,它将尝试调度到下一个可用节点。

您可以使用特定的syndax来控制节点标签,例如In,NotIn,Exists,DoesNotExist,GtLt。但是请记住,大标签列表中的复杂谓词会减慢关键节点的决策过程。场景。换句话说,保持简单。

5配置Pod关联性

如前所述,Kubernetes允许您根据现有的运行Pod配置Pod亲和力。简而言之,您可以允许某些Pod沿着同一区域或节点群集中的其他Pod运行,以便它们之间更频繁地进行通信。

下可用字段podAffinity中的亲和力领域在规范部分是一样的药粥nodeAffinity:requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution。唯一的区别是matchExpressions会将容器分配给已经具有带有该标签的运行容器的节点。

Kubernetes还提供了一个podAntiAffinity字段,该字段与上述操作相反:它不会将Pod调度到包含特定Pod的节点中。

在这两种情况下,相同的建议都适用于nodeAffinity表达式:尝试使规则保持简单和逻辑,以减少匹配的标签(而不是数千个)。生成不匹配的规则非常容易,它将为调度程序带来更多工作,从而降低整体性能。

6配置污点

自定义Pod计划选项的功能并不止于此。当您有成千上万个Pod,标签或节点时,有时很难不允许某些Pod降落在某些节点上。

这就是污点进入的地方。污点表示不允许发生事件的规则,例如出于各种原因不允许将一组特定的节点安排到特定位置。要将异味应用于特定节点,必须在kubectl中使用taint选项。你需要指定一个键和值部分,然后像一个污点效果NoScheduleNOEXECUTE


$ kubectl taint nodes backup-node-1=backups-only:NoSchedule

有趣的是,您也可以使用公差来覆盖此行为。当您有一个受污染的节点时,这很方便,因此没有计划任何事情。现在,您只希望将备份作业安排在此处。那么您如何安排他们呢?您只需要在此处启用具有容忍度的Pod。

在此示例中,您将在Pod Spec中添加以下字段:

spec:
   tolerations:
     - key: "backup-node-1"
        operator: "Equal"
        value: "backups-only"
        effect: "NoSchedule"

 

由于此节点与受污染的节点匹配,因此具有该规范的任何Pod都可以部署在backup-node-1中。

污点和容忍度为Kubernetes管理员提供了最高级别的控制权,但是在使用它们之前,需要进行一些手动设置。

7构建优化的图像

自然,最好使用容器优化的映像,以便Kubernetes可以更快地拉动它们并更有效地运行它们。

我们所说的优化是指它们:

  • 只包含一个应用程序或做一件事。
  • 具有小图像,因为大图像在网络上不那么可移植。
  • 具有用于健康和准备情况检查的端点,以便Kubernetes可以在停机时采取措施。
  • 使用容器友好的操作系统(例如Alpine或CoreOS),以便它们更能抵抗错误的配置。
  • 使用多阶段构建,以便仅部署已编译的应用程序,而不部署其附带的开发源。

许多工具和服务可让您即时扫描和优化图像。随时对其进行更新和安全性评估很重要。

8配置Pod优先级

仅仅因为您已经配置了节点和Pod亲和力,并不意味着所有Pod都应该以相同的优先级进行调度。例如,出于各种原因,您可能需要先部署某些Pod,然后再部署其他Pod。

在这种情况下,Kubernetes提供了为Pod分配优先级的选项。首先,您需要创建一个容器,例如PriorityClass:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 9999
globalDefault: false
description: "This priority class should be used for smoke testing environments before any other pod gets deployed."

 

尽管建议您只创建几个级别(例如,低,中和高),但是您可以根据需要创建任意多个优先级类。较高的数值表示较高的优先级顺序。您可以在Pod规范下添加一个priorityClassName

priorityClassName:高优先级

这样,您可以进行自定义,以根据需要有效地运行某些部署。

9配置Kubernetes功能

Kubernetes运行一个功能门框架,该框架允许管理员为其环境启用或禁用功能。

其中一些功能可能有助于扩展性能,因此值得研究:

  • CPUManager提供基本的核心亲缘关系功能,并将工作负载限制在特定的CPU上。
  • 加速器:启用GPU支持。
  • PodOverhead:处理Pod开销。

除了其他考虑因素之外,管理内存过量使用也同样重要,这样它才不会出现紧急情况,并且可以基于priority杀死进程。

例如,值得验证以下系统设置:

vm.overcommit_memory = 1
vm.panic_on_oom = 0

此外,kubelet config的设置可控制pods-per-core,即基于节点可用核心数在节点上运行的pod数。例如,对于pods-per-core = 10和4核节点,每个节点最多可以有40个pod。

许多优化可能会影响最大群集限制以获得最佳性能(通常为1秒以下的延迟)和每个群集的最大Pod数量,尽管在实践中验证可能不可行。

10优化Etcd集群

Etcd是Kubernetes的大脑,因此保持其健康和优化很重要。理想情况下,应将etcd群集与kube-apiserver放在同一位置,以最大程度地减少它们之间的延迟。如果无法在同一地点进行托管,那么您应该拥有一个优化的路由路径,并且它们之间具有较高的网络吞吐量。

但是要小心,因为扩大etcd群集会导致更高的可用性,但会牺牲更高的性能,因此,在不必要时不要过量使用多余的etcd成员。

摘要

就其价值而言,Kubernetes非常高效且开箱即用。为正确配置部署以满足当前需求而付出的努力越多,从长远来看,您将获得更多的性能。

架构君码字不易,如需转载,请注明出处:https://javajgs.com/archives/6290

发表评论