如何访问Kubernetes Pod资源

Tohad的奖励



当开始使用Kubernetes时,通常会忘记配置容器资源。此时,您只需要确保Docker映像正常工作并且可以将其部署到Kubernetes集群即可。



但是稍后,该应用程序需要与其他应用程序一起部署到生产集群。为此,您需要为容器分配资源,并确保有足够的资源来启动和运行该应用程序,并且在其他正在运行的应用程序中将没有问题。Mail.ru



Kubernetes aaS团队翻译了一篇有关容器资源(CPU和MEM),请求和资源限制的文章。您将了解这些设置的好处以及如果不安装它们会发生什么。



计算资源



我们有两种资源,具有以下单位:



  • 中央处理器(CPU)-核心;
  • 内存(MEM)-字节。


为每个容器指定资源。在以下YAML荚文件中,您将看到一个资源部分,其中包含请求的资源和限制资源:



  • 请求的Pod资源=所有Pod的请求资源之和;
  • 限制容器资源=所有容器的边际资源之和。


apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
请求和限制资源的示例Pod规范中的



字段resources.requested是用于查找所需节点的元素之一。现在,您可以安排Pod部署。您如何找到合适的节点?



Kubernetes由几个组件组成,包括主节点或主节点(Kubernetes控制平面)。主节点中有几个进程:kube-apiserver,kube-controller-manager和kube-scheduler。



kube-scheduler进程负责查看新创建的模块,并查找与所有模块请求(包括请求的资源数量)匹配的可能的工作程序节点。由kube-scheduler找到的节点列表将排名。该广告连播计划用于得分最高的网站。



紫色豆荚会放在哪里?



图片显示kube-scheduler应该安排一个新的紫色Pod。 Kubernetes集群包含两个节点:A和B。如您所见,kube-scheduler无法将Pod调度到节点A-可用(未经请求)的资源与紫色Pod的请求不匹配。例如,紫色Pod请求的1GB内存将不适合节点A,因为可用内存为0.5GB。但是节点B有足够的资源。结果,kube-scheduler决定紫色Pod的目的地是NodeB。



现在我们知道请求的资源如何影响启动Pod的节点的选择。但是边际资源如何影响?



限制资源是CPU / MEM无法跨越的边界。但是,CPU是灵活的,因此达到CPU限制的容器不会导致Pod关闭。相反,CPU节流将开始。如果达到了MEM使用限制,则容器将由于OOM-Killer而停止,并在RestartPolicy设置允许的情况下重新启动。



请求和详细限制资源



Docker和Kubernetes之间的资源关系



解释请求的资源和限制资源的工作方式最好方法是代表Kubernetes和Docker之间的关系。在上图中,您可以看到Kubernetes字段与Docker启动标志之间的关系。



内存:请求和限制



containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"


如上所述,内存以字节为单位。根据Kubernetes文档,我们可以将内存指定为数字。通常,它是一个整数,例如2678-即2678个字节。您也可以使用后缀GGi,最重要的是,记住,他们是不等价的。第一个是十进制,第二个是二进制。作为一个例子,在文档K8S提到:128974848129e6129M123Mi-它们是实质上相等。



Kubernetes参数limits.memory--memory来自Docker的标志匹配。的情况下request.memoryDocker没有箭头,因为Docker不使用此字段。您可能会问这是否有必要?是的如我之前所说,该领域对Kubernetes至关重要。根据从中获得的信息,kube调度程序决定要为其调度Pod的节点。



如果没有足够的内存用于查询,该怎么办?



如果容器达到请求的内存限制,则将Pod放置在Pod组中,当节点中没有内存时该Pod组停止。



如果将内存限制设置得太低会怎样?



如果容器超出内存限制,则由于OOM-Killed而终止。并且将在可能的情况下根据RestartPolicy重新启动,默认值为Always



如果不指定请求的内存会怎样?



Kubernetes将采用该限制并将其设置为默认值。



如果不指定内存限制会怎样?



容器没有限制,它可以根据需要使用尽可能多的内存。如果他开始使用该节点的所有可用内存,则OOM将杀死他。然后,如果可能,将根据RestartPolicy重新启动容器。



如果不指定内存限制会怎样?



这是最坏的情况:调度程序不知道容器需要多少资源,这会在节点上引起严重的问题。在这种情况下,最好具有默认的名称空间约束(由LimitRange设置)。默认情况下没有限制-Pod没有限制,它可以使用任意数量的内存。



如果请求的内存超出节点可提供的内存,则不会调度Pod。重要的是要记住,这Requests.memory不是最小值。这是足以使容器连续运行的内存量的说明。



通常建议为request.memory设置相同的值limit.memory... 这样可以防止Kubernetes在具有足够内存来运行Pod但又不足以运行Pod的节点上调度Pod。注意事项:安排Pod时,Kubernetes仅计算requests.memorylimits.memory不计算在内



CPU:请求和限制



containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"


使用CPU,一切都变得有些复杂。回到Kubernetes与Docker之间的关系图,您可以看到它request.cpu与匹配--cpu-shares,而limit.cpucpusDocker中的标志匹配



Kubernetes请求的CPU乘以1024,即CPU周期的比例。如果要请求1个完整内核,则必须cpu: 1如上所述添加



