How to install Kubernetes Metrics Server

Kubernetes Metrics Server provides the resource metrics API that kubectl top and CPU or memory based autoscaling read from the cluster. Installing it adds a small kube-system workload that scrapes kubelets and exposes recent pod and node CPU and memory usage through the aggregated API server.

The upstream manifest is the direct installation path for most clusters. It creates the metrics-server Deployment, Service, RBAC rules, and v1beta1.metrics.k8s.io APIService, then the API server makes the metrics endpoint available to normal kubectl requests.

Metrics Server is not a full monitoring backend and should not replace Prometheus, long-term storage, or application observability. It also depends on cluster requirements that some local or custom distributions do not enable by default, including the aggregation layer, kubelet webhook authentication and authorization, and kubelet serving certificates trusted by the cluster CA.

Steps to install Kubernetes Metrics Server from the upstream manifest:

  1. Confirm that kubectl can reach the target cluster.
    $ kubectl get nodes
    NAME            STATUS   ROLES           AGE   VERSION
    control-plane   Ready    control-plane   4m    v1.36.1

    Use a context with permission to create cluster-wide RBAC objects, APIService objects, and workloads in /kube-system.
    Related: How to check Kubernetes cluster access

  2. Apply the latest upstream Metrics Server manifest.
    $ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
    serviceaccount/metrics-server created
    clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
    clusterrole.rbac.authorization.k8s.io/system:metrics-server created
    rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
    clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
    clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
    service/metrics-server created
    deployment.apps/metrics-server created
    apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created

    The latest manifest tracks the current Metrics Server release. For clusters pinned to an older supported Kubernetes minor release, use the matching release manifest from the upstream release page instead of the floating URL.

  3. Wait for the metrics-server Deployment to become available.
    $ kubectl rollout status deployment metrics-server --namespace kube-system --timeout=120s
    deployment "metrics-server" successfully rolled out
  4. Patch only a disposable local cluster when kubelet serving certificates are not trusted.
    $ kubectl patch deployment metrics-server --namespace kube-system --type=json --patch='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
    deployment.apps/metrics-server patched

    Skip this step on production or managed clusters unless the platform documentation explicitly requires it. The --kubelet-insecure-tls flag disables kubelet certificate verification and is mainly a lab-cluster workaround for errors such as x509: cannot validate certificate.

  5. Wait for the patched Deployment when the local-cluster workaround was needed.
    $ kubectl rollout status deployment metrics-server --namespace kube-system --timeout=120s
    deployment "metrics-server" successfully rolled out
  6. Check that the aggregated Metrics API is registered.
    $ kubectl get apiservice v1beta1.metrics.k8s.io
    NAME                     SERVICE                      AVAILABLE   AGE
    v1beta1.metrics.k8s.io   kube-system/metrics-server   True        3m

    A False state means the API server cannot use the Metrics Server Service yet. Check the APIService condition and the metrics-server Pod logs before trusting kubectl top output.

  7. Confirm that node metrics are returned.
    $ kubectl top node
    NAME            CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
    control-plane   205m         2%       784Mi           6%

    Metrics may need a short scrape interval after rollout before the first values appear.

  8. Confirm that pod metrics are returned for the Metrics Server Pod.
    $ kubectl top pod --namespace kube-system --selector k8s-app=metrics-server
    NAME                              CPU(cores)   MEMORY(bytes)
    metrics-server-55bf4495db-qtqn5   6m           21Mi

    Use kubectl top pod --all-namespaces or a specific namespace after this check when the goal is workload usage review.
    Related: How to check Kubernetes resource usage