We are going to deploy a kube-state-metrics service to generates metrics about the state of our Kubernetes objects. The metrics are exported on the HTTP endpoint /metrics
on the listening port TCP 8080.
Pre-requisites
We are using our Kubernetes homelab to deploy kube-state-metrics.
Download Files from GitHub
Configuration files used in this article are hosted on GitHub. Clone the following repository:
$ git clone https://github.com/lisenet/kubernetes-homelab.git
TLDR; Install and Configure kube-state-metrics: All in One Go
Create a monitoring namespace:
$ kubectl create ns monitoring
Create everything with a single command:
$ kubectl apply -f kubernetes-homelab/kube-state-metrics/
Install and Configure kube-state-metrics: Step by Step
Step by step instructions. Note that this homelab project is under development, therefore please refer to GitHub for any source code changes.
Create a Namespace
Create a monitoring namespace:
$ kubectl create ns monitoring
Create Cluster Role and Service Account
$ kubectl apply -f kubernetes-homelab/kube-state-metrics/kube-state-metrics-cluster-role.yml
This is what the code looks like:
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: kube-state-metrics labels: app: kube-state-metrics rules: - verbs: - list - watch apiGroups: - certificates.k8s.io resources: - certificatesigningrequests - verbs: - list - watch apiGroups: - '' resources: - configmaps - verbs: - list - watch apiGroups: - batch resources: - cronjobs - verbs: - list - watch apiGroups: - extensions - apps resources: - daemonsets - verbs: - list - watch apiGroups: - extensions - apps resources: - deployments - verbs: - list - watch apiGroups: - '' resources: - endpoints - verbs: - list - watch apiGroups: - autoscaling resources: - horizontalpodautoscalers - verbs: - list - watch apiGroups: - extensions - networking.k8s.io resources: - ingresses - verbs: - list - watch apiGroups: - batch resources: - jobs - verbs: - list - watch apiGroups: - '' resources: - limitranges - verbs: - list - watch apiGroups: - admissionregistration.k8s.io resources: - mutatingwebhookconfigurations - verbs: - list - watch apiGroups: - '' resources: - namespaces - verbs: - list - watch apiGroups: - networking.k8s.io resources: - networkpolicies - verbs: - list - watch apiGroups: - '' resources: - nodes - verbs: - list - watch apiGroups: - '' resources: - persistentvolumeclaims - verbs: - list - watch apiGroups: - '' resources: - persistentvolumes - verbs: - list - watch apiGroups: - policy resources: - poddisruptionbudgets - verbs: - list - watch apiGroups: - '' resources: - pods - verbs: - list - watch apiGroups: - extensions - apps resources: - replicasets - verbs: - list - watch apiGroups: - '' resources: - replicationcontrollers - verbs: - list - watch apiGroups: - '' resources: - resourcequotas - verbs: - list - watch apiGroups: - '' resources: - secrets - verbs: - list - watch apiGroups: - '' resources: - services - verbs: - list - watch apiGroups: - apps resources: - statefulsets - verbs: - list - watch apiGroups: - storage.k8s.io resources: - storageclasses - verbs: - list - watch apiGroups: - admissionregistration.k8s.io resources: - validatingwebhookconfigurations - verbs: - list - watch apiGroups: - storage.k8s.io resources: - volumeattachments --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kube-state-metrics labels: app: kube-state-metrics subjects: - kind: ServiceAccount name: kube-state-metrics namespace: monitoring roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kube-state-metrics --- apiVersion: v1 kind: ServiceAccount metadata: name: kube-state-metrics namespace: monitoring labels: app: kube-state-metrics secrets: - name: kube-state-metrics-token
Create a Deployment Configuration
$ kubectl apply -f kubernetes-homelab/kube-state-metrics/kube-state-metrics-deployment.yml
This is what the code looks like:
--- apiVersion: apps/v1 kind: Deployment metadata: name: kube-state-metrics namespace: monitoring labels: app: kube-state-metrics spec: replicas: 1 selector: matchLabels: app: kube-state-metrics template: metadata: labels: app: kube-state-metrics spec: serviceAccountName: kube-state-metrics serviceAccount: kube-state-metrics securityContext: runAsUser: 65534 runAsGroup: 65534 fsGroup: 65534 containers: - name: kube-state-metrics image: 'quay.io/coreos/kube-state-metrics:v1.9.7' imagePullPolicy: IfNotPresent ports: - containerPort: 8080 protocol: TCP resources: {} livenessProbe: httpGet: path: /healthz port: 8080 scheme: HTTP initialDelaySeconds: 5 timeoutSeconds: 5 periodSeconds: 10 successThreshold: 1 failureThreshold: 3 readinessProbe: httpGet: path: / port: 8080 scheme: HTTP initialDelaySeconds: 5 timeoutSeconds: 5 periodSeconds: 10 successThreshold: 1 failureThreshold: 3 restartPolicy: Always terminationGracePeriodSeconds: 30
Create a Service
$ kubectl apply -f kubernetes-homelab/kube-state-metrics/kube-state-metrics-service.yml
This is what the code looks like:
--- apiVersion: v1 kind: Service metadata: name: kube-state-metrics namespace: monitoring annotations: prometheus.io/scrape: 'true' prometheus.io/port: '8080' labels: app: kube-state-metrics spec: selector: app: kube-state-metrics type: ClusterIP ports: - port: 8080 targetPort: 8080
Check Monitoring Namespace
$ kubectl -n monitoring get all -l app=kube-state-metrics NAME READY STATUS RESTARTS AGE pod/kube-state-metrics-5f44d96774-2zcl4 1/1 Running 0 6d3h NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kube-state-metrics ClusterIP 10.100.211.238 none 8080/TCP 6d3h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/kube-state-metrics 1/1 1 1 6d3h NAME DESIRED CURRENT READY AGE replicaset.apps/kube-state-metrics-5f44d96774 1 1 1 6d3h