From 92304f364ef8ca22f9f9bee3c5fd808ef5da6675 Mon Sep 17 00:00:00 2001 From: Parin Patel <8746551+parinapatel@users.noreply.github.com> Date: Fri, 17 Jan 2020 17:37:10 -0500 Subject: [PATCH] Support Label Selector and Namespace whitelisting. (#32) * Support for Label Selector and Namespace whitelisting * Reset README.md * Removed unused arguments. --- README.md | 6 ++++-- app.py | 36 ++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 52ad147..e7ecd1d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ # metrics-server-exporter [![CircleCI](https://circleci.com/gh/grupozap/metrics-server-exporter.svg?style=svg)](https://circleci.com/gh/grupozap/metrics-server-exporter) [![Total alerts](https://img.shields.io/lgtm/alerts/g/grupozap/metrics-server-exporter.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/grupozap/metrics-server-exporter/alerts/) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/grupozap/metrics-server-exporter.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/grupozap/metrics-server-exporter/context:python) - metrics-server-exporter provides cpu and memory metrics for nodes and pods, directly querying the metrics-server API `/apis/metrics.k8s.io/v1beta1/{pods, nodes}` ### Node metrics @@ -47,7 +46,10 @@ metrics-server-exporter provides cpu and memory metrics for nodes and pods, dire * NAMES_BLACKLIST * A list of names from pods, containers or namespaces to exclude from metrics. - + * NAMESPACE_WHITELIST + * A list of namespace to scrape from this way you can create namespaced rolebinding instead of cluster binding. ( quite useful for larger clusters ) ( default : '' (all namespaces)) + * LABEL_SELECTOR + * A list of Label Selectors. ### Options * --insecure-tls diff --git a/app.py b/app.py index 2ddc63c..7818c6f 100644 --- a/app.py +++ b/app.py @@ -2,7 +2,6 @@ import datetime import getopt -import json import os import requests import string @@ -22,8 +21,11 @@ def __init__(self): self.ca_cert = os.environ.get('K8S_CA_CERT_PATH', '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt') self.api_url = os.environ.get('K8S_ENDPOINT', 'https://kubernetes.default.svc') self.names_blacklist = os.environ.get('NAMES_BLACKLIST', '').split(',') + self.namespaces = os.environ.get('NAMESPACE_WHITELIST','').split(',') + self.labelSelector = os.environ.get('LABEL_SELECTOR','') + self.api_nodes_url = "{}/apis/metrics.k8s.io/v1beta1/nodes".format(self.api_url) - self.api_pods_url = "{}/apis/metrics.k8s.io/v1beta1/pods".format(self.api_url) + self.api_pods_url = "{}/apis/metrics.k8s.io/v1beta1/pods".format( self.api_url) self.insecure_tls = self.set_tls_mode() self.token = self.set_token() @@ -42,9 +44,12 @@ def set_token(self): return None + def set_namespaced_pod_url(self,namespace): + return '{}/apis/metrics.k8s.io/v1beta1/namespaces/{}/pods?labelSelector={}'.format( self.api_url ,namespace,self.labelSelector ) + def kube_metrics(self): headers = { "Authorization": "Bearer {}".format(self.token) } - + query = { 'labelSelector' : self.labelSelector } session = requests.Session() retry = Retry(total=3, connect=3, backoff_factor=0.1) adapter = HTTPAdapter(max_retries=retry) @@ -54,11 +59,22 @@ def kube_metrics(self): session.verify = False elif os.path.exists(self.ca_cert): session.verify = self.ca_cert - - payload = { - 'nodes': session.get(self.api_nodes_url, headers=headers), - 'pods': session.get(self.api_pods_url, headers=headers) - } + if self.namespaces: + pod_data = None + for namespace in self.namespaces: + if pod_data is None: + pod_data = session.get(self.set_namespaced_pod_url(namespace), headers=headers, params=query).json() + else: + pod_data['items'] += session.get(self.set_namespaced_pod_url(namespace), headers=headers, params=query).json()['items'] + payload = { + 'nodes': session.get(self.api_nodes_url, headers=headers, params=query).json(), + 'pods': pod_data + } + else: + payload = { + 'nodes': session.get(self.api_nodes_url, headers=headers, params=query).json(), + 'pods': session.get(self.api_pods_url, headers=headers, params=query).json() + } return payload @@ -68,8 +84,8 @@ def collect(self): end_time = datetime.datetime.now() total_time = (end_time - start_time).total_seconds() - nodes = json.loads(ret['nodes'].text) - pods = json.loads(ret['pods'].text) + nodes = ret['nodes'] + pods = ret['pods'] metrics_nodes_mem = Metric('kube_metrics_server_nodes_mem', 'Metrics Server Nodes Memory', 'gauge') metrics_nodes_cpu = Metric('kube_metrics_server_nodes_cpu', 'Metrics Server Nodes CPU', 'gauge')