Skip to main content

`kubectl top` Returned Nothing. The Cause Was a Missing metrics-server — K3s Never Has That Problem

section01

You took a Horizontal Pod Autoscaler (HPA) manifest you'd validated on K3s and applied it, unchanged, to a standard Kubernetes cluster bootstrapped with kubeadm. kubectl top returned nothing, and HPA never scaled a single replica. Plenty of infrastructure engineers have hit exactly this wall. The cause is usually something surprisingly basic: whether metrics-server is present at all. Something that just worked on K3s simply doesn't exist yet on standard Kubernetes. This article walks through why that gap exists, backed by official documentation, and how to diagnose it.

1. The Day kubectl top Went Silent

section02

The story is simple enough. A Deployment with HPA attached, built and tested on a K3s environment, gets moved to a production-equivalent standard Kubernetes cluster bootstrapped with kubeadm. The manifest itself hasn't changed. But kubectl top pods returns nothing, and the HPA status sits stuck at unknown.

The official Kubernetes HPA walkthrough spells out the prerequisite plainly:

To follow this walkthrough, you also need to use a cluster that has a Metrics Server deployed and configured.

In other words, using HPA requires Metrics Server to be deployed and correctly configured as a baseline assumption. On K3s, that assumption was already satisfied, so nobody ever had to think about it. On standard Kubernetes, it's a condition you have to satisfy yourself.

2. Why K3s Ships metrics-server by Default

section03

The official K3s "Packaged Components" documentation spells out exactly which addons K3s bundles by default:

K3s comes with a number of packaged components that are deployed as AddOns via the manifests directory: coredns, traefik, local-storage, and metrics-server.

Alongside coredns (DNS), traefik (Ingress), and local-storage (local volume provisioning), metrics-server is explicitly listed as one of the standard components. These manifests are placed automatically under /var/lib/rancher/k3s/server/manifests and get deployed the moment K3s starts, in a process similar to kubectl apply. The same fact is confirmed in SUSE's official documentation.

K3s is designed around the goal of "running Kubernetes from a lightweight single binary," and that design philosophy extends to bundling the minimum set of addons needed for real operation. The existence of documented steps to disable metrics-server is itself proof that it's enabled by default. Both kubectl top and HPA work the moment the cluster comes up. Kubo, a managed service built on K3s, inherits this same bundling policy.

3. Why Standard Kubernetes (kubeadm) Doesn't Include metrics-server

section04

kubeadm, on the other hand, is a tool focused on providing a minimal control plane. CNI, an Ingress Controller, and metrics-server are all addons that fall outside what kubeadm installs.

The official Kubernetes "Resource metrics pipeline" documentation states this directly:

You must deploy the metrics-server or alternative adapter that serves the Metrics API to be able to access it.

The same page positions metrics-server as a "cluster addon component" and explains that HPA, VPA, and kubectl top all depend on the Metrics API it provides. In short: just because you created a cluster with kubeadm doesn't mean HPA, VPA, or kubectl top will work out of the box.

Installing it isn't hard. You can apply the components.yaml manifest from the official metrics-server repository with a single command:

bash
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

The problem is that teams migrating from K3s are the ones most likely to forget — or never know — this step existed in the first place. A step nobody on K3s ever had to think about becomes a mandatory extra task on standard Kubernetes. Even managed services built on standard Kubernetes, like EKS or AKS, often leave this kind of addon installation as the customer's responsibility. Kubo Cloud is built on K3s and delivers Pure Kubernetes, so this initial setup burden never arises in the first place.

4. What Breaks When metrics-server Is Missing

section05

When metrics-server is absent, or its Pod isn't running, trying to run HPA typically produces an error like this:

text
failed to get cpu utilization: unable to get metrics for resource cpu: no metrics returned from resource metrics API

A troubleshooting guide aimed at on-call engineers lays out a diagnostic sequence for exactly this error:

  1. Confirm metrics-server exists
    bash
    kubectl get deployment metrics-server -n kube-system
    kubectl get pods -n kube-system -l k8s-app=metrics-server
    
  2. Confirm metrics are actually being returned
    bash
    kubectl top nodes
    kubectl top pods -n default
    
  3. Confirm the API service registration
    bash
    kubectl get apiservices | grep metrics
    
    Check whether v1beta1.metrics.k8s.io shows a Status of True. If it's False, metrics-server itself likely has a startup problem.

Working through these three steps immediately tells you whether you're looking at an HPA misconfiguration or a missing metrics-server altogether. Teams that have only ever worked with K3s often don't even know this diagnostic sequence exists.

5. Bundled and Self-Installed metrics-server Don't Always Behave the Same

section06

There's one more wrinkle worth watching for: "I installed metrics-server, but it behaves differently than it did on K3s." According to an article explaining metrics-server resource monitoring, the binary's own default for --metric-resolution is 60 seconds, but the official manifest sets it to --metric-resolution=15s. Which value is actually running changes how fresh the metrics are that HPA uses to make scaling decisions.

On top of that, flags like --kubelet-insecure-tls, used to tolerate kubelets with self-signed certificates, can be enabled or disabled differently depending on the distribution and install method. The configuration bundled with K3s and the configuration you get from applying components.yaml yourself are not guaranteed to match. If HPA feels like it's reacting at a different speed than it used to "on the same metrics-server," this configuration gap is the first thing to suspect.

On small clusters, it's also worth paying attention to metrics-server's own resource footprint. Typical startup requirements are cited at around 100m CPU / 200Mi memory in requests, and that overhead isn't negligible on nodes already under resource pressure.

Conclusion: On a K3s Foundation, This Problem Never Comes Up

Most cases where HPA or kubectl top don't work aren't misconfigurations — they're a missing prerequisite: metrics-server. K3s bundles it by default, so this problem simply doesn't occur. If you're running standard Kubernetes (kubeadm) yourself, you need to turn metrics-server installation and flag configuration into a checklist you run every time.

The difference between "it just works" and "you run a checklist every time" quietly adds up as operational cost. Kubo is a managed Kubernetes service built on K3s, where standard addons including metrics-server work from the moment the cluster is up. If you're spending this kind of setup effort on AWS EKS or Azure AKS, you can try the same Pure Kubernetes setup starting at ¥48,000/month.

This kind of "invisible gap in default assumptions" when migrating clusters shows up far beyond just HPA and metrics-server. If you're carrying similar overhead running standard Kubernetes on your own, feel free to get in touch to talk through what a Kubo setup would look like.

Related articles

← Back to all posts