基础模式-可预测的需求

艾因技术K8s翻译大约 25 分钟

基础模式-可预测的需求

2.1 Predictable Demands

2.1 可预测的需求

The foundation of successful application deployment, management, and coexistence on a shared cloud environment is dependent on identifying and declaring the application resource requirements and runtime dependencies. This Predictable Demands pattern is about how you should declare application requirements, whether they are hard runtime dependencies or resource requirements. Declaring your requirements is essential for Kubernetes to find the right place for your application within the cluster.

在共享云环境中成功部署、管理和协作应用程序的基础,是依赖于应用程序可以清晰的对资源需求和运行时依赖性声明。这个可预测的需求模式是关于如何声明应用程序需求的,包括硬件上的运行时依赖项和软件资源需求。声明需求对于Kubernetes在集群中应用程序找到合适的位置有着至关重要的作用。

2.1.1 Problem

2.1.1 问题

Kubernetes can manage applications written in different programming languages as long as the application can be run in a container. However, different languages have different resource requirements. Typically, a compiled language runs faster and often requires less memory compared to just-in-time runtimes or interpreted languages. Considering that many modern programming languages in the same category have similar resource requirements, from a resource consumption point of view, more important aspects are the domain, the business logic of an application, and the actual implementation details.

只要应用程序可以在容器中运行,Kubernetes就可以管理用不同编程语言编写的应用程序。但是,不同的语言有不同的资源需求。通常,与即时运行时或解释语言相比,编译语言运行速度更快,通常需要更少的内存。考虑到同一类别中的许多现代编程语言具有相似的资源需求,从资源消耗的角度来看,更重要的方面是领域、应用程序的业务逻辑和实际实现细节。

It is difficult to predict the amount of resources a container may need to function optimally, and it is the developer who knows the resource expectations of a service implementation (discovered through testing). Some services have a fixed CPU and memory consumption profile, and some are spiky. Some services need persistent storage to store data; some legacy services require a fixed port number on the host system to work correctly. Defining all these application characteristics and passing them to the managing platform is a fundamental prerequisite for cloud-native applications.

很难预测容器实现最佳功能所需的资源量,而开发人员知道服务实现的资源期望(通过测试发现)。有些服务具有固定的CPU和内存消耗模式,有些则是尖峰的。有些服务需要持久存储来存储数据;某些传统服务需要主机系统上的固定端口号才能正常工作。定义所有这些应用程序特征并将其传递给管理平台是云原生应用程序的基本先决条件。

Besides resource requirements, application runtimes also have dependencies on platform-managed capabilities like data storage or application configuration.

除了资源需求外,应用程序运行时还依赖于平台管理的功能,如数据存储或应用程序配置。

2.1.2 Solution

2.1.2 解决方案

Knowing the runtime requirements for a container is important mainly for two reasons.First, with all the runtime dependencies defined and resource demands envisaged,Kubernetes can make intelligent decisions for where to place a container on the cluster for most efficient hardware utilization. In an environment with shared resources among a large number of processes with different priorities, the only way for a successful coexistence is to know the demands of every process in advance. However, intelligent placement is only one side of the coin.

了解容器的运行时需求非常重要,主要有两个原因。首先,定义了所有的运行时依赖项并设想了资源需求,Kubernetes可以智能地决定在集群上放置容器的位置,以实现最高效的硬件利用率。在大量具有不同优先级的流程共享资源的环境中,成功共存的唯一方法是提前了解每个流程的需求。然而,智能布局只是一半原因。

The second reason container resource profiles are essential is capacity planning.Based on the particular service demands and the total number of services, we can do some capacity planning for the different environments and come up with the most cost-effective host profiles to satisfy the entire cluster demand. Service resource profiles and capacity planning go hand-to-hand for successful cluster management in the long term.

至关重要的第二个原因是容器资源配置文件里面的容量规划。根据特定的服务需求和服务总数,我们可以针对不同的环境进行容量规划,并提出最经济高效的主机配置文件以满足整个集群的需求。从长远来看,服务资源配置文件和容量规划密切相关,可实现成功的群集管理。

Let’s have a look first at how to declare runtime dependencies before we dive into resource profiles.

在深入研究资源配置文件之前,让我们先看看如何声明运行时依赖项。

2.1.2.1 Runtime Dependencies

2.1.2.1 运行时依赖

One of the most common runtime dependencies is file storage for saving application state. Container filesystems are ephemeral and lost when a container is shut down.Kubernetes offers volume as a Pod-level storage utility that survives container restarts.

最常见的运行时依赖项之一是用于保存应用程序状态的文件存储。容器文件系统是短暂的,当容器关闭时会丢失。Kubernetes提供卷作为一个Pod级存储实用程序,在容器重新启动后仍然存在。

The most straightforward type of volume is emptyDir, which lives as long as the Pod lives and when the Pod is removed, its content is also lost. The volume needs to be backed by some other kind of storage mechanism to have a volume that survives Pod restarts. If your application needs to read or write files to such long-lived storage, you have to declare that dependency explicitly in the container definition using volumes,as shown in Example 2-1.

最直接的卷类型是emptyDir,它的寿命与Pod的寿命一样长,当Pod被移除时,其内容也会丢失。该卷需要由其他类型的存储机制来支持,以使该卷在Pod重新启动后仍能生存。如果应用程序需要将文件读写到这种长寿命存储中,则必须使用卷在容器定义中显式声明该依赖关系,如示例2-1所示。

Example 2-1. Dependency on a PersistentVolume

apiVersion: v1
kind: Pod
metadata:
 name: random-generator
spec:
 containers:
 - image: k8spatterns/random-generator:1.0
 name: random-generator
 volumeMounts:
 - mountPath: "/logs"
  name: log-volume
volumes:
- name: log-volume
 #Dependency of a PVC to be present and bound
 persistentVolumeClaim:
  claimName: random-generator-log

The scheduler evaluates the kind of volume a Pod requires, which affects where the Pod gets placed. If the Pod needs a volume that is not provided by any node on the cluster, the Pod is not scheduled at all. Volumes are an example of a runtime dependency that affects what kind of infrastructure a Pod can run and whether the Pod can be scheduled at all.

调度器评估Pod需要的卷的类型,这会影响Pod放置的位置。如果Pod需要群集上任何节点都不提供的卷,则Pod根本不会被调度。卷是运行时依赖关系的一个示例,它影响Pod可以运行的基础结构类型以及Pod是否可以调度。

A similar dependency happens when you ask Kubernetes to expose a container port on a specific port on the host system through hostPort. The usage of a hostPort creates another runtime dependency on the nodes and limits where a Pod can be scheduled. hostPort reserves the port on each node in the cluster and limit to maximum one Pod scheduled per node. Because of port conflicts, you can scale to as many Pods as there are nodes in the Kubernetes cluster.

当你要求Kubernetes通过hostPort公开主机系统上特定端口上的容器端口时,也会发生类似的依赖关系。主机端口的使用在节点上创建了另一个运行时依赖项,并限制了Pod的调度位置。hostPort保留群集中每个节点上的端口,并限制每个节点最多调度一个Pod。由于端口冲突,您可以扩展到Kubernetes集群中节点的数量。

A different type of dependency is configurations. Almost every application needs some configuration information and the recommended solution offered by Kubernetes is through ConfigMaps. Your services need to have a strategy for consuming settings—either through environment variables or the filesystem. In either case, this introduces a runtime dependency of your container to the named ConfigMaps. If not all of the expected ConfigMaps are created, the containers are scheduled on a node, but they do not start up. ConfigMaps and Secrets are explained in more details in Chapter 19, Configuration Resource, and Example 2-2 shows how these resources are used as runtime dependencies.

另一种依赖关系是配置。几乎每个应用程序都需要一些配置信息,Kubernetes推荐的解决方案是通过ConfigMaps。服务需要有一个通过环境变量或文件系统使用设置的策略。在任何一种情况下,这都会将容器的运行时依赖项引入到命名的ConfigMaps。如果未创建所有预期的ConfigMap,则会在节点上调度容器,但它们不会启动。配置映射和敏感数据集在第19章“配置资源”中有更详细的解释,示例2-2显示了如何将这些资源用作运行时依赖项。

