配置垂直 Pod 自动扩缩

本页面说明了如何在 Google Kubernetes Engine (GKE) 集群中配置 Pod 纵向自动扩缩。Pod 纵向自动扩缩涉及调整 Pod 的 CPU 和内存请求。

如需使用 Pod 纵向自动扩缩,您需要执行以下操作:

  1. 在 GKE 集群上启用 Pod 纵向自动扩缩。对于 Autopilot 集群,Pod 纵向自动扩缩默认处于启用状态。
  2. 通过创建 VerticalPodAutoscaler 对象为工作负载配置 Pod 纵向自动扩缩,如以下部分所述。

概览

您可以使用 VerticalPodAutoscaler 自定义资源来分析和调整容器的 CPU 请求内存请求

您可以将 VerticalPodAutoscaler 资源配置为推荐 CPU 和内存请求,也可以自动更改 CPU 和内存请求。这可以通过在 VerticalPodAutoscaler 资源的 updateMode 字段中指定以下模式之一来做到这一点:

  • Off:在此模式(也称为建议模式)下,Pod 纵向自动扩缩不会对 Pod 进行任何更改。系统会计算建议,并在 VerticalPodAutoscaler 对象中对其进行检查。
  • Initial:Pod 纵向自动扩缩仅会在创建 Pod 时分配资源请求,之后不再进行更改。
  • Auto:Pod 纵向自动扩缩会在 Pod 的生命周期内更新 CPU 和内存请求。需要进行调整时,系统会删除 Pod,调整 CPU 和内存请求,然后启动新的 Pod。

本文档中的练习演示了如何使用这些模式。

自动模式下的 Pod 纵向自动扩缩

由于 Kubernetes 的限制,修改正在运行的 Pod 的资源请求的唯一方法是重新创建 Pod。因此,如果您创建了一个 updateMode"Auto"VerticalPodAutoscaler 对象,则 VerticalPodAutoscaler 将在需要更改某个 Pod 的资源请求时逐出该 Pod。

如需限制 Pod 重新启动的数量,请使用 Pod 中断预算

如需确保集群可以处理新规模的工作负载,请使用集群自动扩缩程序节点自动预配。 Pod 纵向自动扩缩功能会在更新之前通知集群自动扩缩程序,并在重新创建 Pod 之前提供运行大小经过调整的工作负载所需的资源,以最大限度地缩短中断时间。

准备工作

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

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 为可用区级集群选择默认 Compute Engine 可用区,或为区域级集群或 Autopilot 集群选择区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project PROJECT_ID
  • 如果您使用的是可用区级集群,请设置默认计算可用区
    gcloud config set compute/zone COMPUTE_ZONE
  • 如果您使用的是 Autopilot 集群或区域级集群,请设置默认计算区域
    gcloud config set compute/region COMPUTE_REGION
  • gcloud 更新到最新版本:
    gcloud components update

为集群启用 Pod 纵向自动扩缩

您可以使用 gcloud 工具或 Google Cloud Console 在新的或现有的标准集群上启用 Pod 纵向自动扩缩。在 Autopilot 集群中,Pod 纵向自动扩缩默认处于启用状态。

gcloud

如需创建启用了 Pod 纵向自动扩缩的新标准集群,请使用以下命令:

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

CLUSTER_NAME 替换为新集群的名称。

如需在现有标准集群上启用 Pod 纵向自动扩缩,请使用以下命令:

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

CLUSTER_NAME 替换为您的集群名称。

控制台

如需创建启用了 Pod 纵向自动扩缩的新标准集群,请执行以下任务:

  1. 转到 Cloud Console 中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 点击 创建

  3. 标准部分中,点击配置

  4. 根据需要配置集群。

  5. 从导航面板中选择自动化

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

  7. 点击创建

如需在现有集群上启用 Pod 纵向自动扩缩,请执行以下任务:

  1. 转到 Cloud Console 中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

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

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

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

  5. 点击保存更改

获取资源推荐