请求完整内核(比例= 1024)并不意味着您的容器将收到它。如果您的主机只有一个内核,并且您使用的容器不止一个,则所有容器之间必须共享可用的CPU。这是怎么发生的?让我们看一下图片。





CPU请求-单核系统



假设您有一个运行容器的单核主机系统。妈妈(Kubernetes)已烤制一个馅饼(CPU),并希望在孩子(容器)之间共享。三个孩子想要整个蛋糕(比例= 1024),另一个孩子想要一半的蛋糕(512)。妈妈想公平一点,做一个简单的计算。



#    ?
# 3           
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
#   :
3 (/) * 1 ( / ) + 1 (/) * 0.5 ( / )
#   ?
availableCakesNumber = 1
#   ()    ?
newMaxRequest = 1 / 3.5 =~ 28%


根据计算,三个孩子将获得28%的内核,而不是整个内核。第四个孩子将获得完整内核的14%,而不是一半。但是,如果您有多核系统,情况将有所不同。





CPU请求-多核(4)系统



在上图中,您可以看到三个孩子想要整个馅饼,一个想要一半。由于妈妈烤了四个蛋糕,她的每个孩子都会得到他们想要的东西。在多核系统中,处理器资源分布在所有可用的处理器核上。如果一个容器限制为少于一个完整的CPU内核,则仍可以100%使用它。



简化了以上计算,以了解如何在容器之间分配CPU。当然,除了容器本身之外,还有其他进程也使用CPU资源。当一个容器中的进程处于空闲状态时,其他容器可以使用其资源。CPU: "200m"对应CPU: 0,2,这表示一个核心的20%



现在让我们谈谈limit.cpu... 限制Kubernetes的CPU乘以100。结果是容器每100μs(cpu-period可使用的时间



limit.cpu匹配Docker标志--cpus这是旧--cpu-period旧的新结合--cpu-quota通过设置它,我们指示容器在开始节流之前可以使用多少可用CPU资源:



  • 的CPU是的组合cpu-period,是cpu-quota. cpus = 1.5等同于设置cpu-period = 100000cpu-quota = 150000;
  • cpu-period - CPU CFS调度程序周期,默认为100微秒;
  • cpu-quota-cpu-period容器内部限制的微秒数


如果请求的CPU不足会怎样?



如果容器需要的容量超过安装的容量,那么它将从其他进程中窃取CPU。



如果您设置的CPU限制不足会怎样?



由于CPU资源是可调的,因此节流将打开。



如果不指定CPU请求会怎样?



与内存一样,请求值等于限制。



如果不指定CPU限制会怎样?



容器将使用所需的CPU。如果在命名空间中定义了默认的CPU策略(LimitRange),则此限制也将用于容器。



如果不指定请求或CPU限制,会发生什么情况?



与内存一样,这是最坏的情况。调度程序不知道您的容器需要多少资源,这会在节点上引起严重的问题。为避免这种情况,您需要设置名称空间的默认限制(LimitRange)。



请记住,如果您请求的CPU数量超过节点可以提供的数量,则不会安排Pod。Requests.cpu-不是最小值,而是足以启动Pod并正常工作的值。如果您的应用程序不执行复杂的计算,则最佳选择是安装request.cpu <= 1并运行所需数量的副本。



理想的请求资源量或资源限制



我们了解了计算资源的局限性。现在是时候回答这个问题了,“我的Pod要运行应用程序而没有问题,需要多少资源?理想的量是多少?”



不幸的是,对于这些问题没有确切的答案。如果您不知道应用程序的性能如何,需要多少CPU或内存,最好的选择是为应用程序分配大量的内存和CPU,然后运行基准测试。



除了性能测试外,还应观察应用程序一周的监视行为。如果这些图表明您的应用程序消耗的资源少于请求的资源,则可以减少请求的CPU或内存量。



请参阅此Grafana仪表板作为示例... 它显示请求的资源或资源限制与当前资源使用之间的差异。



结论



查询和限制资源有助于保持Kubernetes集群的健康。正确配置限制可以最大程度地降低成本,并使应用程序始终保持运行状态。



简而言之,请记住以下几点:



  1. 请求的资源是启动期间(当Kubernetes计划托管应用程序时)要考虑的配置。相反,在应用程序已经在节点上运行时,限制资源在运行时很重要。
  2. 与内存相比,CPU是受管制的资源。如果CPU不足,您的Pod不会关闭,它将开始节流。
  3. 请求的资源和资源限制不是最小值和最大值!通过标识请求的资源,可以确保您的应用程序将平稳运行。
  4. 优良作法是将内存请求设置为等于内存限制。
  5. CPU <=1如果应用程序不执行复杂的计算,则可以按要求设置
  6. 如果您请求的资源多于节点的资源,则永远不会为该节点调度Pod。
  7. 使用负载测试和监视来确定请求的资源/资源限制的正确数量。


希望本文能帮助您了解资源限制的基本概念。您将能够在工作中应用这些知识。



祝好运!



还有什么要读的:



  1. SRE的可观察性:名称空间和度量结构
  2. 90+ Kubernetes: , , , .
  3. Kubernetes .



All Articles