Example 2-2. Dependency on a ConfigMap

apiVersion: v1
kind: Pod
metadata:
 name: random-generator
spec:
 containers:
 - image: k8spatterns/random-generator:1.0
 name: random-generator
 env:
 - name: PATTERN
  valueFrom:
 configMapKeyRef:
 # Dependency of a ConfigMap to be present
  name: random-generator-config
  key: pattern

A similar concept to ConfigMaps are Secrets, which offer a slightly more secure way of distributing environment-specific configurations to a container.The way to consume a Secret is the same as it is for ConfigMap consumption, and it introduces the same kind of dependency from a container to a namespace.

与ConfigMaps类似的概念是敏感数据集(Secret),它提供了一种更安全的方式将特定于环境的配置分发到容器。使用Secret的方式与使用ConfigMap的方式相同,并且它引入了从容器到命名空间的相同类型的依赖关系。

While the creation of ConfigMap and Secret objects are simple admin tasks we have to perform, cluster nodes provide storage and port numbers. Some of these dependencies limit where a Pod gets scheduled (if anywhere at all), and other dependencies may prevent the Pod from starting up. When designing your containerized applications with such dependencies, always consider the runtime constraints they will create later.

虽然创建ConfigMap和Secret对象是我们必须执行的简单管理任务,但集群节点提供存储和端口号。其中一些依赖项限制了Pod的调度位置(如果在任何地方),其他依赖项可能会阻止Pod启动。在设计具有此类依赖关系的容器化应用程序时,始终考虑它们稍后将创建的运行时约束。

2.1.2.2 Resource Profiles
2.1.2.2 资源概况

Specifying container dependencies such as ConfigMap, Secret, and volumes is straightforward. We need some more thinking and experimentation for figuring out the resources requirements of a container. Compute resources in the context of Kubernetes are defined as something that can be requested by, allocated to, and consumed from a container. The resources are categorized as compressible (i.e., can be throttled, such as CPU, or network bandwidth) and incompressible (i.e., cannot be throttled, such as memory).

指定容器依赖项(如ConfigMap、Secret和volumes)非常简单。我们需要做更多的思考和实验来确定容器的资源需求。Kubernetes上下文中的计算资源定义为容器可以请求、分配和使用的资源。这些资源分为可压缩(即,可以节流,如CPU或网络带宽)和不可压缩(即,不能节流,如内存)。

Making the distinction between compressible and incompressible resources is important. If your containers consume too many compressible resources such as CPU, they are throttled, but if they use too many incompressible resources (such as memory), they are killed (as there is no other way to ask an application to release allocated memory).

区分可压缩资源和不可压缩资源很重要。如果您的容器消耗了太多的可压缩资源(如CPU),它们将被限制,但如果它们使用了太多的不可压缩资源(如内存),它们将被终止(因为没有其他方法要求应用程序释放分配的内存)。

Based on the nature and the implementation details of your application, you have to specify the minimum amount of resources that are needed (called requests) and the maximum amount it can grow up to (the limits). Every container definition can specify the amount of CPU and memory it needs in the form of a request and limit. At a high level, the concept of requests/limits is similar to soft/hard limits. For example, similarly, we define heap size for a Java application by using the -Xms and -Xmx command-line options.

根据应用程序的性质和实现细节,你必须指定容器所需的最小资源量(称为基本需求资源)和最大资源量(最大限制)。每个容器定义都可以以请求和限制的形式指定它所需的CPU和内存量。在高层次上,请求/限制的概念类似于软/硬限制。例如,类似地,我们通过使用-Xms和-Xmx命令行选项为Java应用程序定义堆大小。

The requests amount (but not limits) is used by the scheduler when placing Pods to nodes. For a given Pod, the scheduler considers only nodes that still have enough capacity to accommodate the Pod and all of its containers by summing up the requested resource amounts. In that sense, the requests field of each container affects where a Pod can be scheduled or not. Example 2-3 shows how such limits are specified for a Pod.

调度器在放置POD到节点时使用的是最小资源量(不是最大限制资源)。对于给定的Pod,调度器通过汇总请求的资源量,只考虑仍有足够容量容纳Pod及其所有容器的节点。从这个意义上讲,每个容器的requests字段都会影响Pod的调度位置。示例2-3显示了如何为Pod指定此类限制。

Example 2-3. Resource limits

apiVersion: v1
kind: Pod
metadata:
 name: random-generator
spec:
 containers:
 - image: k8spatterns/random-generator:1.0
  name: random-generator
  resources:
   requests:
   #Initial resource request for CPU and memory
    cpu: 100m
    memory: 100Mi
   limits:
   #Upper limit until we want our application to grow at max
    cpu: 200m
    memory: 200Mi

Depending on whether you specify the requests, the limits, or both, the platform offers a different kind of Quality of Service (QoS).

根据你是指定基本需求资源、最大限制资源还是两者都指定,K8S平台提供不同类型的服务质量(QoS)。

Best-Effort-最大效率的Pod

  • Pod that does not have any requests and limits set for its containers. Such a Pod is considered as the lowest priority and is most likely killed first when  the node where the Pod is placed runs out of incompressible resources.
  • 那些没有为其容器设置任何基本需求资源和最大限制资源的Pod。会被认为是最低优先级的,当放置Pod的节点耗尽不可压缩的资源时,最有可能首先被杀死。

Burstable-可膨胀的Pod

  • Pod that has requests and limits defined, but they are not equal (and limits is larger than requests as expected). Such a Pod has minimal resource guarantees,but is also willing to consume more resources up to its limit when available.When the node is under incompressible resource pressure, these Pods are likely to be killed if no Best-Effort Pods remain.
  • 那些设置了基本需求资源和最大限制资源的Pod,并且两者的资源量不相等(其中最大限制的资源大于基本需求资源)。这样的Pod具有最小的资源保证,同时在资源可用时,可以消耗更多的资源,直到达到其设置的最大限制值。当节点的不可压缩资源耗尽时,如果当前没有最大效率的Pod存在,则这些定义了不同基本需求资源和最大限制资源的Pod也可能会被杀掉。

Guaranteed-具有保证的Pod

  • Pod that has an equal amount of request and limit resources. These are the highest-priority Pods and guaranteed not to be killed before Best-Effort and Burstable Pods.
  • 那些具有相同基本需求资源和最大限制资源配置的Pod,它们具有最高的优先级并且被保证在存在最大效率Pod和可膨胀Pod的情况下不被杀掉。

So the resource characteristics you define or omit for the containers have a direct impact on its QoS and define the relative importance of the Pod in the event of resource starvation. Define your Pod resource requirements with this consequence in mind.

因此,为容器定义资源特性将直接影响其服务质量,并且在资源不足时,定义Pod资源是非常重要的。考虑到这一点,请对Pod资源需求进行配置。

2.1.2.3 Pod Priority
2.1.2.3 Pod优先级

We explained how container resource declarations also define Pods’ QoS and affect the order in which the Kubelet kills the container in a Pod in case of resource starvation.Another related feature that is still in beta at the time of this writing is Pod Priority and Preemption. Pod priority allows indicating the importance of a Pod relative to other Pods, which affects the order in which Pods are scheduled. Let’s see that in action in Example 2-4.

我们解释了容器资源声明如何定义Pod的服务质量,以及如何影响K8s在资源不足的情况下杀死Pod中容器的顺序。在撰写本文时,另一个相关功能仍处于测试阶段,即Pod优先级和抢占。Pod优先级允许指示Pod相对于其他Pod的重要性,这会影响Pod的调度顺序。让我们在例2-4中看到这一点。

Example 2-4. Pod priority

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
 name: high-priority    #The name of the priority class object
value: 1000       #The priority value of the object
globalDefault: false
description: This is a very high priority Pod class
---
apiVersion: v1
kind: Pod
metadata:
 name: random-generator
 labels:
  env: random-generator
 spec:
 containers:
 - image: k8spatterns/random-generator:1.0
  name: random-generator
 priorityClassName: high-priority   
 #The priority class to use with this Pod, as defined in PriorityClass resource

We created a PriorityClass, a non-namespaced object for defining an integer-based priority. Our PriorityClass is named high-priority and has a priority of 1,000. Now we can assign this priority to Pods by its name as priorityClassName: highpriority. PriorityClass is a mechanism for indicating the importance of Pods relative to each other, where the higher value indicates more important Pods.

我们创建了一个PriorityClass,一个无命名空间的对象,用于定义基于整数的优先级。我们的PriorityClass被命名为high priority,优先级为1000。现在,我们可以通过名称priorityClassName:highpriority将此优先级分配给POD。PriorityClass是一种表示Pods相对重要性的机制,其中值越高表示Pods越重要。

When the Pod Priority feature is enabled, it affects the order in which the scheduler places Pods on nodes. First, the priority admission controller uses the priorityClass Name field to populate the priority value for new Pods. When multiple Pods are waiting to be placed, the scheduler sorts the queue of pending Pods by highest priority first. Any pending Pod is picked before any other pending Pod with lower priority in the scheduling queue, and if there are no constraints preventing it from scheduling, the Pod gets scheduled.

当Pod优先级功能启用时,它会影响调度器在节点上放置Pod的顺序。首先,优先级许可调度器使用priorityClass名称字段填充新POD的优先级值。当多个Pods等待放置时,调度器首先按最高优先级对挂起Pods队列进行排序。在调度队列中,任何高优先级的Pod会比低优先级的Pod先被放置,如果没有约束阻止其调度,Pod将被调度。

Here comes the critical part. If there are no nodes with enough capacity to place a Pod, the scheduler can preempt (remove) lower-priority Pods from nodes to free up resources and place Pods with higher priority. As a result, the higher-priority Pod might be scheduled sooner than Pods with a lower priority if all other scheduling requirements are met. This algorithm effectively enables cluster administrators to control which Pods are more critical workloads and place them first by allowing the scheduler to evict Pods with lower priority to make room on a worker node for higher-priority Pods. If a Pod cannot be scheduled, the scheduler continues with the placement of other lower-priority Pods.

关键部分来了。如果没有足够容量的节点放置Pod,调度程序可以抢占(删除)节点中优先级较低的Pod,以释放资源并放置优先级较高的Pod。因此,如果满足所有其他调度要求,则优先级较高的Pod可能比优先级较低的Pod调度得更快。此算法有效地使群集管理员能够控制哪些POD是更关键的工作负载,并通过允许调度器逐出优先级较低的POD,在工作节点上为优先级较高的POD腾出空间,将它们放在第一位。如果无法调度Pod,则调度程序将继续放置其他优先级较低的Pod。

Pod QoS (discussed previously) and Pod priority are two orthogonal features that are not connected and have only a little overlap. QoS is used primarily by the Kubelet to preserve node stability when available compute resources are low. The Kubelet first considers QoS and then PriorityClass of Pods before eviction. On the other hand, the scheduler eviction logic ignores the QoS of Pods entirely when choosing preemption targets. The scheduler attempts to pick a set of Pods with the lowest priority possible that satisfies the needs of higher-priority Pods waiting to be placed.

Pod 的服务质量(资源配置)和Pod优先级是两个相互正交的特性,它们没有连接,只有一点重叠。服务质量(资源配置)主要由K8s用于在可用计算资源较低时保持节点稳定性。K8s首先考虑服务质量(资源配置),然后在资源不足时优先考虑PriorityClass 。另一方面,调度器的回收逻辑在选择抢占目标时完全忽略了POD的服务质量(资源配置)。调度器尝试选择一组优先级尽可能低的Pods,以满足等待放置的高优先级Pods的需要。

When Pods have a priority specified, it can have an undesired effect on other Pods that are evicted. For example, while a Pod’s graceful termination policies are respected, the PodDisruptionBudget as discussed in Chapter 10, Singleton Service is not guaranteed, which could break a lower-priority clustered application that relies on a quorum of Pods.

当POD具有指定的优先级时,它可能会对其他被逐出的POD产生不可预料的影响。例如,虽然Pod的优雅终止策略得到了遵守,但如第10章“单例服务”中所述的Pod中断预算无法保证,这可能会破坏依赖Pod仲裁的低优先级集群应用程序。

Another concern is a malicious or uninformed user who creates Pods with the highest possible priority and evicts all other Pods. To prevent that, ResourceQuota has been extended to support PriorityClass, and larger priority numbers are reserved for critical system Pods that should not usually be preempted or evicted.

另一个问题是,在恶意或不知情的用户创建具有最高优先级的pod并逐出所有其他pod。为了防止这种情况,ResourceQuota已经扩展到支持PriorityClass,并为通常不应抢占或逐出的关键系统Pods保留了更大的优先级。

In conclusion, Pod priorities should be used with caution because user-specified numerical priorities that guide the scheduler and Kubelet about which Pods to place or to kill are subject to gaming by users. Any change could affect many Pods, and could prevent the platform from delivering predictable service-level agreements.

总之,应该谨慎使用Pod优先级,因为指导调度器和K8s放置或杀死哪些Pod的数字优先级,可能取决于用户的随意游戏。任何更改都可能影响许多POD,并可能阻止平台提供可预测的服务级别协议。

2.1.2.4 Project Resources
2.1.2.4 项目资源

Kubernetes is a self-service platform that enables developers to run applications as they see suitable on the designated isolated environments. However, working in a shared multitenanted platform also requires the presence of specific boundaries and control units to prevent some users from consuming all the resources of the platform. One such tool is ResourceQuota, which provides constraints for limiting the aggregated resource consumption in a namespace. With ResourceQuotas, the cluster administrators can limit the total sum of computing resources (CPU, memory) and storage consumed. It can also limit the total number of objects (such as ConfigMaps, Secrets, Pods, or Services) created in a namespace.

Kubernetes是一个自助服务平台,使开发人员能够在指定的隔离环境中运行他们认为合适的应用程序。然而,在共享多租户平台中工作还需要特定的边界和控制单元,以防止某些用户消耗平台的所有资源。其中一个工具是ResourceQuota,它提供了限制命名空间中聚合资源消耗的约束。通过资源配额,集群管理员可以限制计算资源(CPU、内存)和存储消耗的总和。它还可以限制在命名空间中创建的对象(如ConfigMaps、Secrets、Pod或Services)的总数。

Another useful tool in this area is LimitRange, which allows setting resource usage limits for each type of resource. In addition to specifying the minimum and maximum permitted amounts for different resource types and the default values for these resources, it also allows you to control the ratio between the requests and limits, also known as the overcommit level. Table 2-1 gives an example how the possible values for requests and limits can be chosen.

该领域的另一个有用工具是LimitRange,它允许为每种类型的资源设置资源使用限制。除了为不同的资源类型指定允许的最小和最大数量以及这些资源的默认值外,它还允许您控制请求和限制之间的比率,也称为超额提交级别。表2-1给出了如何选择请求和限制的可能值的示例。

Table 2-1. Limit and request ranges

TypeResourceMinMaxDefault limitDefault requestLim/req ratio
ContainerCPU500m2500m250m4
ContainerMemory250Mi2Gi500Mi250Mi4

LimitRanges are useful for controlling the container resource profiles so that there are no containers that require more resources than a cluster node can provide. It can also prevent cluster users from creating containers that consume a large number of resources, making the nodes not allocatable for other containers. Considering that the requests (and not limits) are the primary container characteristic the scheduler uses for placing, LimitRequestRatio allows you to control how much difference there is between the requests and limits of containers. Having a big combined gap between requests and limits increases the chances for overcommitting on the node and may degrade application performance when many containers simultaneously require more resources than originally requested.

限制资源范围区间的方法对于控制容器资源配置文件非常有用,这样就不会有容器需要的资源比集群节点提供的资源还要多。它还可以防止集群用户创建消耗大量资源的容器,从而使节点无法分配给其他容器。考虑到基本资源需求(而不是限制)是调度器用于放置的主要容器特性,LimitRequestRatio允许您控制请求和容器限制之间的差异。请求和限制之间存在较大的组合间隙会增加在节点上过度交付的机会,并且当许多容器同时需要比最初请求更多的资源时,可能会降低应用程序性能。

2.1.2.5 Capacity Planning

2.1.2.5 容量计划

Considering that containers may have different resource profiles in different environments, and a varied number of instances, it is evident that capacity planning for a multipurpose environment is not straightforward. For example, for best hardware utilization, on a nonproduction cluster, you may have mainly Best-Effort and Burstable containers. In such a dynamic environment, many containers are starting up and shutting down at the same time, and even if a container gets killed by the platform during resource starvation, it is not fatal. On the production cluster where we want things to be more stable and predictable, the containers may be mainly of the Guaranteed type and some Burstable. If a container gets killed, that is most likely a sign that the capacity of the cluster should be increased.

考虑到容器在不同环境中可能具有不同的资源配置文件,以及不同数量的实例,显然多用途环境的容量规划并不简单。例如,为了获得最佳的硬件利用率,在非生产集群上,您可能主要使用最大效率和可膨胀(扩展)的容器。在这样一个动态环境中,许多容器同时启动和关闭,即使容器在资源匮乏期间被平台杀死,也不是致命的。在我们希望事情更加稳定和可预测的生产集群上,容器可能主要是保证类型和一些稳定类型。如果容器被杀死,这很可能是集群容量应该增加的迹象。

Table 2-2 presents a few services with CPU and memory demands. 表格2-2 展示了一些具有CPU和内存需求的服务。

Table 2-2. Capacity planning example

PodCPU requestCPU limitMemory requestMemory limitInstances
A500m500m500Mi500Mi4
B250m500m250Mi1000Mi2
C500m1000m1000Mi2000Mi2
D500m500m500Mi500Mi1
Total4000m5500m5000Mi8500Mi9

Of course, in a real-life scenario, the more likely reason you are using a platform such as Kubernetes would be because there are many more services to manage, some of which are about to retire, and some are still at the design and development phase. Even if it is a continually moving target, based on a similar approach as described previously, we can calculate the total amount of resources needed for all the services per environment.

当然,在现实场景中,使用Kubernetes这样的平台的原因更有可能是因为还有更多的服务需要管理,其中一些服务即将退役,而一些服务仍处于设计和开发阶段。即使它是一个不断移动的目标,基于前面描述的类似方法,我们也可以计算每个环境中所有服务所需的资源总量。

Keep in mind that in the different environments there are also a different number of containers, and you may even need to leave some room for autoscaling, build jobs, infrastructure containers, and more. Based on this information and the infrastructure provider, you can choose the most cost-effective compute instances that provide the required resources.

请记住,在不同的环境中,容器的数量也不同,你甚至可能需要为自动缩放、构建作业、基础结构容器等留出一些空间。根据这些信息和基础结构提供商,你可以选择提供所需资源的最经济高效的计算实例。

2.1.3 Discussion

2.1.3 讨论

Containers are useful not only for process isolation and as a packaging format. With identified resource profiles, they are also the building blocks for successful capacity planning. Perform some early tests to discover the resource needs for each container and use that information as a base for future capacity planning and prediction.

容器不仅对于过程隔离和包装格式很有用。通过确定资源概况,它们也是成功进行能力规划的基础。执行一些早期测试,以发现每个容器的资源需求,并将这些信息用作未来容量规划和预测的基础。

However, more importantly, resource profiles are the way an application communicates with Kubernetes to assist in scheduling and managing decisions. If your application doesn’t provide any requests or limits, all Kubernetes can do is treat your containers as opaque boxes that are dropped when the cluster gets full. So it is more or less mandatory for every application to think about and provide these resource declarations.

然而,更重要的是,资源配置文件是应用程序与Kubernetes通信的方式,以帮助调度和管理决策。如果你的应用程序不提供任何资源需求或限制设置,Kubernetes所能做的就是将你的容器视为不透明的盒子,在集群满时丢弃。因此,每个应用程序或多或少都必须考虑并提供这些资源声明。

Now that you know how to size our applications, in Chapter 3, Declarative Deployment, you will learn multiple strategies to get our applications installed and updated on Kubernetes.

现在你已经知道了如何调整应用程序的大小,在第下一章“声明式部署”中,你将学习在Kubernetes上安装和更新应用程序的多种策略。