配置 Pod 纵向自动扩缩

Pod 纵向自动扩缩功能可自动设置 Kubernetes Pod 中容器的 CPU 和内存资源请求和限制。Pod 纵向自动扩缩功能会分析历史资源用量和当前资源用量,以提供建议,这些建议可以通过显示或通过更新 Pod 自动应用。此功能通过合理调整资源分配来提高稳定性和成本效益。

准备工作

在配置 Pod 纵向自动扩缩之前,请确保满足以下前提条件:

  • 您有一个正在运行的裸金属集群。
  • 您拥有对集群的 kubectl 访问权限。
  • 集群中提供 Metrics Server。裸金属集群默认包含 Metrics Server。

启用 Pod 纵向自动扩缩

通过设置预览版注释并配置集群规范,在裸金属集群上启用 Pod 纵向自动扩缩:

  1. 在集群自定义资源上添加或更新预览版注释。

    直接修改集群自定义资源,或修改集群配置文件并使用 bmctl update

    metadata:
      annotations:
        preview.baremetal.cluster.gke.io/vertical-pod-autoscaler: enable
    
  2. 修改集群自定义资源的 spec,以添加 verticalPodAutoscaling 字段并指定 enableUpdaterenableMemorySaver 模式:

    apiVersion: baremetal.cluster.gke.io/v1
    kind: Cluster
    metadata:
      name: cluster1
      namespace: cluster-cluster1
      annotations:
        preview.baremetal.cluster.gke.io/vertical-pod-autoscaler: enable
    spec:
      # ... other cluster spec fields
      verticalPodAutoscaling:
        enableUpdater: true       # Set to true for automated updates
        enableMemorySaver: true   # Set to true to reduce recommender memory usage
    
  3. 如果您修改了集群配置文件,请使用以下命令应用更改:

    bmctl update cluster -c CLUSTER_NAME --kubeconfig KUBECONFIG
    

    替换以下内容:

    • CLUSTER_NAME:您的集群的名称。

    • KUBECONFIG:集群 kubeconfig 文件的路径。

创建 VerticalPodAutoscaler 自定义资源

在集群上启用 Pod 纵向自动扩缩后,定义一个 VerticalPodAutoscaler 自定义资源以定位特定工作负载:

  1. 在目标工作负载所在的命名空间中定义 VerticalPodAutoscaler 资源。

    此自定义资源使用 targetRef 和任何资源政策指定其目标 Pod。

    apiVersion: "autoscaling.k8s.io/v1"
    kind: VerticalPodAutoscaler
    metadata:
      name: hamster-vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind: Deployment
        name: hamster
      resourcePolicy:
        containerPolicies:
          -   containerName: '*'
            minAllowed:
              cpu: 100m
              memory: 50Mi
            maxAllowed:
              cpu: 1
              memory: 500Mi
            controlledResources: ["cpu", "memory"]
    
  2. 使用以下命令应用 VerticalPodAutoscaler 清单:

    kubectl apply -f VPA_MANIFEST \
        --kubeconfig KUBECONFIG
    

    替换以下内容:

    • VPA_MANIFESTVerticalPodAutoscaler 清单文件的路径。

    • KUBECONFIG:集群 kubeconfig 文件的路径。

了解 Pod 纵向自动扩缩模式

Pod 纵向自动扩缩功能以不同模式运行,这些模式控制着它如何应用资源建议。

建议模式

在建议模式下,Pod 纵向自动扩缩会安装推荐器组件。此组件会分析资源使用情况,并在您创建的 VerticalPodAutoscaler 自定义资源的状态部分中发布 CPU 和内存请求及限制的建议值。

如需查看资源请求和限制建议,请使用以下命令:

kubectl describe vpa VPA_NAME \
    --kubeconfig KUBECONFIG \
    -n CLUSTER_NAMESPACE
Replace the following:

*   `VPA_NAME`: the name of the `VerticalPodAutoscaler`
    that's targeting the workloads for which you are considering resource
    adjustments.

*   `KUBECONFIG`: the path of the cluster kubeconfig
    file.

*   `CLUSTER_NAMESPACE`: the name of the cluster that's
    running vertical Pod autoscaling.

响应应包含一个类似于以下示例的 Status 部分:

Status:
  Conditions:
    Last Transition Time:  2025-08-04T23:53:32Z
    Status:                True
    Type:                  RecommendationProvided
  Recommendation:
    Container Recommendations:
      Container Name:  hamster
      Lower Bound:
        Cpu:     100m
        Memory:  262144k
      Target:
        Cpu:     587m
        Memory:  262144k
      Uncapped Target:
        Cpu:     587m
        Memory:  262144k
      Upper Bound:
        Cpu:     1
        Memory:  500Mi

在此模式下,Pod 不会自动更新。您可以根据这些建议手动更新 Pod 配置。如果未设置 enableUpdater 或将其设置为 false,则这是默认行为。

自动更新模式

当您将 enableUpdater enableUpdater 设置为 true 时,除了推荐器之外,裸金属生命周期控制器还会部署 Pod 纵向自动扩缩更新器和准入控制器组件。更新程序会监控当前资源请求与建议值相差很大的 Pod。

VerticalPodAutoscaler 资源中的更新政策指定了更新程序如何应用建议。默认情况下,更新模式为 Auto,这意味着更新程序会在创建 Pod 时分配更新后的资源设置。以下 VerticalPodAutoscaler 示例展示了如何将更新模式设置为 Initial

apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
  name: hamster-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: hamster
  resourcePolicy:
  updatePolicy:
    updateMode: "Initial"
    ...

更新程序支持以下五种模式:

  • Auto:更新程序驱逐 Pod。准入控制器会拦截新 Pod 的创建请求,并对其进行修改,以使用推荐器提供的建议 CPU 和内存值。更新资源需要重新创建 Pod,这可能会导致中断。使用更新程序遵循的 Pod 中断预算来管理逐出流程。此模式等同于 Recreate

  • Recreate:更新程序会在重新创建 Pod 时逐出 Pod 并分配建议的资源请求和限制。

  • InPlaceOrRecreate(Alpha 版):更新程序会尽力尝试就地更新,但如果无法就地更新,可能会回退到重新创建 Pod。如需了解详情,请参阅就地调整 Pod 大小文档。

  • Initial:更新程序仅在创建 Pod 时分配资源请求,之后不再加以更改。

  • Off:更新程序不会自动更改 Pod 的资源要求。系统会计算建议,并在 VerticalPodAutoscaler 对象中对其进行检查。

如需详细了解 VerticalPodAutoscaler 自定义资源,请使用 kubectl 检索安装在 1.33.0 版或更高版本集群上的 verticalpodautoscalercheckpoints.autoscaling.k8s.io 自定义资源定义。

以下示例展示了资源建议在 hamster 容器的 Status 部分中可能显示的方式。该示例还展示了 Pod 逐出事件的示例,当更新程序在自动为重新创建的 Pod 分配建议的资源配置之前逐出 Pod 时,就会发生该事件:

Spec:
  Resource Policy:
    Container Policies:
      Container Name:  *
      Controlled Resources:
        cpu
        memory
      Max Allowed:
        Cpu:     1
        Memory:  500Mi
      Min Allowed:
        Cpu:     100m
        Memory:  50Mi
  Target Ref:
    API Version:  apps/v1
    Kind:         Deployment
    Name:         hamster
  Update Policy:
    Update Mode:  Auto
Status:
  Conditions:
    Last Transition Time:  2025-08-04T23:53:32Z
    Status:                True
    Type:                  RecommendationProvided
  Recommendation:
    Container Recommendations:
      Container Name:  hamster
      Lower Bound:
        Cpu:     100m
        Memory:  262144k
      Target:
        Cpu:     587m
        Memory:  262144k
      Uncapped Target:
        Cpu:     587m
        Memory:  262144k
      Upper Bound:
        Cpu:     1
        Memory:  500Mi
Events:
  Type    Reason      Age   From         Message
  ----    ------      ----  ----         -------
  Normal  EvictedPod  49s   vpa-updater  VPA Updater evicted Pod hamster-7cb59fb657-lkrk4 to apply resource recommendation.

省内存模式

