Helm Chart repository<\/code><\/strong>.<\/li>\n<\/ol>\n\n\n\nIn this tutorial, we will use the components manifests file to install Metrics server.<\/p>\n\n\n\n
Download Metrics Server Manifests<\/h4>\n\n\n\n If you want to update the manifest configurations like resource limits,or other parameters based on your requirements, it is best to download it to your control plane for editing.<\/p>\n\n\n\n
Thus, you can download the latest Metrics server components manifest file using the command below;<\/p>\n\n\n\n
wget https:\/\/github.com\/kubernetes-sigs\/metrics-server\/releases\/latest\/download\/components.yaml<\/code><\/pre>\n\n\n\nThis is how default Metrics server components manifest file looks like;<\/p>\n\n\n\n
cat components.yaml<\/code><\/pre>\n\n\n\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server\n namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n labels:\n k8s-app: metrics-server\n rbac.authorization.k8s.io\/aggregate-to-admin: \"true\"\n rbac.authorization.k8s.io\/aggregate-to-edit: \"true\"\n rbac.authorization.k8s.io\/aggregate-to-view: \"true\"\n name: system:aggregated-metrics-reader\nrules:\n- apiGroups:\n - metrics.k8s.io\n resources:\n - pods\n - nodes\n verbs:\n - get\n - list\n - watch\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n labels:\n k8s-app: metrics-server\n name: system:metrics-server\nrules:\n- apiGroups:\n - \"\"\n resources:\n - nodes\/metrics\n verbs:\n - get\n- apiGroups:\n - \"\"\n resources:\n - pods\n - nodes\n verbs:\n - get\n - list\n - watch\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: RoleBinding\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server-auth-reader\n namespace: kube-system\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: Role\n name: extension-apiserver-authentication-reader\nsubjects:\n- kind: ServiceAccount\n name: metrics-server\n namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server:system:auth-delegator\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: system:auth-delegator\nsubjects:\n- kind: ServiceAccount\n name: metrics-server\n namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n labels:\n k8s-app: metrics-server\n name: system:metrics-server\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: system:metrics-server\nsubjects:\n- kind: ServiceAccount\n name: metrics-server\n namespace: kube-system\n---\napiVersion: v1\nkind: Service\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server\n namespace: kube-system\nspec:\n ports:\n - name: https\n port: 443\n protocol: TCP\n targetPort: https\n selector:\n k8s-app: metrics-server\n---\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server\n namespace: kube-system\nspec:\n selector:\n matchLabels:\n k8s-app: metrics-server\n strategy:\n rollingUpdate:\n maxUnavailable: 0\n template:\n metadata:\n labels:\n k8s-app: metrics-server\n spec:\n containers:\n - args:\n - --cert-dir=\/tmp\n - --secure-port=4443\n - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n - --kubelet-use-node-status-port\n - --metric-resolution=15s\n image: registry.k8s.io\/metrics-server\/metrics-server:v0.6.3\n imagePullPolicy: IfNotPresent\n livenessProbe:\n failureThreshold: 3\n httpGet:\n path: \/livez\n port: https\n scheme: HTTPS\n periodSeconds: 10\n name: metrics-server\n ports:\n - containerPort: 4443\n name: https\n protocol: TCP\n readinessProbe:\n failureThreshold: 3\n httpGet:\n path: \/readyz\n port: https\n scheme: HTTPS\n initialDelaySeconds: 20\n periodSeconds: 10\n resources:\n requests:\n cpu: 100m\n memory: 200Mi\n securityContext:\n allowPrivilegeEscalation: false\n readOnlyRootFilesystem: true\n runAsNonRoot: true\n runAsUser: 1000\n volumeMounts:\n - mountPath: \/tmp\n name: tmp-dir\n nodeSelector:\n kubernetes.io\/os: linux\n priorityClassName: system-cluster-critical\n serviceAccountName: metrics-server\n volumes:\n - emptyDir: {}\n name: tmp-dir\n---\napiVersion: apiregistration.k8s.io\/v1\nkind: APIService\nmetadata:\n labels:\n k8s-app: metrics-server\n name: v1beta1.metrics.k8s.io\nspec:\n group: metrics.k8s.io\n groupPriorityMinimum: 100\n insecureSkipTLSVerify: true\n service:\n name: metrics-server\n namespace: kube-system\n version: v1beta1\n versionPriority: 100\n<\/code><\/pre>\n\n\n\nInstall Kubernetes Metrics Server<\/h4>\n\n\n\n One thing to note before you can proceed, is that Metrics server will be communicating with the following components in the cluster;<\/p>\n\n\n\n
\nControl Plane API server<\/code><\/strong>: This is the primary way to interact with a Kubernetes cluster and the metrics that are gathered from the cluster components by Metrics server are exposed through this API for consumption by tools like Kubernetes Dashboard.<\/li>\n\n\n\nKubelet<\/code><\/strong>: Kubelet is an agent that runs on each worker node in the cluster. It exposes an API endpoint through which Metrics server will scrape the Pods\/containers resource usage metrics.<\/li>\n<\/ul>\n\n\n\nMetrics server is configured to communicate with these endpoints using TLS certificate that should be signed by cluster CA. Thus, for demo purposes you can disable the SSL\/TLS verification between the Metrics server and the above endpoints using the option, --kubelet-insecure-tls<\/code><\/strong>.<\/p>\n\n\n\nAlso, the default components manifest file defines the container port as 10250\/tcp. This port is already used by kubelet<\/strong> on the cluster;<\/p>\n\n\n\nsudo ss -atlnp | grep 10250<\/code><\/pre>\n\n\n\nLISTEN 0 4096 *:10250 *:* users:((\"kubelet\",pid=1185141,fd=20))<\/code><\/pre>\n\n\n\nHence, let’s change this to a free port, for example, 4443<\/strong>.<\/p>\n\n\n\nvim components.yaml<\/code><\/pre>\n\n\n\n\n...\n spec:\n containers:\n - args:\n - --cert-dir=\/tmp\n - --secure-port=4443<\/strong>\n - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n - --kubelet-use-node-status-port\n - --metric-resolution=15s\n - --kubelet-insecure-tls<\/strong>\n...\n name: metrics-server\n ports:\n - containerPort: 4443<\/strong>\n name: https\n protocol: TCP\n<\/code><\/pre>\n\n\n\nAlso, to avoid a situation whereby the availability status of Metric-server becomes False<\/strong> with “FailedDiscoveryCheck<\/strong>“, you need to configure the Pods created by the Metric server Deployment to use the host’s network namespace (hostNetwork: true<\/strong>). The Metrics server API service doesn’t run directly within the virtual cluster network (the overlay network used by Pods for communication), hence the use of this host network.<\/p>\n\n\n\n\n...\n spec:\n hostNetwork: true<\/strong>\n containers:\n - args:\n - --cert-dir=\/tmp\n - --secure-port=4443<\/strong>\n - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n - --kubelet-use-node-status-port\n - --metric-resolution=15s\n - --kubelet-insecure-tls<\/strong>\n...\n name: metrics-server\n ports:\n - containerPort: 4443<\/strong>\n name: https\n protocol: TCP\n<\/code><\/pre>\n\n\n\nSimilarly, to solve this “panic: unable to load configmap based request-header-client-ca-file: Get “…”: dial tcp … i\/o timeout<\/strong>“, you need to update the roles to allow access to configmaps<\/strong> resources.<\/p>\n\n\n\n...\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n labels:\n k8s-app: metrics-server\n rbac.authorization.k8s.io\/aggregate-to-admin: \"true\"\n rbac.authorization.k8s.io\/aggregate-to-edit: \"true\"\n rbac.authorization.k8s.io\/aggregate-to-view: \"true\"\n name: system:aggregated-metrics-reader\nrules:\n- apiGroups:\n - metrics.k8s.io\n resources:\n - pods\n - nodes\n - configmaps<\/strong>\n verbs:\n - get\n - list\n - watch\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n labels:\n k8s-app: metrics-server\n name: system:metrics-server\nrules:\n- apiGroups:\n - \"\"\n resources:\n - nodes\/metrics\n verbs:\n - get\n- apiGroups:\n - \"\"\n resources:\n - pods\n - nodes\n - configmaps<\/strong>\n verbs:\n - get\n - list\n - watch\n\n<\/code><\/pre>\n\n\n\nIn general, this is how our updated configuration is like.<\/p>\n\n\n\n
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server\n namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n labels:\n k8s-app: metrics-server\n rbac.authorization.k8s.io\/aggregate-to-admin: \"true\"\n rbac.authorization.k8s.io\/aggregate-to-edit: \"true\"\n rbac.authorization.k8s.io\/aggregate-to-view: \"true\"\n name: system:aggregated-metrics-reader\nrules:\n- apiGroups:\n - metrics.k8s.io\n resources:\n - pods\n - nodes\n - configmaps\n verbs:\n - get\n - list\n - watch\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n labels:\n k8s-app: metrics-server\n name: system:metrics-server\nrules:\n- apiGroups:\n - \"\"\n resources:\n - nodes\/metrics\n verbs:\n - get\n- apiGroups:\n - \"\"\n resources:\n - pods\n - nodes\n - configmaps\n verbs:\n - get\n - list\n - watch\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: RoleBinding\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server-auth-reader\n namespace: kube-system\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: Role\n name: extension-apiserver-authentication-reader\nsubjects:\n- kind: ServiceAccount\n name: metrics-server\n namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server:system:auth-delegator\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: system:auth-delegator\nsubjects:\n- kind: ServiceAccount\n name: metrics-server\n namespace: kube-system\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n labels:\n k8s-app: metrics-server\n name: system:metrics-server\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: system:metrics-server\nsubjects:\n- kind: ServiceAccount\n name: metrics-server\n namespace: kube-system\n---\napiVersion: v1\nkind: Service\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server\n namespace: kube-system\nspec:\n ports:\n - name: https\n port: 443\n protocol: TCP\n targetPort: https\n selector:\n k8s-app: metrics-server\n---\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n labels:\n k8s-app: metrics-server\n name: metrics-server\n namespace: kube-system\nspec:\n selector:\n matchLabels:\n k8s-app: metrics-server\n strategy:\n rollingUpdate:\n maxUnavailable: 0\n template:\n metadata:\n labels:\n k8s-app: metrics-server\n spec:\n hostNetwork: true\n containers:\n - args:\n - --cert-dir=\/tmp\n - --secure-port=4443\n - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\n - --kubelet-use-node-status-port\n - --metric-resolution=15s\n - --kubelet-insecure-tls\n image: registry.k8s.io\/metrics-server\/metrics-server:v0.7.1\n imagePullPolicy: IfNotPresent\n livenessProbe:\n failureThreshold: 3\n httpGet:\n path: \/livez\n port: https\n scheme: HTTPS\n periodSeconds: 10\n name: metrics-server\n ports:\n - containerPort: 4443\n name: https\n protocol: TCP\n readinessProbe:\n failureThreshold: 3\n httpGet:\n path: \/readyz\n port: https\n scheme: HTTPS\n initialDelaySeconds: 20\n periodSeconds: 10\n resources:\n requests:\n cpu: 100m\n memory: 200Mi\n securityContext:\n allowPrivilegeEscalation: false\n capabilities:\n drop:\n - ALL\n readOnlyRootFilesystem: true\n runAsNonRoot: true\n runAsUser: 1000\n seccompProfile:\n type: RuntimeDefault\n volumeMounts:\n - mountPath: \/tmp\n name: tmp-dir\n nodeSelector:\n kubernetes.io\/os: linux\n priorityClassName: system-cluster-critical\n serviceAccountName: metrics-server\n volumes:\n - emptyDir: {}\n name: tmp-dir\n---\napiVersion: apiregistration.k8s.io\/v1\nkind: APIService\nmetadata:\n labels:\n k8s-app: metrics-server\n name: v1beta1.metrics.k8s.io\nspec:\n group: metrics.k8s.io\n groupPriorityMinimum: 100\n insecureSkipTLSVerify: true\n service:\n name: metrics-server\n namespace: kube-system\n version: v1beta1\n versionPriority: 100\n<\/code><\/pre>\n\n\n\nOpen the metrics server port on firewall on all cluster nodes.<\/p>\n\n\n\n
If using UFW;<\/p>\n\n\n\n
sudo ufw allow 4443\/tcp<\/code><\/pre>\n\n\n\nIf using something else other than ufw, open the port accordingly.<\/p>\n\n\n\n
You can now install Metrics server by applying the Metrics server components manifest configuration file using the command below.<\/p>\n\n\n\n
kubectl apply -f components.yaml<\/code><\/pre>\n\n\n\nSimilarly, if you want to directly install the Metrics server without modifying the default configs, then you can execute the command below;<\/p>\n\n\n\n
kubectl apply -f https:\/\/github.com\/kubernetes-sigs\/metrics-server\/releases\/latest\/download\/components.yaml<\/code><\/pre>\n\n\n\nVerify Kubernetes Metrics Server Installation<\/h3>\n\n\n\n You can now verify the installation of Metric server on Kubernetes.<\/p>\n\n\n\n
Based on the components manifest configuration above, a deployment called metrics-server<\/code><\/strong> will be created under the kube-system<\/code><\/strong> namespace.<\/p>\n\n\n\nTo get the details of the Metrics server deployment, run the command below;<\/p>\n\n\n\n
kubectl get deployment metrics-server -n kube-system<\/code><\/pre>\n\n\n\nSample output;<\/p>\n\n\n\n
\nNAME READY UP-TO-DATE AVAILABLE AGE\nmetrics-server 1\/1 1 1 8m16s\n<\/code><\/pre>\n\n\n\nA Pod is also created;<\/p>\n\n\n\n
kubectl get pods -n kube-system<\/code><\/pre>\n\n\n\n\nNAME READY STATUS RESTARTS AGE\n...\nmetrics-server-7b4c4d4bfd-rdz8t 1\/1 Running 0 9m21s\n<\/code><\/pre>\n\n\n\nCheck API Services;<\/p>\n\n\n\n
kubectl get apiservices<\/code><\/pre>\n\n\n\n...\nv1beta1.metrics.k8s.io kube-system\/metrics-server True 11m\n<\/code><\/pre>\n\n\n\nCheck Kubernetes Pods\/Nodes CPU and Memory Usage<\/h3>\n\n\n\n After the installation, the Metrics server will now start collecting resource usage information from the cluster.<\/p>\n\n\n\n
Let’s run top command to check CPU and Memory usage of the Pods in the default namespace;<\/p>\n\n\n\n
kubectl top pods<\/code><\/pre>\n\n\n\n\nNAME CPU(cores) MEMORY(bytes) \nnagios-core-deployment-694b75b55b-845mh 2m 32Mi \nnagios-core-deployment-694b75b55b-8lflz 2m 32Mi \nnagios-core-deployment-694b75b55b-hrw4n 3m 31Mi\n<\/code><\/pre>\n\n\n\nShow metrics for all pods in the given namespace;<\/p>\n\n\n\n
kubectl top pod --namespace=NAMESPACE<\/code><\/pre>\n\n\n\nShow metrics for a given pod and its containers;<\/p>\n\n\n\n
kubectl top pod POD_NAME --containers<\/code><\/pre>\n\n\n\nCheck nodes;<\/p>\n\n\n\n
kubectl top nodes<\/code><\/pre>\n\n\n\nNAME CPU(cores) CPU% MEMORY(bytes) MEMORY% \nmaster.kifarunix.com 449m 22% 1516Mi 39% \nwk01.kifarunix.com 120m 6% 1022Mi 26% \nwk02.kifarunix.com 46m 2% 1035Mi 27% \nwk03.kifarunix.com 76m 3% 812Mi 21%\n<\/code><\/pre>\n\n\n\nView Metrics on Kubernetes Dashboard<\/h3>\n\n\n\n You can install Kubernetes dashboard and used it to view Pods\/containers metrics;<\/p>\n\n\n\n
Easy Way to Install Kubernetes Dashboard on Ubuntu 22.04\/20.04<\/a><\/p>\n\n\n\n <\/figure>\n\n\n\nKubernetes Dashboard automatically integrates with the Metrics Server. The Metrics Server provides the necessary resource utilization metrics, such as CPU and memory usage, which the Dashboard utilizes to display information and statistics about your cluster.<\/p>\n\n\n\n
Other Tutorials<\/h2>\n\n\n\n What are the core concepts in Kubernetes?<\/a><\/p>\n\n\n\nKubernetes Architecture: A High-level Overview of Kubernetes Cluster Components<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"This tutorial provides a step-by-step guide on how to install Kubernetes Metrics server on a Kubernetes cluster. Kubernetes Metrics Server plays a vital role in<\/p>\n","protected":false},"author":10,"featured_media":16794,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_lock_modified_date":false,"footnotes":""},"categories":[1076,1077,121,1668],"tags":[6774,6775,6777,6776],"class_list":["post-16789","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-containers","category-docker","category-howtos","category-kubernetes","tag-install-metrics-server-on-kubernetes","tag-kubernetes-metrics-server","tag-step-by-step-guide-how-to-install-metrics-server-on-kubernetes","tag-view-kubernetes-metrics-on-dashboard","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50","resize-featured-image"],"_links":{"self":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/16789"}],"collection":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/comments?post=16789"}],"version-history":[{"count":15,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/16789\/revisions"}],"predecessor-version":[{"id":22688,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/16789\/revisions\/22688"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media\/16794"}],"wp:attachment":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media?parent=16789"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/categories?post=16789"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/tags?post=16789"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}