Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# node-cert-exporter

[![Build Status](https://travis-ci.org/amimof/node-cert-exporter.svg?branch=master)](https://travis-ci.org/amimof/node-cert-exporter) [![Go Report Card](https://goreportcard.com/badge/github.com/amimof/node-cert-exporter)](https://goreportcard.com/report/github.com/amimof/node-cert-exporter) [![huego](https://godoc.org/github.com/amimof/node-cert-exporter?status.svg)](https://godoc.org/github.com/amimof/node-cert-exporter)

---
Expand All @@ -7,40 +8,59 @@

*This project is currently in beta and is looking for contributors. Feel free to leave your feedback using issues or pull requests.*

# Kubernetes DaemonSet
```
## Kubernetes DaemonSet

```bash
kubectl apply -f https://raw.githubusercontent.com/amimof/node-cert-exporter/master/deploy/daemonset.yml
```

# Docker
## Openshift DaemonSet

__Tip__: This YAML files configured via jsonnet for prometheus-operator in OKD 3.11 and for the project `monitoring`

```bash
oc create -f https://raw.githubusercontent.com/amimof/node-cert-exporter/master/okd/rendered/node-cert-exporter-service.yaml
oc create -f https://raw.githubusercontent.com/amimof/node-cert-exporter/master/okd/rendered/node-cert-exporter-serviceMonitor.yaml
oc create -f https://raw.githubusercontent.com/amimof/node-cert-exporter/master/okd/rendered/node-cert-exporter-serviceAccount.yaml
oc adm policy add-scc-to-user hostmount-anyuid -n monitoring -z node-cert-exporter
oc create -f https://raw.githubusercontent.com/amimof/node-cert-exporter/master/okd/rendered/node-cert-exporter-daemonset.yaml
```

## Docker

```bash
docker run -p 9117:9117 amimof/node-cert-exporter --logtostderr=true --path=/etc/ssl,/dir/with/certs
```

# Helm
```
## Helm

```bash
helm repo add node-cert-exporter https://amimof.github.io/node-cert-exporter
helm repo update
helm install node-cert-exporter node-cert-exporter/node-cert-exporter
```

# Binary
```
## Binary

```bash
curl -LOs https://github.com/amimof/node-cert-exporter/releases/latest/download/node-cert-exporter-linux-amd64 && chmod +x node-cert-exporter-linux-amd64
./node-cert-exporter-linux-amd64 --path=/etc/ssl,/dir/with/certs
```

# Building from source
```
## Building from source

```bash
git clone https://github.com/amimof/node-cert-exporter.git
cd node-cert-exporter
make
```

# Grafana Dashboard
## Grafana Dashboard

Once the the node-cert-exporter is scraped by Prometheus, the metrics can easily be visualized using [Grafana](https://grafana.com). Get started by using the [Node Cert Exporter](https://grafana.com/dashboards/9999) dashboard hosted at grafana.com.

![](./img/grafana.png)
![Grafana dashboard](./img/grafana.png)

## Contribute

# Contribute
All help in any form is highly appreciated and your are welcome participate in developing together. To contribute submit a Pull Request. If you want to provide feedback, open up a Github Issue or contact me personally.
164 changes: 164 additions & 0 deletions deploy/okd/grafana/k8s-cert-expire.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "Dashboard for certificates in OKD 3.11",
"editable": false,
"gnetId": 9999,
"graphTooltip": 0,
"id": 18,
"links": [],
"panels": [
{
"columns": [],
"datasource": "prometheus",
"fontSize": "100%",
"gridPos": {
"h": 16,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"links": [],
"options": {},
"pageSize": null,
"scroll": true,
"showHeader": true,
"sort": {
"col": 3,
"desc": false
},
"styles": [
{
"alias": "Time",
"align": "auto",
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"pattern": "Time",
"type": "hidden"
},
{
"alias": "Expires In",
"align": "auto",
"colorMode": "cell",
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"decimals": 2,
"pattern": "Value",
"thresholds": [
"7889231.49",
"15778463"
],
"type": "number",
"unit": "dtdurations"
},
{
"alias": "Node",
"align": "auto",
"colorMode": null,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"decimals": 2,
"mappingType": 1,
"pattern": "nodename",
"thresholds": [],
"type": "string",
"unit": "short"
},
{
"alias": "Path",
"align": "auto",
"colorMode": null,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"dateFormat": "YYYY-MM-DD HH:mm:ss",
"decimals": 2,
"link": false,
"mappingType": 1,
"pattern": "path",
"preserveFormat": false,
"sanitize": false,
"thresholds": [],
"type": "string",
"unit": "short"
}
],
"targets": [
{
"expr": "sum(ssl_certificate_expiry_seconds{path!~\"/opt/etc/etcd/generated_certs/.+|/opt/etc/etcd/ca/.+\"}) by (nodename,path)",
"format": "table",
"hide": false,
"instant": true,
"legendFormat": "{{ nodename }}",
"refId": "A"
}
],
"title": "Node Certificates",
"transform": "table",
"type": "table"
}
],
"refresh": "30s",
"schemaVersion": 22,
"style": "dark",
"tags": [
"kubernetes",
"node-cert-exporter"
],
"templating": {
"list": []
},
"time": {
"from": "now-1m",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"timezone": "",
"title": "Cert Expire",
"uid": "F_gILm6iz",
"version": 1
}
123 changes: 123 additions & 0 deletions deploy/okd/jsonnet/cert-exporter.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
local k = import '../../vendor/ksonnet/ksonnet.beta.4/k.libsonnet';

{
_config+:: {
namespace: 'default',

versions+:: {
nodeCertExporter: '1.0.0',
},

imageRepos+:: {
nodeCertExporter: 'amimof/node-cert-exporter',
},

nodeCertExporter+:: {
port: 9117,
labels: {
'k8s-app': 'node-cert-exporter',
},
container: {
requests: { cpu: '100m', memory: '128Mi' },
limits: { cpu: '250m', memory: '256Mi' },
},
},
},

nodeCertExporter+:: {
daemonset:
local daemonset = k.apps.v1.daemonSet;
local container = daemonset.mixin.spec.template.spec.containersType;
local volume = daemonset.mixin.spec.template.spec.volumesType;
local containerPort = container.portsType;
local targetPort = $._config.nodeCertExporter.port;
local portName = 'metric';
local containerVolumeMount = container.volumeMountsType;
local podSelector = daemonset.mixin.spec.template.spec.selectorType;
local containerEnv = container.envType;

local podLabels = $._config.nodeCertExporter.labels;

local etcdVolumeName = 'etcd';
local etcdVolume = volume.fromHostPath(etcdVolumeName, '/etc/etcd');
local etcdVolumeMount = containerVolumeMount.new(etcdVolumeName, '/opt/etc/etcd').
withReadOnly(true);

local masterVolumeName = 'master';
local masterVolume = volume.fromHostPath(masterVolumeName, '/etc/origin/master');
local masterVolumeMount = containerVolumeMount.new(masterVolumeName, '/opt/etc/master').
withReadOnly(true);

local nodeVolumeName = 'node';
local nodeVolume = volume.fromHostPath(nodeVolumeName, '/etc/origin/node/certificates');
local nodeVolumeMount = containerVolumeMount.new(nodeVolumeName, '/opt/etc/node').
withReadOnly(true);

local nodename = containerEnv.fromFieldPath('NODE_NAME', 'spec.nodeName');

local nodeCertExporter =
container.new('node-cert-exporter', $._config.imageRepos.nodeCertExporter + ':' + $._config.versions.nodeCertExporter) +
container.withArgs([
'--v=2',
'--logtostderr=true',
'--path=/opt/etc/etcd/,/opt/etc/master/,/opt/etc/node/'
]) +
container.withVolumeMounts([etcdVolumeMount, masterVolumeMount, nodeVolumeMount]) +
container.mixin.resources.withRequests($._config.nodeCertExporter.container.requests) +
container.withPorts(containerPort.newNamed(targetPort, portName)) +
container.withEnv([nodename]) +
container.mixin.resources.withLimits($._config.nodeCertExporter.container.limits);

local c = [nodeCertExporter];

daemonset.new() +
daemonset.mixin.metadata.withName('node-cert-exporter') +
daemonset.mixin.metadata.withNamespace($._config.namespace) +
daemonset.mixin.metadata.withLabels(podLabels) +
daemonset.mixin.spec.selector.withMatchLabels(podLabels) +
daemonset.mixin.spec.template.metadata.withLabels(podLabels) +
daemonset.mixin.spec.template.spec.withNodeSelector({ 'beta.kubernetes.io/os': 'linux' }) +
daemonset.mixin.spec.template.spec.withContainers(c) +
daemonset.mixin.spec.template.spec.withVolumes([etcdVolume, masterVolume, nodeVolume]) +
daemonset.mixin.spec.template.spec.withServiceAccountName('node-cert-exporter') +
daemonset.mixin.spec.template.spec.securityContext.withRunAsUser(0),

serviceAccount:
local serviceAccount = k.core.v1.serviceAccount;

serviceAccount.new('node-cert-exporter') +
serviceAccount.mixin.metadata.withNamespace($._config.namespace),

serviceMonitor:
{
apiVersion: 'monitoring.coreos.com/v1',
kind: 'ServiceMonitor',
metadata: {
name: 'node-cert-exporter',
namespace: $._config.namespace,
labels: $._config.nodeCertExporter.labels,
},
spec: {
selector: {
matchLabels: $._config.nodeCertExporter.labels,
},
endpoints: [
{
port: 'metric',
interval: '15s',
},
],
},
},

service:
local service = k.core.v1.service;
local servicePort = k.core.v1.service.mixin.spec.portsType;

local nodeCertExporterPort = servicePort.newNamed('metric', $._config.nodeCertExporter.port, 'metric');

service.new('node-cert-exporter', $.nodeCertExporter.daemonset.spec.selector.matchLabels, nodeCertExporterPort) +
service.mixin.metadata.withNamespace($._config.namespace) +
service.mixin.metadata.withLabels($._config.nodeCertExporter.labels),
},
}
Loading