内存节省模式可减少 Pod 纵向自动扩缩推荐器组件的内存占用。将 enableMemorySaver 设置为 true 时,推荐器仅跟踪并计算具有匹配的 VerticalPodAutoscaler 自定义资源的 Pod 的汇总数据。

但缺点是,当您为现有工作负载创建新的 VerticalPodAutoscaler 自定义资源时,推荐器需要一些时间(最长 24 小时)来收集足够的历史记录,才能提供准确的建议。对于大多数集群类型,此模式默认处于 false 状态,但对于边缘集群,此模式默认处于 true 状态。

使用 Prometheus 作为持久历史记录提供程序

默认情况下,Recommender 组件会在内存中维护集群上运行的工作负载的资源消耗历史记录,并定期将其状态保存到 etcd 中的 VerticalPodAutoscalerCheckpoint 自定义资源,以提供针对重启的弹性。

从 Google Distributed Cloud 1.34 版开始,您可以使用自己的 Prometheus 实例作为资源消耗数据(即 CPU 和内存用量指标)的持久历史记录提供程序。启用此集成后,Recommender 可以在启动或重启时查询 Prometheus 服务器,以检索所有受管 Pod 的长期历史资源用量数据。检索此数据可让推荐器立即使用丰富的数据集构建其内部状态,从而从一开始就提供更明智、更准确的建议。

使用 Prometheus 作为持久历史记录提供方具有以下优势:

  • 优化资源利用率: 推荐器会在启动后立即生成明智且准确的建议,以便您优化集群资源利用率。

  • 防止内存不足 (OOM) 错误: Prometheus 无需将 Recommender 的内部状态存储在 VerticalPodAutoscalerCheckpoint 自定义资源 (CR) 中,从而提高 ETCD 内存利用率。当推荐器组件重启时,它会丢失内存中的历史数据。当您使用 Prometheus 作为历史记录提供方时,Recommender 会在重启时从 Prometheus 中提取历史指标,从而无需使用 VerticalPodAutoscalerCheckpoint CR 并节省 ETCD 内存。

您可以随时启用和停用 Prometheus 作为持久历史记录提供程序。

将 Prometheus 与 Pod 纵向自动扩缩搭配使用的前提条件

如需将自己的 Prometheus 实例用作 Pod 纵向自动扩缩的历史记录提供程序,您必须将其配置为抓取必要的指标,这涉及以下步骤:

  1. 如果需要,请在要将其用作 Pod 纵向自动扩缩的持久历史记录提供方的集群中部署 Prometheus 运算符。如需了解详情,请参阅如何在 Kubernetes中部署和配置 Prometheus 运算符。

  2. 配置用于抓取指标的权限。

    如需允许 Prometheus 使用配置文件从 cAdvisor 抓取指标,您必须向 Prometheus 服务器使用的服务帐号授予其他权限。创建或更新包含这些规则的 ClusterRole,并确保使用 ClusterRoleBinding 将其绑定到正确的 Prometheus 服务帐号:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
       name: prometheus-role
       labels:
          app: prometheus-server
    rules:
       - apiGroups: [""]
         resources:
           - nodes
         verbs:
           - get
           - list
           - watch
       - apiGroups: [""]
         resources:
           - nodes/proxy
           - nodes/metrics
         verbs:
           - get
        ---
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: prometheus-binding
      labels:
        app: prometheus-server
    subjects:
      - kind: ServiceAccount
        name: prometheus-server        # Service account being used by prometheus
        namespace: prometheus          # Service account's namespace
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: prometheus-role            # Name of the ClusterRole created above
    
  3. 更新 Prometheus 配置文件,以从 cAdvisor 抓取以下指标:

    • container_cpu_usage_seconds_total
    • container_memory_working_set_bytes

    以下行定义了 cAdvisor 指标的抓取详细信息:

    - job_name: 'kubernetes-cadvisor'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
        - role: node
      relabel_configs:
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)
        - target_label: __address__
          replacement: kubernetes.default.svc:443
        - source_labels: [__meta_kubernetes_node_name]
          regex: (.+)
          target_label: __metrics_path__
          replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
    
      metric_relabel_configs:
      # Keep only the metrics VPA uses to save disk space
        - source_labels: [__name__]
          regex: (container_cpu_usage_seconds_total|container_memory_working_set_bytes)
          action: keep
    
  4. 更新 Prometheus 配置文件,以从 kube-state-metrics 服务抓取以下指标:

    • kube_pod_labels
    1. 在集群上部署 kube-state-metrics 服务。

      您可以使用以下 Helm 命令安装新服务:

      helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
      helm repo update
      
    2. 创建包含以下内容的 ksm-values.yaml 文件:

      fullnameOverride: vpa-kube-state-metrics
      metricAllowlist:
        - kube_pod_labels
      metricLabelsAllowlist:
        - "pods=[*]"
      
    3. 根据上一步中的值文件安装 Helm 图表:

      helm install vpa-ksm prometheus-community/kube-state-metrics \
          -f ksm-values.yaml --namespace kube-system
      
    4. 将以下行添加到 Prometheus 配置文件,以从已安装的 kube-state-metrics 服务抓取 kube_pod_labels 指标:

      - job_name: 'kube-state-metrics'
        static_configs:
          - targets: ['vpa-kube-state-metrics.kube-system.svc.cluster.local:8080']
        metric_relabel_configs:
          - source_labels: [ __name__ ]
            regex: 'kube_pod_labels'
            action: keep
      