在本练习中,您将创建一个 updateMode"Off"VerticalPodAutoscaler 对象。然后创建一个具有两个 Pod 的 Deployment,每个 Pod 各有一个容器。Pod 创建后,Pod 纵向自动扩缩器会分析容器的 CPU 和内存需求,并在其 status 字段中记录这些推荐值。Pod 纵向自动扩缩器不会采取任何操作来更新正在运行的容器的资源请求。

  1. 将以下 VerticalPodAutoscaler 清单保存为名为 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"
    
  2. 创建 VerticalPodAutoscaler 对象:

    kubectl create -f my-rec-vpa.yaml
    
  3. 将以下 Deployment 清单保存为名为 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 或内存请求。您还可以看到 Deployment 中的 Pod 属于 VerticalPodAutoscaler,因为它指向 kind: Deploymentname: my-rec-deployment 的目标。

  4. 创建 Deployment:

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

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

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

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

现在您已获得推荐的 CPU 和内存请求,所以您可以选择删除部署,将 CPU 和内存请求添加到部署清单,然后再次启动部署。

停用特定容器

在本练习中,您将创建一个停用了特定容器的 VerticalPodAutoscaler 对象。然后创建一个 Deployment,其中包含一个 Pod,该 Pod 内又包含两个容器。在创建 Pod 之后,Pod 纵向自动扩缩将仅为一个容器创建并应用建议,忽略另一个已选择停用的容器。

  1. 将以下 VerticalPodAutoscaler 清单保存为名为 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"
    

    请注意,VerticalPodAutoscalerresourcePolicy 部分中提供了额外的信息。mode: "Off" 会针对具有指定名称(本例中为 my-opt-sidecar)的容器停用推荐功能。

  2. 创建 VerticalPodAutoscaler 对象:

    kubectl create -f my-opt-vpa.yaml
    
  3. 将以下 Deployment 清单保存为名为 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. 创建 Deployment:

    kubectl create -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 会重新创建,但只有一个容器包含更新的资源请求。

自动更新资源请求

在此练习中,您将创建具有两个 Pod 的部署。每个 Pod 各有一个请求 100 milliCPU 和 50 MiB 内存的容器。然后创建一个自动调整 CPU 和内存请求的 VerticalPodAutoscaler 对象。

  1. 将以下 Deployment 清单保存为名为 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: k8s.gcr.io/ubuntu-slim:0.1
            resources:
              requests:
                cpu: 100m
                memory: 50Mi
            command: ["/bin/sh"]
            args: ["-c", "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"]
    
  2. 创建 Deployment:

    kubectl create -f my-auto-deployment.yaml
    
  3. 列出正在运行的 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
    
  4. 记下 Pod 名称,以备日后使用。

该部署的 CPU 和内存请求非常小,因此该部署可能会因资源增加而受益。

  1. 将以下 VerticalPodAutoscaler 保存为名为 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"
    

    在此清单中,targetRef 字段显示,名为 my-deployment 的 Deployment 所控制的任何 Pod 都属于该 Pod 纵向自动扩缩器。

    updateMode 字段的值为 Auto,这意味着 Pod 纵向自动扩缩可以在 Pod 的生命周期内更新 CPU 和内存请求。亦即,Pod 纵向自动扩缩可以删除 Pod,调整 CPU 和内存请求,然后启动一个新 Pod。

  2. 创建 VerticalPodAutoscaler 对象:

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

    kubectl get pods
    

    注意 Pod 名称是否已更改。如果 Pod 名称尚未更改,请再稍等片刻,然后再次列出正在运行的 Pod。

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

    kubectl get pod POD_NAME --output yaml
    

    POD_NAME 替换为您的其中一个 pod 的名称。

    在输出结果中,可以看到 Pod 纵向自动扩缩增加了内存和 CPU 请求。还可以看到一个记录更新的注释:

    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
        ...
    
  5. 获取有关 Pod 纵向自动扩缩的详细信息:

    kubectl get vpa my-vpa --output yaml
    

    以下输出显示三组推荐的 CPU 和内存请求:下限、目标和上限:

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

    target 推荐值表示容器请求 587 milliCPU 和 262144 千字节的内存时将以最佳状态运行。

    Pod 纵向自动扩缩使用 lowerBoundupperBound 推荐值来决定是否删除 Pod 并将其替换为新 Pod。如果 Pod 的请求小于下限或大于上限,则 Pod 纵向自动扩缩器将删除该 Pod 并将其替换为符合目标推荐值的 Pod。

清理

为避免因本页面中使用的资源导致您的 Google Cloud 帐号产生费用,请执行以下任务:

  1. 在集群中停用 Pod 纵向自动扩缩:

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

    CLUSTER_NAME 替换为您的集群的名称。

  2. 您也可以选择删除集群

后续步骤