扩缩容器资源请求和限制


本页面介绍了如何使用 Pod 纵向自动扩缩在 Google Kubernetes Engine (GKE) 集群中分析和调整容器的 CPU 请求内存请求

您可以通过 Trusted Cloud 控制台手动扩缩容器资源,使用 VerticalPodAutoscaler 对象分析资源,或使用 Pod 纵向自动扩缩配置自动扩缩。

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

分析资源请求

Pod 纵向自动扩缩器会自动分析容器并提供建议的资源请求。您可以使用Trusted Cloud 控制台、Cloud Monitoring 或 Google Cloud CLI 查看这些资源请求。

控制台

如需在 Trusted Cloud 控制台中查看建议的资源请求,您必须部署至少存在 24 小时的现有工作负载。某些建议可能不适用于某些工作负载或与某些工作负载不相关,例如过去 24 小时内创建的工作负载、独立 Pod 以及使用 Java 编写的应用。

  1. 前往 Trusted Cloud 控制台中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要扩缩的工作负载的名称。

  3. 点击 操作 > 扩缩 > 修改资源请求

    “分析资源利用率数据”部分显示 Pod 纵向自动扩缩器控制器分析的历史使用情况数据,用于在“调整资源请求和限制”部分中创建建议的资源请求。

Cloud Monitoring

如需在 Cloud Monitoring 中查看建议的资源请求,您必须已部署现有工作负载。

  1. 前往 Trusted Cloud 控制台中的 Metrics Explorer 页面。

    进入 Metrics Explorer

  2. 点击配置

  3. 展开选择指标菜单。

  4. 资源菜单中,选择 Kubernetes 扩缩 (Kubernetes Scale)。

  5. 指标类别 (Metric category) 菜单中,选择自动扩缩器

  6. 指标菜单中,选择 Recommended per replicate request bytes(每个复制请求建议的字节数)和 Recommended per replica request core(每个副本请求建议的核心)。

  7. 点击应用

gcloud CLI

如需查看建议的资源请求,您必须创建 VerticalPodAutoscaler 对象和 Deployment。

  1. 对于 Standard 集群,请为集群启用 Pod 纵向自动扩缩。对于 Autopilot 集群,Pod 纵向自动扩缩默认处于启用状态。

    gcloud container clusters update CLUSTER_NAME --enable-vertical-pod-autoscaling
    

    CLUSTER_NAME 替换为您的集群名称。

  2. 将以下清单保存为 my-rec-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-rec-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: my-rec-deployment
      template:
        metadata:
          labels:
            app: my-rec-deployment
        spec:
          containers:
          - name: my-rec-container
            image: nginx
    

    此清单描述了一个没有 CPU 或内存请求的 Deploymentcontainers.name 值为 my-rec-deployment 指定 Deployment 中的所有 Pod 都属于 VerticalPodAutoscaler

  3. 将清单应用于集群:

    kubectl create -f my-rec-deployment.yaml
    
  4. 将以下清单保存为 my-rec-vpa.yaml

    apiVersion: autoscaling.k8s.io/v1
    kind: VerticalPodAutoscaler
    metadata:
      name: my-rec-vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind:       Deployment
        name:       my-rec-deployment
      updatePolicy:
        updateMode: "Off"
    

    此清单描述了 VerticalPodAutoscalerupdateModeOff 意味着,在 Pod 创建后,Pod 纵向自动扩缩器控制器会分析容器的 CPU 和内存需求,并在资源的 status 字段中记录这些建议。Pod 纵向自动扩缩器不会自动更新正在运行的容器的资源请求。

  5. 将清单应用于集群:

    kubectl create -f my-rec-vpa.yaml
    
  6. 一段时间后,查看 VerticalPodAutoscaler

    kubectl get vpa my-rec-vpa --output yaml
    

    输出内容类似如下:

    ...
      recommendation:
        containerRecommendations:
        - containerName: my-rec-container
          lowerBound:
            cpu: 25m
            memory: 262144k
          target:
            cpu: 25m
            memory: 262144k
          upperBound:
            cpu: 7931m
            memory: 8291500k
    ...
    

    此输出显示针对 CPU 和内存请求的建议。

手动设置 Pod 资源请求

您可以使用 Trusted Cloud 控制台或 kubectl 手动设置 Pod 资源请求。请遵循以下最佳实践来设置容器资源请求和限制:

  • 内存:为请求和限制设置相同的内存量。
  • CPU:对于请求,请根据您自己的 SLO 指定确保正确运行所需的最低 CPU。设置无限制的 CPU 限制。

控制台

  1. 前往 Trusted Cloud 控制台中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要扩缩的工作负载的名称。

  3. 点击 操作 > 扩缩 > 修改资源请求

    1. 调整资源请求和限制部分显示每个容器的当前 CPU 和内存请求以及建议的 CPU 和内存请求。
  4. 点击 Apply Latest Suggestions(应用最新建议)以查看为每个容器建议的请求。

  5. 点击保存更改

  6. 点击确认

kubectl

纵向扩缩工作负载并将中断降至最低

Kubernetes 1.33 版开始,您可以使用 kubectl patch 命令通过更新分配给容器的资源来纵向扩缩工作负载,而无需重新创建 Pod。如需了解详情(包括限制),请参阅 有关调整 CPU 和内存资源大小的 Kubernetes 文档

如需使用 kubectl patch 命令,请在 --patch 标志下指定更新的资源请求。例如,如需将 my-app 扩缩到 800 mCPU,请运行以下命令:

kubectl patch pod my-app --subresource resize --patch \
  '{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}'

纵向扩缩工作负载

如需为 Pod 设置资源请求,请在 Deployment 清单中设置 requests.cpu 和 memory.cpu 值。在此示例中,您将使用建议的资源请求手动修改在分析资源请求中创建的 Deployment。

  1. 将以下示例清单保存为 my-adjusted-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-rec-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: my-rec-deployment
      template:
        metadata:
          labels:
            app: my-rec-deployment
        spec:
          containers:
          - name: my-rec-container
            image: nginx
            resources:
              requests:
                cpu: 25m
                memory: 256Mi
    

    此清单描述了一个具有两个 Pod 的 Deployment。每个 Pod 各有一个请求 25 milliCPU 和 256 MiB 内存的容器。

  2. 将清单应用于集群:

    kubectl apply -f my-adjusted-deployment.yaml
    

自动设置 Pod 资源请求

Pod 纵向自动扩缩会使用 VerticalPodAutoscaler 对象在 updateModeAuto 时自动设置 Pod 上的资源请求。您可以使用 gcloud CLI 或Trusted Cloud 控制台来配置 VerticalPodAutoscaler

控制台

如需自动设置资源请求,您必须有一个启用了 Pod 纵向自动扩缩功能的集群。Autopilot 集群默认启用 Pod 纵向自动扩缩功能。

启用 Pod 纵向自动扩缩

  1. 进入 Trusted Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 在集群列表中,点击您要修改的集群的名称。

  3. 自动化部分中,点击 Pod 纵向自动扩缩选项对应的 修改

  4. 选中启用 Pod 纵向自动扩缩复选框。

  5. 点击保存更改

配置 Pod 纵向自动扩缩

  1. 前往 Trusted Cloud 控制台中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要为其配置 Pod 纵向自动扩缩的 Deployment 的名称。

  3. 点击 操作 > 自动扩缩 > Pod 纵向自动扩缩

  4. 选择自动扩缩模式:

    • 自动模式:Pod 纵向自动扩缩会在 Pod 的生命周期内更新 CPU 和内存请求。
    • 初始模式:Pod 纵向自动扩缩仅会在创建 Pod 时分配资源请求,之后不再进行更改。
  5. (可选)设置容器政策。通过此选项,您可以确保建议绝不会设置为高于或低于指定的资源请求。

    1. 点击 添加政策
    2. 修改容器模式选择自动
    3. 受控资源中,选择要针对哪些资源自动扩缩容容器。
    4. 点击添加规则,为容器的资源请求设置一个或多个最小或最大范围:
      • 允许的内存下限:容器应始终具有的内存大小下限(以 MiB 为单位)。
      • 允许的 CPU 下限:容器应始终具有的 CPU 数量下限(以 mCPU 为单位)。
      • 允许的内存上限:容器应始终具有的内存大小上限(以 MiB 为单位)。
      • 允许的 CPU 数量上限:容器应始终具有的 CPU 数量上限(以 mCPU 为单位)。
  6. 点击完成

  7. 点击保存

gcloud

如需自动设置资源请求,您必须使用启用了 Pod 纵向自动扩缩功能的集群。Autopilot 集群默认启用了该功能。

  1. 对于 Standard 集群,请为集群启用 Pod 纵向自动扩缩:

    gcloud container clusters update CLUSTER_NAME --enable-vertical-pod-autoscaling
    

    CLUSTER_NAME 替换为您的集群名称。

  2. 将以下清单保存为 my-auto-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-auto-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: my-auto-deployment
      template:
        metadata:
          labels:
            app: my-auto-deployment
        spec:
          containers:
          - name: my-container
            image: registry.k8s.io/ubuntu-slim:0.14
            resources:
              requests:
                cpu: 100m
                memory: 50Mi
            command: ["/bin/sh"]
            args: ["-c", "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"]
    

    此清单描述了一个具有两个 Pod 的 Deployment。每个 Pod 各有一个请求 100 milliCPU 和 50 MiB 内存的容器。

  3. 将清单应用于集群:

    kubectl create -f my-auto-deployment.yaml
    
  4. 列出正在运行的 Pod:

    kubectl get pods
    

    输出会显示 my-deployment 中的 Pod 的名称:

    NAME                            READY     STATUS             RESTARTS   AGE
    my-auto-deployment-cbcdd49fb-d6bf9   1/1       Running            0          8s
    my-auto-deployment-cbcdd49fb-th288   1/1       Running            0          8s
    
  5. 将以下清单保存为 my-vpa.yaml

    apiVersion: autoscaling.k8s.io/v1
    kind: VerticalPodAutoscaler
    metadata:
      name: my-vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind:       Deployment
        name:       my-auto-deployment
      updatePolicy:
        updateMode: "Auto"
    

    此清单描述了具有以下属性的 VerticalPodAutoscaler

    • targetRef.name:指定由名为 my-deployment 的 Deployment 控制的任何 Pod 都属于此 VerticalPodAutoscaler
    • updateMode: Auto:指定 Pod 纵向自动扩缩器控制器可以删除 Pod,调整 CPU 和内存请求,然后启动新的 Pod。

    您还可以使用 updateMode: "Initial" 配置 Pod 纵向自动扩缩,使其仅在创建 Pod 时分配资源请求。

  6. 将清单应用于集群:

    kubectl create -f my-vpa.yaml
    
  7. 等待几分钟,然后再次查看正在运行的 Pod:

    kubectl get pods
    

    输出显示 Pod 名称已更改:

    NAME                                 READY     STATUS             RESTARTS   AGE
    my-auto-deployment-89dc45f48-5bzqp   1/1       Running            0          8s
    my-auto-deployment-89dc45f48-scm66   1/1       Running            0          8s
    

    如果 Pod 名称未更改,请再稍等片刻,然后再次查看正在运行的 Pod。

查看 Pod 纵向自动扩缩器的相关信息

要查看 Pod 纵向自动扩缩器的详细信息,请执行以下操作:

  1. 获取有关正在运行的其中一个 Pod 的详细信息:

    kubectl get pod POD_NAME --output yaml
    

    POD_NAME 替换为您在上一步中检索到的其中一个 Pod 的名称。

    输出类似于以下内容:

    apiVersion: v1
    kind: Pod
    metadata:
      annotations:
        vpaUpdates: 'Pod resources updated by my-vpa: container 0: cpu capped to node capacity, memory capped to node capacity, cpu request, memory request'
    ...
    spec:
      containers:
      ...
        resources:
          requests:
            cpu: 510m
            memory: 262144k
        ...
    

    此输出显示 Pod 纵向自动扩缩器控制器的内存请求为 262144k,CPU 请求为 510 milliCPU。

  2. 获取有关 VerticalPodAutoscaler 的详细信息:

    kubectl get vpa my-vpa --output yaml
    

    输出类似于以下内容:

    ...
      recommendation:
        containerRecommendations:
        - containerName: my-container
          lowerBound:
            cpu: 536m
            memory: 262144k
          target:
            cpu: 587m
            memory: 262144k
          upperBound:
            cpu: 27854m
            memory: "545693548"
    

    此输出显示有关 CPU 和内存请求的建议,并包括以下属性:

    • target:指定为了使容器以最佳方式运行,它应请求 587 milliCPU 和 262,144 千字节的内存。
    • lowerBoundupperBound:Pod 纵向自动扩缩使用这些属性来决定是否删除 Pod 并将其替换为新 Pod。如果 Pod 的请求小于下限或大于上限,则 Pod 纵向自动扩缩器会删除该 Pod 并将其替换为符合目标特性的 Pod。

停用特定容器

您可以使用 gcloud CLI 或 Trusted Cloud 控制台选择退出 Pod 纵向自动扩缩的特定容器。

控制台

如需停用特定容器的 Pod 纵向自动扩缩功能,您必须有一个启用了 Pod 纵向自动扩缩功能的集群。Autopilot 集群默认启用 Pod 纵向自动扩缩功能。

启用 Pod 纵向自动扩缩

  1. 进入 Trusted Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 在集群列表中,点击您要修改的集群的名称。

  3. 自动化部分中,点击 Pod 纵向自动扩缩选项对应的 修改

  4. 选中启用 Pod 纵向自动扩缩复选框。

  5. 点击保存更改

配置 Pod 纵向自动扩缩

  1. 前往 Trusted Cloud 控制台中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要为其配置 Pod 纵向自动扩缩的 Deployment 的名称。

  3. 点击 操作 > 自动扩缩 > Pod 纵向自动扩缩

  4. 选择自动扩缩模式:

    • 自动模式:Pod 纵向自动扩缩会在 Pod 的生命周期内更新 CPU 和内存请求。
    • 初始模式:Pod 纵向自动扩缩仅会在创建 Pod 时分配资源请求,之后不再进行更改。
  5. 点击 添加政策

  6. 选择要停用的容器。

  7. 对于修改容器模式,请选择关闭

  8. 点击完成

  9. 点击保存

gcloud

如需停用特定容器的 Pod 纵向自动扩缩,请执行以下步骤:

  1. 将以下清单保存为 my-opt-vpa.yaml

    apiVersion: autoscaling.k8s.io/v1
    kind: VerticalPodAutoscaler
    metadata:
      name: my-opt-vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind:       Deployment
        name:       my-opt-deployment
      updatePolicy:
        updateMode: "Auto"
      resourcePolicy:
        containerPolicies:
        - containerName: my-opt-sidecar
          mode: "Off"
    

    此清单描述了 VerticalPodAutoscalermode: "Off" 值会关闭针对容器 my-opt-sidecar 的建议。

  2. 将清单应用于集群:

    kubectl apply -f my-opt-vpa.yaml
    
  3. 将以下清单保存为 my-opt-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-opt-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-opt-deployment
      template:
        metadata:
          labels:
            app: my-opt-deployment
        spec:
          containers:
          - name: my-opt-container
            image: nginx
          - name: my-opt-sidecar
            image: busybox
            command: ["sh","-c","while true; do echo Doing sidecar stuff!; sleep 60; done"]
    
  4. 将清单应用于集群:

    kubectl apply -f my-opt-deployment.yaml
    
  5. 一段时间后,查看 Pod 纵向自动扩缩器:

    kubectl get vpa my-opt-vpa --output yaml
    

    以下输出显示推荐的 CPU 和内存请求:

    ...
      recommendation:
        containerRecommendations:
        - containerName: my-opt-container
    ...
    

    在此输出中,只有针对一个容器的建议。未针对 my-opt-sidecar 提供建议。

    Pod 纵向自动扩缩绝不会更新已停用的容器上的资源。 如果您等待几分钟,该 Pod 会重新创建,但只有一个容器包含更新的资源请求。

识别没有资源请求或限制的工作负载

您可能需要找出未配置资源请求和限制的工作负载,因为 GKE 建议为所有工作负载设置资源请求和限制作为最佳实践,以避免在节点资源压力下突然终止 Pod 并提高费用分配的准确性。当节点遇到内存压力时,定义 BestEffort Pod 或具有Burstable内存的 Pod 可能会导致可靠性问题。 请遵循以下最佳实践来设置容器资源请求和限制:

  • 内存:为请求和限制设置相同的内存量。
  • CPU:对于请求,请根据您自己的 SLO 指定确保正确运行所需的最低 CPU。设置无限制的 CPU 限制。

GKE 会针对在没有资源请求和限制的情况下运行的工作负载生成分析洞见和建议。

下表介绍了 GKE 检测到的资源配置场景以及每个场景的条件。

提示子类型 缺少设置场景 详细信息
REQUEST_OR_LIMIT_NOT_SET 未配置内存请求和限制。 (MEMORY_REQUEST_AND_LIMIT_NOT_SET) Pod 正在运行,其容器没有设置内存请求量和限制。GKE 无法限制内存用量,如果节点遇到内存压力,可能会突然终止此类 Pod,从而可能导致可靠性问题。
REQUEST_OR_LIMIT_NOT_SET 未配置内存限制。 (MEMORY_LIMIT_NOT_SET) Pod 正在运行,其容器没有设置内存限制。GKE 无法限制内存用量,如果节点遇到内存压力,并且 Pod 的内存用量超出请求量,则可能会突然终止此类 Pod,从而可能导致可靠性问题。 您应为请求和限制设置相同的内存量,以避免 Pod 使用的内存超出请求的内存量。
REQUEST_OR_LIMIT_NOT_SET 未配置 CPU 请求和限制。 (CPU_REQUEST_AND_LIMIT_NOT_SET) Pod 正在运行,容器没有设置 CPU 请求量和限制。这会增加节点资源耗尽的几率,因而当节点 CPU 利用率接近其限制时,Pod 更有可能被节流,并可能导致性能问题。

如需详细了解这些分析洞见,请按照说明查看分析洞见和建议

手动检查资源请求和限制

您可能需要手动检查哪些资源请求和限制缺失,需要为给定的工作负载指定,以便您可以按照建议更新配置。

如需查看或更新指定工作负载的资源请求和限制配置,请执行以下操作:

  1. 前往 Trusted Cloud 控制台中的工作负载页面。

    转到“工作负载”

  2. 在工作负载列表中,点击要检查的工作负载的名称。

  3. 点击 操作 > 扩缩 > 修改资源请求

    1. 调整资源请求和限制部分显示每个容器的当前 CPU 和内存请求。

后续步骤