启用和使用 Prometheus

Pod 纵向自动扩缩支持基本身份验证和基于不记名令牌的身份验证,以连接到 Prometheus。使用身份验证时,您需要在集群命名空间中创建一个包含必要凭据的 Secret。控制器会将此 Secret 转发到目标集群,并将其装载为 Recommender Pod 中的卷或环境变量。您也可以在不进行身份验证的情况下使用 Prometheus。

如需启用自己的 Prometheus 实例并将其与 Pod 纵向自动扩缩搭配使用,您需要在集群规范的 verticalPodAutoscaling 部分中配置连接到 Prometheus 实例的详细信息。

以下示例展示了集群规范中用于不记名令牌的配置:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
  namespace: cluster-cluster1
  annotations:
    preview.baremetal.cluster.gke.io/vertical-pod-autoscaler: enable
spec:
  # ... other existing cluster configurations ...
  verticalPodAutoscaling:
    # ... other vertical Pod autoscaling configurations ...
    # Add this new section to configure the vpa to use prometheus using bearer token authentication as history provider
    prometheus:
      url: "http://prometheus.prometheus.monitoring.svc.cluster.local:9090"
      auth:
        bearerTokenAuth:
            name: prom-bearer-creds
            key: bearertoken

如需启用 Prometheus 以与 Pod 纵向自动扩缩搭配使用,请执行以下操作:

  1. 确保您的 Prometheus 实例已设置为抓取必要的指标,如 将 Prometheus 与 Pod 纵向自动扩缩 搭配使用的前提条件中所述。

  2. 更新集群自定义资源 spec,以便 verticalPodAutoscaling.prometheus 字段指定 Prometheus 服务器的连接设置。

  3. url 添加到 prometheus 部分,并将其设置为用于从集群内连接到 Prometheus 的完全限定域名 (FQDN):

    spec:
      # ... other existing cluster configurations ...
      verticalPodAutoscaling:
        # ... other vpa configurations ...
        # Add this new section to configure the vpa to use prometheus as history provider
        prometheus:
          # Required: The URL of the Prometheus server
          url: "http://prometheus.prometheus.svc.cluster.local:9090"
    
  4. 指定连接详细信息:

    Pod 纵向自动扩缩支持以下三种连接方法:

    • 无身份验证
    • 基本(用户名、密码)身份验证
    • 不记名令牌身份验证

    无身份验证

    如果您的 Prometheus 实例不需要身份验证,则无需执行任何操作。 prometheus 部分必须仅包含 url 字段。

    基本身份验证

    请按照以下步骤为 Prometheus 指定基本身份验证:

    1. 创建一个 Secret,其中包含 stringData 部分中的用户名和密码,以及 baremetal.cluster.gke.io/mark-source: "true" 注解。

      以下示例展示了支持基本身份验证的 Secret:

      apiVersion: v1
      kind: Secret
      metadata:
        name: prom-basic-creds
        namespace: <cluster-namespace>
        annotations:
          baremetal.cluster.gke.io/mark-source: "true"
      type: Opaque
      stringData:
        username: admin
        password: pwd
      

      必须添加此注解,以确保源 Secret 和目标集群中的 Secret 始终保持同步。当源 Secret 更新时,Secret 也会更新。

    2. 更新集群规范的 prometheus.auth.basicAuth 部分,以引用 Secret 的 data 字段中的用户名和密码。

      以下示例展示了一个 basicAuth 部分,该部分引用了上一步中 Secret 中的用户名和密码:

      # ... other vpa configurations ...
      prometheus:
        url: "http://prometheus.prometheus.svc.cluster.local:9090"
        auth:
          basicAuth:
            usernameRef:
              name: prom-basic-creds
              key: username
            passwordRef:
              name: prom-basic-creds
              key: password
      

      用户名和密码必须位于同一 Secret 中。密钥必须是 Secret 的 data 字段中的有效密钥。

    更新集群自定义资源后,Prometheus 实例应开始充当 Pod 纵向自动扩缩器的历史记录提供程序。

    不记名令牌身份验证

    请按照以下步骤为 Prometheus 指定不记名令牌身份验证:

    1. 创建一个 Secret,其中包含 stringData 部分中的不记名令牌,以及 baremetal.cluster.gke.io/mark-source: "true" 注解。

      以下示例展示了支持不记名令牌身份验证的 Secret:

      apiVersion: v1
      kind: Secret
      metadata:
        name: prom-bearer-creds
        namespace: <cluster-namespace>
        annotations:
          baremetal.cluster.gke.io/mark-source: "true"
      type: Opaque
      stringData:
        bearertoken: "SAMPLE_TOKEN"
      

      必须添加此注解,以确保源 Secret 和目标集群中的 Secret 始终保持同步。当源 Secret 更新时,Secret 也会更新。

    2. 更新集群规范的 prometheus.auth.bearerTokenAuth 部分,以引用 Secret 的 data 字段中的不记名令牌。

      以下示例展示了一个 bearerTokenAuth 部分,该部分引用了上一步中 Secret 中的不记名令牌:

      # ... other vertical Pod autoscaling configurations ...
      prometheus:
        url: "http://prometheus.prometheus.svc.cluster.local:9090"
        auth:
          bearerTokenAuth:
              name: prom-bearer-creds
              key: bearertoken
      

      密钥必须是 Secret 的 data 字段中的有效密钥。

    更新集群自定义资源后,Prometheus 实例应开始充当 Pod 纵向自动扩缩的历史记录提供程序。

