Securely Install Kubernetes Metrics Server

Introduction
Metrics Server provides information about CPU and memory usage for all pods across your Kubernetes cluster. Its primary purpose is autoscaling, but it can also be used to view resource usage in a UI, such as Lens. By default, you may encounter a "Failed to scrape node" error, with the quickest fix being the addition of the --kubelet-insecure-tls argument. However, I will show you a more secure way to resolve this issue.
Prerequisites
- A Kubernetes cluster deployed using
kubeadm
. - Flux System (FluxCD) installed and configured. See How to install Flux System with Git.
Step-by-step Guide
Even though I used FluxCD, you can also use a standard Helm command.
-
Enable TLS bootstrapping
Ensure that
serverTLSBootstrap
is set totrue
when bootstrapping the Kubernetes cluster:apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration serverTLSBootstrap: true
If not, you can update the Kubelet configuration by editing the
kubelet-config
ConfigMap and adding theserverTLSBootstrap: true
option. Then, apply the changes by running the following command on all nodes:sudo kubeadm upgrade node phase kubelet-config sudo systemctl restart kubelet
-
Install
kubelet-csr-approver
Since my node hostname starts with
pi*
, I use providerRegex:^(pi)\d+$
for the configuration. This enables automatic approval for any CSR that matches the regular expression. Seerelease.yaml
file on Github:kubectl create -f https://github.com/harrytang/k8s/raw/refs/heads/main/clusters/pi/kube-system/csr-approver/repository.yaml kubectl create -f https://github.com/harrytang/k8s/raw/refs/heads/main/clusters/pi/kube-system/csr-approver/release.yaml
Verify by executing the following command:
kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION csr-7s6sp 2m18s kubernetes.io/kubelet-serving system:node:pi3 <none> Approved,Issued csr-jrmjs 41s kubernetes.io/kubelet-serving system:node:pi5 <none> Approved,Issued csr-mbvss 2m17s kubernetes.io/kubelet-serving system:node:pi6 <none> Approved,Issued csr-mr9v8 5m57s kubernetes.io/kubelet-serving system:node:pi1 <none> Approved,Issued csr-thf2p 100s kubernetes.io/kubelet-serving system:node:pi4 <none> Approved,Issued csr-vr5fm 4m kubernetes.io/kubelet-serving system:node:pi2 <none> Approved,Issued
-
Install Metrics Server
kubectl create -f https://github.com/harrytang/k8s/raw/refs/heads/main/clusters/pi/kube-system/metrics-server/repository.yaml kubectl create -f https://github.com/harrytang/k8s/raw/refs/heads/main/clusters/pi/kube-system/metrics-server/release.yaml
You can check the installation status; all pods should be in the Running state:
kubectl -n kube-system get pods NAME READY STATUS RESTARTS AGE kubelet-csr-approver-6d695fc9c6-cxgf4 1/1 Running 0 126m kubelet-csr-approver-6d695fc9c6-tnks9 1/1 Running 0 126m metrics-server-6fdb59879c-klbh4 1/1 Running 0 123m metrics-server-6fdb59879c-s7pcf 1/1 Running 0 124m ...
Conclusion
As you can see, there is no need to add the --kubelet-insecure-tls
argument to the Metrics Server. Here are some screenshots from Lens showing metric information: