Resource monitoring and Pod autoscaling

Managing application resources well is critical for performance, stability, and cost-efficiency. Cloudfleet provides two tools for this: the kubectl top command for real-time resource monitoring, and Horizontal Pod Autoscaling (HPA). HPA is a standard Kubernetes feature that automatically adjusts your application’s scale to meet demand.

The first step is to understand your resource consumption. The kubectl top command shows how your nodes and Pods use CPU and memory. Use this information to identify bottlenecks, optimize resource requests and limits, and make informed scaling decisions.

After you understand your resource patterns, use Horizontal Pod Autoscaling (HPA) to make your applications respond to changes in load. Your application automatically scales out (adds Pods) during peak traffic and scales in (removes Pods) during quieter periods. You get high availability without overprovisioning.

Cloudfleet’s node auto-provisioning feature increases the benefits of HPA:

  • Efficient scale-out: When HPA adds Pods because demand increases and your current nodes lack capacity, node auto-provisioning creates new nodes. Your application scales without manual intervention.

  • Cost-effective scale-in: When HPA reduces the number of Pods as demand drops, node auto-provisioning can remove underutilized or empty nodes. You pay only for the infrastructure you actively use.

Your entire stack, from Pods to nodes, scales efficiently and economically. For more details on node auto-provisioning, see the Node auto-provisioning documentation.

Monitoring resource usage with kubectl top

The kubectl top command shows a snapshot of resource consumption (CPU and memory) for nodes and Pods in your cluster. Use it for real-time monitoring.

Overview

The kubectl top command fetches resource metrics from the Metrics Server. The Metrics Server is an integral component of your Cloudfleet Kubernetes cluster and collects data on CPU and memory usage.

Viewing node metrics

To display CPU and memory usage for all nodes in the cluster:

bash
kubectl top nodes

Example output:

bash
NAME            CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
node-worker-1   150m         7%     1750Mi          45%
node-worker-2   220m         11%    2500Mi          62%
...

Viewing Pod metrics

To display CPU and memory usage for Pods:

For Pods in the current (default) namespace:

bash
kubectl top pods

For Pods in a specific namespace:

bash
kubectl top pods -n <your-namespace>

For Pods across all namespaces:

bash
kubectl top pods --all-namespaces

Example output (for a single namespace):

bash
NAME                                 CPU(cores)   MEMORY(bytes)
my-app-deployment-7b5d8f9c4f-abcde   55m          130Mi
my-app-deployment-7b5d8f9c4f-fghij   60m          135Mi
another-service-pod-xyz123           100m         240Mi
...

For more command options, see the official kubectl top documentation.

Horizontal Pod autoscaling (HPA)

Horizontal Pod Autoscaling (HPA) automatically scales the number of Pods in a Deployment, ReplicaSet, StatefulSet, or ReplicationController. HPA bases scaling on observed CPU utilization or other custom metrics.

How HPA works

The HPA controller is part of the Kubernetes control plane. It periodically checks metrics from the Metrics Server and compares them against the target values you define in a HorizontalPodAutoscaler resource.

  • Scaling out: If the observed metric (for example, average CPU utilization) exceeds your target, the HPA controller increases the number of Pod replicas.
  • Scaling in: If the observed metric falls below your target, the HPA controller decreases the number of Pod replicas, but not below the minimum you set.

Your application keeps its performance under load and conserves resources when demand is low.

Cloudfleet supports standard Kubernetes HPA. Configuration and management follow standard Kubernetes practices. The Metrics Server, which HPA relies on for CPU and memory data, is a core component of your Cloudfleet cluster.

This example creates an HPA that targets a Deployment named my-app-deployment. It aims to keep an average CPU utilization of 60% across all its Pods, and scales between 1 and 10 replicas.

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
  namespace: default # Or your specific namespace
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app-deployment # Name of the Deployment to scale
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        # The target average CPU utilization over all the pods,
        # represented as a percentage of the requested CPU.
        averageUtilization: 60

To apply this example, save the YAML to a file (for example, my-app-hpa.yaml) and apply it with kubectl:

bash
kubectl apply -f my-app-hpa.yaml

To check the status of your HPA, run:

bash
kubectl get hpa my-app-hpa

The output is similar to this:

bash
NAME         REFERENCE                      TARGETS   MINPODS   MAXPODS   REPLICAS     AGE
my-app-hpa   Deployment/my-app-deployment   25%/60%   1         10        3            15m

The output shows the following information:

  • NAME: The name of your HPA resource (my-app-hpa).
  • REFERENCE: The workload that HPA scales (Deployment/my-app-deployment).
  • TARGETS: The current metric utilization compared to the target. In this example, 25%/60% means the current average CPU utilization across Pods is 25%, and the target is 60%. If no Pods are running or metrics are not yet available, you might see <unknown>/60%.
  • MINPODS: The minimum number of replicas configured (1).
  • MAXPODS: The maximum number of replicas configured (10).
  • REPLICAS: The current number of running replicas (3).

To get more details about the HPA, describe it:

bash
kubectl describe hpa my-app-hpa

For details on HPA configuration, supported metrics (including custom and external metrics), and advanced features, see the official Kubernetes HPA documentation.

Scenario: HPA scales up and node auto-provisioning responds

This scenario shows how HPA and Cloudfleet’s node auto-provisioning work together to scale your cluster automatically. Here is what happens when HPA scales up your application and the existing nodes lack capacity:

  1. Increased load and HPA reaction: The load on your application increases (for example, higher CPU usage). The HPA controller detects that the current average resource utilization (for example, CPU) across your Pods exceeds the target defined in your HorizontalPodAutoscaler resource.

  2. HPA scales out Pods: HPA increases the number of Pod replicas for your Deployment, ReplicaSet, or StatefulSet to meet the demand.

  3. Pod scheduling attempt: The Kubernetes scheduler tries to place the new Pods on available nodes in the cluster.

  4. Insufficient resources and pending Pods: Existing nodes may lack the allocatable resources (CPU, memory, and so on) for one or more new Pods. These Pods then enter the Pending state. To see this, run kubectl get pods. The events for a pending Pod (shown by kubectl describe pod <pod-name>) might indicate reasons like FailedScheduling due to insufficient resources.

  5. Node auto-provisioning detects need: Cloudfleet’s node auto-provisioning constantly monitors for unschedulable Pods. It identifies that Pods are pending due to a lack of resources.

  6. New node provisioning: The node auto-provisioner checks your Fleet constraints, such as allowed regions and instance families, and your Fleet CPU limits. If a new node would let the pending Pods be scheduled, the node auto-provisioner creates a new virtual machine and adds it to your Kubernetes cluster. Node creation typically takes a few minutes. During this time, the Pods stay Pending.

  7. Node joins cluster: After the new node joins the Kubernetes cluster, it is available for scheduling workloads.

  8. Pods scheduled on new node: The Kubernetes scheduler detects the new node and its available resources. It schedules the previously Pending Pods on this new node.

  9. Application capacity increased: The new Pods move to the Running state. Your application now has more capacity to handle the higher load, with no manual steps.

With Horizontal Pod Autoscaling and node auto-provisioning together, your applications scale from the Pod level up to the infrastructure level without manual intervention. Resource utilization stays efficient.

On this page