停用 Prometheus 的使用

如需停用 Prometheus 与 Pod 纵向自动扩缩的搭配使用,请从集群自定义资源的 verticalPodAutoscaling 部分中移除 prometheus 部分。

停用 Pod 纵向自动扩缩

从集群中移除 Pod 纵向自动扩缩的自定义资源和配置,以停用该功能:

  1. 删除您创建的所有 VerticalPodAutoscaler 自定义资源。

  2. 修改集群自定义资源,并从 spec 中移除整个 verticalPodAutoscaling 部分。

    您可以直接修改集群自定义资源,也可以修改集群配置文件并使用 bmctl update

  3. 从 Cluster 自定义资源中移除 preview.baremetal.cluster.gke.io/vertical-pod-autoscaler 注释。

限制

使用 Pod 纵向自动扩缩时,请考虑以下限制:

  • Pod 纵向自动扩缩目前还无法用于 JVM 工作负载,因为对此类工作负载的实际内存用量的了解有限。
  • 更新程序要求 Deployment 至少有两个 Pod 副本,以便将 Pod 替换为修改后的资源值。
  • 更新程序不会快速更新因内存不足 (OOM) 错误而陷入崩溃循环的 Pod。
  • Pod 的 InPlaceOrRecreate 更新政策是 Pod 纵向自动扩缩功能中的一项 Alpha 版功能。它会尽力进行就地更新,但如果无法进行就地更新,可能会回退到重新创建 Pod。

后续步骤