🇧🇷 Leia a versão em português aqui.
Commands like kubectl top nodes or kubectl top pods don't work by default in a freshly created Kubernetes cluster — and the horizontal autoscaler (HPA), used to automatically scale applications based on CPU, also depends on a metrics source to work. The component responsible for providing this data is the Metrics Server.
In this article, I show how to install the Metrics Server and, most importantly, how to solve the most common issue when installing it in on-premise clusters: the lack of valid TLS certificates between nodes.
Installing the Metrics Server
The standard installation is done by applying the project's official manifest directly to the cluster:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
This creates a Deployment in the kube-system namespace, responsible for periodically collecting CPU and memory usage metrics from all nodes and pods in the cluster.
Checking that it works
First, confirm that the Metrics Server pod came up correctly:
kubectl get pods --all-namespaces
Look for a pod named something like metrics-server-xxxxxxxxxx-xxxxx and check that its status is Running.
Then, test the commands that depend on it:
kubectl top nodes
Or:
kubectl top pods --all-namespaces
If both return CPU and memory usage data, everything is working.
When it doesn't work: the TLS issue in on-premise clusters
In cloud-managed clusters, nodes usually have valid, recognized certificates for the Metrics Server. But in on-premise environments, it's common for the Metrics Server to fail to communicate with each node's kubelet, getting stuck in an error state (the pod stays Running, but top commands return an error or "not found").
This happens because, by default, the Metrics Server tries to validate the kubelet's TLS certificate — and without a properly configured certificate chain between the nodes, that validation fails.
Manually fixing the manifest
To work around this, download the manifest locally instead of applying it directly from the URL:
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Edit the file:
vim components.yaml
And adjust the metrics-server container's arguments, adding the --kubelet-insecure-tls flag (which disables strict validation of the kubelet's certificate) and other compatibility flags:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=10250
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls
image: registry.k8s.io/metrics-server/metrics-server:v0.7.2
imagePullPolicy: IfNotPresent
⚠️ The
--kubelet-insecure-tlsflag disables verification of the kubelet's certificate — an acceptable solution for internal and lab environments, but one that reduces communication security. For production, the ideal approach is to properly set up the cluster's certificate chain instead of bypassing validation.
After editing, apply the updated manifest:
kubectl apply -f components.yaml
And test again:
kubectl top nodes
kubectl top pods --all-namespaces
Why this matters
Besides making it easier to manually diagnose the cluster (quickly seeing which nodes or pods are consuming the most resources), the Metrics Server is a prerequisite for the Horizontal Pod Autoscaler (HPA) — the feature that automatically scales the number of replicas of an application based on CPU usage, as we saw when configuring autoscaling for a Deployment in earlier articles of this Kubernetes journey. Without the Metrics Server working, the kubectl get hpa command shows resource usage as <unknown>, and the autoscaler simply doesn't scale anything.
Top comments (0)