From 2752417ffb7831cec1f24a8c1cd77b4b464e66ea Mon Sep 17 00:00:00 2001 From: Paul Forman <45043543+pforman-zymergen@users.noreply.github.com> Date: Tue, 27 Aug 2019 18:53:35 -0600 Subject: [PATCH] feat(app) Adds default CA Certificate verification (#23) * verify metrics-server https with cluster CA * add insecure-tls option, order imports, change TLS retries from default 10 down to 3, exp backoff made that ~2m --- README.md | 12 ++++++++++-- app.py | 24 ++++++++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 08e6865..f49a43c 100644 --- a/README.md +++ b/README.md @@ -42,18 +42,26 @@ metrics-server-exporter provides cpu and memory metrics for nodes and pods, dire * K8S_FILEPATH_TOKEN * Path of ServiceAccount token file (default /var/run/secrets/kubernetes.io/serviceaccount/token) + * K8S_CA_CERT_PATH + * Path of Kubernetes CA certificate (default /var/run/secrets/kubernetes.io/serviceaccount/ca.crt) + * NAMES_BLACKLIST * A list of names from pods, containers or namespaces to exclude from metrics. +### Options + + * --insecure-tls + * Disables TLS verification of the Kubernetes API Server. (Not recommended in production) + ### How to build $ docker build . -t vivareal/metrics-server-exporter ### How to run -You will need `K8S_TOKEN` and `K8S_ENDPOINT` to access the api-server +You will need `K8S_TOKEN` and `K8S_ENDPOINT` to access the api-server. Use "--insecure-tls" or mount the CA certificate into the container. Kubernetes will provide the CA certificate in a Kubernetes installation. - $ docker run -p 8000:8000 -e "K8S_ENDPOINT=${K8S_ENDPOINT}" -e "K8S_TOKEN=${K8S_TOKEN}" vivareal/metrics-server-exporter + $ docker run -p 8000:8000 -e "K8S_ENDPOINT=${K8S_ENDPOINT}" -e "K8S_TOKEN=${K8S_TOKEN}" vivareal/metrics-server-exporter --insecure-tls ### How to deploy diff --git a/app.py b/app.py index 4407a55..2ddc63c 100644 --- a/app.py +++ b/app.py @@ -1,11 +1,13 @@ # -*- coding: utf-8 -*- +import datetime +import getopt +import json import os import requests -import json -import time import string -import datetime +import sys +import time from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.retry import Retry @@ -17,13 +19,18 @@ class MetricsServerExporter: def __init__(self): self.svc_token = os.environ.get('K8S_FILEPATH_TOKEN', '/var/run/secrets/kubernetes.io/serviceaccount/token') + 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.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.insecure_tls = self.set_tls_mode() self.token = self.set_token() + def set_tls_mode(self): + return ('--insecure-tls','') in options + def set_token(self): if os.environ.get('K8S_TOKEN') is not None: return os.environ.get('K8S_TOKEN') @@ -39,14 +46,18 @@ def kube_metrics(self): headers = { "Authorization": "Bearer {}".format(self.token) } session = requests.Session() - retry = Retry(connect=3, backoff_factor=0.1) + retry = Retry(total=3, connect=3, backoff_factor=0.1) adapter = HTTPAdapter(max_retries=retry) session.mount('http://', adapter) session.mount('https://', adapter) + if self.insecure_tls: + 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, verify=False), - 'pods': session.get(self.api_pods_url, headers=headers, verify=False) + 'nodes': session.get(self.api_nodes_url, headers=headers), + 'pods': session.get(self.api_pods_url, headers=headers) } return payload @@ -106,6 +117,7 @@ def collect(self): yield metrics_pods_cpu if __name__ == '__main__': + options, remainder = getopt.gnu_getopt(sys.argv[1:], '', ['insecure-tls']) REGISTRY.register(MetricsServerExporter()) start_http_server(8000) while True: