From a2e64160bf70ac13cc0ec218b06d0ce64cbffa69 Mon Sep 17 00:00:00 2001 From: Fanch Date: Thu, 25 May 2023 16:36:51 +0200 Subject: [PATCH] ajout des dockers traefik et grafana --- dockers/grafana/.env | 1 + dockers/grafana/docker-compose.yml | 67 + dockers/grafana/grafana.env | 6 + .../provisioning/dashboards/dashboard.yml | 21 + .../dashboards/reverse-proxy_rev1.json | 1293 +++++++++++++++++ .../provisioning/datasources/datasource.yml | 50 + dockers/grafana/prometheus/alert.rules | 11 + dockers/grafana/prometheus/prometheus.yml | 12 + dockers/traefik/.env | 1 + .../conf/dynamic/certificates.yml.tmpl | 20 + dockers/traefik/conf/dynamic/conf.yml | 11 + dockers/traefik/conf/traefik.yml.old | 54 + dockers/traefik/docker-compose.tmpl.yml.dist | 188 +++ dockers/traefik/proxy-gen.sh | 165 +++ dockers/traefik/reload.sh | 4 + 15 files changed, 1904 insertions(+) create mode 120000 dockers/grafana/.env create mode 100644 dockers/grafana/docker-compose.yml create mode 100644 dockers/grafana/grafana.env create mode 100644 dockers/grafana/grafana/provisioning/dashboards/dashboard.yml create mode 100644 dockers/grafana/grafana/provisioning/dashboards/reverse-proxy_rev1.json create mode 100644 dockers/grafana/grafana/provisioning/datasources/datasource.yml create mode 100644 dockers/grafana/prometheus/alert.rules create mode 100644 dockers/grafana/prometheus/prometheus.yml create mode 120000 dockers/traefik/.env create mode 100644 dockers/traefik/conf/dynamic/certificates.yml.tmpl create mode 100644 dockers/traefik/conf/dynamic/conf.yml create mode 100644 dockers/traefik/conf/traefik.yml.old create mode 100644 dockers/traefik/docker-compose.tmpl.yml.dist create mode 100755 dockers/traefik/proxy-gen.sh create mode 100755 dockers/traefik/reload.sh diff --git a/dockers/grafana/.env b/dockers/grafana/.env new file mode 120000 index 0000000..406acd1 --- /dev/null +++ b/dockers/grafana/.env @@ -0,0 +1 @@ +../../config/dockers.env \ No newline at end of file diff --git a/dockers/grafana/docker-compose.yml b/dockers/grafana/docker-compose.yml new file mode 100644 index 0000000..57919e9 --- /dev/null +++ b/dockers/grafana/docker-compose.yml @@ -0,0 +1,67 @@ +version: '3' + +services: + + prometheus: + image: prom/prometheus:v2.15.2 + restart: unless-stopped + container_name: ${prometheusServName} + volumes: + - ./prometheus/:/etc/prometheus/ + - prometheus:/prometheus + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + command: + - "--web.route-prefix=/" + - "--web.external-url=https://${site}.${domain}/prometheus" + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + - "--web.console.libraries=/usr/share/prometheus/console_libraries" + - "--web.console.templates=/usr/share/prometheus/consoles" + networks: + - traefikNet + labels: + - "traefik.enable=true" + - "traefik.http.routers.prometheus-secure.entrypoints=websecure" + - "traefik.http.middlewares.prometheus-stripprefix.stripprefix.prefixes=/prometheus" + - "traefik.http.routers.prometheus-secure.rule=Host(`${site}.${domain}`) && PathPrefix(`/prometheus`)" + # - "traefik.http.routers.prometheus-secure.tls=true" + - "traefik.http.routers.prometheus-secure.middlewares=prometheus-stripprefix,test-adminipwhitelist@file,traefik-auth" + - "traefik.http.routers.prometheus-secure.service=prometheus" + - "traefik.http.services.prometheus.loadbalancer.server.port=9090" + - "traefik.docker.network=traefikNet" + + grafana: + image: grafana/grafana:6.6.1 + restart: unless-stopped + container_name: ${grafanaServName} + volumes: + - grafana:/var/lib/grafana + - ./grafana/provisioning:/etc/grafana/provisioning + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - grafana.env + depends_on: + - prometheus + networks: + - traefikNet + labels: + - "traefik.enable=true" + - "traefik.http.routers.grafana-secure.entrypoints=websecure" + - "traefik.http.middlewares.grafana-stripprefix.stripprefix.prefixes=/grafana" + - "traefik.http.routers.grafana-secure.rule=Host(`${site}.${domain}`) && PathPrefix(`/grafana`)" + # - "traefik.http.routers.grafana-secure.tls=true" + - "traefik.http.routers.grafana-secure.service=grafana" + - "traefik.http.routers.grafana-secure.middlewares=grafana-stripprefix,test-adminipwhitelist@file,traefik-auth" + - "traefik.http.services.grafana.loadbalancer.server.port=3000" + - "traefik.docker.network=traefikNet" + +networks: + traefikNet: + external: true + name: traefikNet + +volumes: + prometheus: + grafana: diff --git a/dockers/grafana/grafana.env b/dockers/grafana/grafana.env new file mode 100644 index 0000000..e6516d7 --- /dev/null +++ b/dockers/grafana/grafana.env @@ -0,0 +1,6 @@ +GF_AUTH_ANONYMOUS_ENABLED=true +GF_AUTH_BASIC_ENABLED=false +GF_AUTH_PROXY_ENABLED=false +GF_USERS_ALLOW_SIGN_UP=false +GF_INSTALL_PLUGINS=grafana-piechart-panel +GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana \ No newline at end of file diff --git a/dockers/grafana/grafana/provisioning/dashboards/dashboard.yml b/dockers/grafana/grafana/provisioning/dashboards/dashboard.yml new file mode 100644 index 0000000..bc14030 --- /dev/null +++ b/dockers/grafana/grafana/provisioning/dashboards/dashboard.yml @@ -0,0 +1,21 @@ +apiVersion: 1 + +providers: + # provider name +- name: 'default' + # org id. will default to orgId 1 if not specified + orgId: 1 + # name of the dashboard folder. Required + folder: '' + # folder UID. will be automatically generated if not specified + folderUid: '' + # provider type. Required + type: file + # disable dashboard deletion + disableDeletion: false + # enable dashboard editing + editable: true + # how often Grafana will scan for changed dashboards + updateIntervalSeconds: 10 + options: + path: /etc/grafana/provisioning/dashboards \ No newline at end of file diff --git a/dockers/grafana/grafana/provisioning/dashboards/reverse-proxy_rev1.json b/dockers/grafana/grafana/provisioning/dashboards/reverse-proxy_rev1.json new file mode 100644 index 0000000..7abc943 --- /dev/null +++ b/dockers/grafana/grafana/provisioning/dashboards/reverse-proxy_rev1.json @@ -0,0 +1,1293 @@ +{ + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "6.3.6" + }, + { + "type": "panel", + "id": "grafana-piechart-panel", + "name": "Pie Chart", + "version": "1.3.9" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": 10906, + "graphTooltip": 0, + "id": null, + "iteration": 1569328089102, + "links": [ + { + "icon": "external link", + "tags": [ + "link" + ], + "type": "dashboards" + } + ], + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "s", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 22, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "options": {}, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "time() - process_start_time_seconds{job=\"$job\"}", + "format": "time_series", + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "", + "title": "Uptime", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(26, 206, 22, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 0, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 6, + "w": 3, + "x": 3, + "y": 0 + }, + "id": 26, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "options": {}, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "200%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"404\",method=\"GET\",protocol=~\"$protocol\"}[$interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "traefik_requests_total", + "refId": "A", + "step": 60 + } + ], + "thresholds": "0,1", + "title": "404 Error Count last $interval", + "type": "singlestat", + "valueFontSize": "200%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "max" + }, + { + "aliasColors": {}, + "breakPoint": "50%", + "cacheTimeout": null, + "combine": { + "label": "Others", + "threshold": 0 + }, + "datasource": "Prometheus", + "fontSize": "80%", + "format": "short", + "gridPos": { + "h": 6, + "w": 7, + "x": 6, + "y": 0 + }, + "id": 18, + "interval": null, + "legend": { + "percentage": true, + "show": true, + "sort": null, + "sortDesc": null, + "values": true + }, + "legendType": "Right side", + "links": [], + "maxDataPoints": 3, + "nullPointMode": "connected", + "options": {}, + "pieType": "pie", + "strokeWidth": 1, + "targets": [ + { + "expr": "traefik_service_requests_total{protocol=~\"$protocol\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{method}} : {{code}}", + "refId": "A" + } + ], + "title": "$protocol return code", + "type": "grafana-piechart-panel", + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 6, + "w": 4, + "x": 13, + "y": 0 + }, + "id": 20, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "options": {}, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(traefik_entrypoint_request_duration_seconds_sum) / sum(traefik_entrypoint_requests_total) * 1000", + "format": "time_series", + "intervalFactor": 2, + "refId": "A" + } + ], + "thresholds": "", + "title": "Average response time", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 7, + "x": 17, + "y": 0 + }, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_service_request_duration_seconds_sum{protocol=~\"$protocol\"}) / sum(traefik_entrypoint_requests_total{protocol=~\"$protocol\"}) * 1000", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Average response time (ms)", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average response time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 10, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 6 + }, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{code=\"404\",method=\"GET\",protocol=~\"$protocol\"}[$interval])) by (service)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{service}} ", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bad Status Code Count $interval", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 6 + }, + "hideTimeOverride": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total[$interval]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Total requests", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total requests over $interval", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 10, + "x": 0, + "y": 12 + }, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "process_open_fds{job=~\"$job\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ instance }}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Used sockets", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 14, + "x": 10, + "y": 12 + }, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(traefik_service_requests_total{protocol=~\"http|https\",code=\"200\"}[$interval])) by (service)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{service}} {{method}} {{code}}", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Access to backends", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_entrypoint_open_connections) by (method)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ method }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "ENTRYPOINT - Open Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 7, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 28, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(traefik_service_open_connections) by (method)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ method }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "BACKEND - Open Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 0, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/^[^234].*/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(increase(traefik_service_requests_total{protocol=~\"$protocol\"}[$interval])) by (code)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{code}}", + "refId": "A", + "step": 120 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Status Code Count per $interval", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": 0, + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "10s", + "schemaVersion": 19, + "style": "dark", + "tags": [ + "traefik", + "load-balancer", + "docker", + "prometheus", + "link" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Job:", + "multi": false, + "name": "job", + "options": [], + "query": "label_values(job)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": "traefik", + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Node:", + "multi": false, + "name": "node", + "options": [], + "query": "label_values(process_start_time_seconds, instance)", + "refresh": 1, + "regex": "/([^:]+):.*/", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "label_values(traefik_service_requests_total, protocol)", + "hide": 0, + "includeAll": true, + "label": "Service:", + "multi": true, + "name": "protocol", + "options": [], + "query": "label_values(traefik_service_requests_total, protocol)", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "auto": true, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "30m", + "value": "30m" + }, + "hide": 0, + "label": "Interval", + "name": "interval", + "options": [ + { + "selected": false, + "text": "auto", + "value": "$__auto_interval_interval" + }, + { + "selected": false, + "text": "1m", + "value": "1m" + }, + { + "selected": false, + "text": "10m", + "value": "10m" + }, + { + "selected": true, + "text": "30m", + "value": "30m" + }, + { + "selected": false, + "text": "1h", + "value": "1h" + }, + { + "selected": false, + "text": "6h", + "value": "6h" + }, + { + "selected": false, + "text": "12h", + "value": "12h" + }, + { + "selected": false, + "text": "1d", + "value": "1d" + }, + { + "selected": false, + "text": "7d", + "value": "7d" + }, + { + "selected": false, + "text": "14d", + "value": "14d" + }, + { + "selected": false, + "text": "30d", + "value": "30d" + } + ], + "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", + "refresh": 2, + "skipUrlSync": false, + "type": "interval" + } + ] + }, + "time": { + "from": "now-1h", + "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": "traefik", + "uid": "3ipsWfViz", + "version": 13, + "description": "Dashboard for Traefik2/Prometheus" +} \ No newline at end of file diff --git a/dockers/grafana/grafana/provisioning/datasources/datasource.yml b/dockers/grafana/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 0000000..304d2f8 --- /dev/null +++ b/dockers/grafana/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,50 @@ +# config file version +apiVersion: 1 + +# list of datasources that should be deleted from the database +deleteDatasources: + - name: Prometheus + orgId: 1 + +# list of datasources to insert/update depending +# whats available in the database +datasources: + # name of the datasource. Required +- name: Prometheus + # datasource type. Required + type: prometheus + # access mode. direct or proxy. Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://prometheus:9090 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: false + # basic auth username + basicAuthUser: + # basic auth password + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: true + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: false + tlsAuthWithCACert: false + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: true diff --git a/dockers/grafana/prometheus/alert.rules b/dockers/grafana/prometheus/alert.rules new file mode 100644 index 0000000..e10abbe --- /dev/null +++ b/dockers/grafana/prometheus/alert.rules @@ -0,0 +1,11 @@ +groups: +- name: traefik + rules: + - alert: service_down + expr: up == 0 + for: 2m + labels: + severity: page + annotations: + summary: "Instance {{ $labels.instance }} down" + description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 2 minutes" \ No newline at end of file diff --git a/dockers/grafana/prometheus/prometheus.yml b/dockers/grafana/prometheus/prometheus.yml new file mode 100644 index 0000000..26219e4 --- /dev/null +++ b/dockers/grafana/prometheus/prometheus.yml @@ -0,0 +1,12 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +rule_files: + - 'alert.rules' + +scrape_configs: + - job_name: 'traefik' + scrape_interval: 5s + static_configs: + - targets: ['dashboard.kaz.sns:8289','dashboard2.kaz.sns:8289'] diff --git a/dockers/traefik/.env b/dockers/traefik/.env new file mode 120000 index 0000000..406acd1 --- /dev/null +++ b/dockers/traefik/.env @@ -0,0 +1 @@ +../../config/dockers.env \ No newline at end of file diff --git a/dockers/traefik/conf/dynamic/certificates.yml.tmpl b/dockers/traefik/conf/dynamic/certificates.yml.tmpl new file mode 100644 index 0000000..3676fd3 --- /dev/null +++ b/dockers/traefik/conf/dynamic/certificates.yml.tmpl @@ -0,0 +1,20 @@ +#tls: +# certificates: +# - certFile: __SSL_CERT__ +# keyFile: __SSL_KEY__ +# +# stores: +# default: +# defaultCertificate: +# certFile: __SSL_CERT__ +# keyFile: __SSL_KEY__ +# options: +# default: +# minVersion: VersionTLS12 +# cipherSuites: +# - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +# - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +# - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +# - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 +# - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 +# - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 diff --git a/dockers/traefik/conf/dynamic/conf.yml b/dockers/traefik/conf/dynamic/conf.yml new file mode 100644 index 0000000..f4059bd --- /dev/null +++ b/dockers/traefik/conf/dynamic/conf.yml @@ -0,0 +1,11 @@ +# http: +# middlewares: +# redirect-to-https: +# redirectscheme: +# scheme: https +# permanent: true +# routers: +# http-catchall: +# rule: "HostRegexp(`{host:.+}`)" +# middlewares: redirect-to-https +# service: noop@internal diff --git a/dockers/traefik/conf/traefik.yml.old b/dockers/traefik/conf/traefik.yml.old new file mode 100644 index 0000000..75e3c6e --- /dev/null +++ b/dockers/traefik/conf/traefik.yml.old @@ -0,0 +1,54 @@ +providers: + file: + directory: "/etc/traefik/dynamic" + watch: true + docker: {} + +entryPoints: + web: + address: ":80" + websecure: + address: ":443" + http: + tls: + certResolver: letsencrypt + # Ajout d'un point d'entrée sur le port 8289 + metrics: + address: ":8289" + +#serversTransport: +# rootCAs: +# - /etc/letsencrypt/local/rootCA.pem + + +api: + dashboard: true + +accessLog: + filePath: "/var/log/traefik/access.log" + format: json + +certificatesresolvers: + letsencrypt: + acme: + # email: sysadmins@kaz.bzh + storage: /letsencrypt/acme.json + # caServer: "https://acme-staging.api.letsencrypt.org/directory" + httpChallenge: + entryPoint: web + +# Ajout de la partie métrique qui concerne Prometheus +metrics: + prometheus: + # Nom du point d'entrée défini au dessus + entryPoint: metrics + # On configure la latence des métriques + buckets: + - 0.1 + - 0.3 + - 1.2 + - 5.0 + # Ajout des métriques sur les points d'entrée + addEntryPointsLabels: true + # Ajout des services + addServicesLabels: true diff --git a/dockers/traefik/docker-compose.tmpl.yml.dist b/dockers/traefik/docker-compose.tmpl.yml.dist new file mode 100644 index 0000000..3b70c25 --- /dev/null +++ b/dockers/traefik/docker-compose.tmpl.yml.dist @@ -0,0 +1,188 @@ +version: '3' + +services: + reverse-proxy: + # The official v2 Traefik docker image + image: traefik:v2.10 + container_name: ${traefikServName} + # Enables the web UI and tells Traefik to listen to docker + ports: + # The HTTP port + - ${MAIN_IP}:80:80 + - ${MAIN_IP}:443:443 + # The Web UI (enabled by --api.insecure=true) + # - ${MAIN_IP}:8289:8289 + volumes: + # So that Traefik can listen to the Docker events + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./conf:/etc/traefik/ + - letsencrypt:/letsencrypt + environment: + - TRAEFIK_PROVIDERS_DOCKER=true + - TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT=false + - TRAEFIK_API=true + - TRAEFIK_PROVIDERS_FILE_DIRECTORY=/etc/traefik/dynamic + - TRAEFIK_ENTRYPOINTS_web_ADDRESS=:80 + - TRAEFIK_ENTRYPOINTS_web_HTTP_REDIRECTIONS_ENTRYPOINT_TO=websecure + - TRAEFIK_ENTRYPOINTS_websecure_ADDRESS=:443 + - TRAEFIK_ENTRYPOINTS_websecure_HTTP_TLS_CERTRESOLVER=letsencrypt + #- TRAEFIK_ENTRYPOINTS_metrics_ADDRESS=:8289 + #- TRAEFIK_METRICS_PROMETHEUS_ENTRYPOINT=metrics + - TRAEFIK_CERTIFICATESRESOLVERS_letsencrypt_ACME_EMAIL=postmaster@${domain} + - TRAEFIK_CERTIFICATESRESOLVERS_letsencrypt_ACME_CASERVER=${acme_server} + - TRAEFIK_CERTIFICATESRESOLVERS_letsencrypt_ACME_STORAGE=/letsencrypt/acme.json + - TRAEFIK_CERTIFICATESRESOLVERS_letsencrypt_ACME_TLSCHALLENGE=true + - TRAEFIK_LOG_LEVEL=INFO + #- TRAEFIK_CERTIFICATESRESOLVERS_letsencrypt_ACME_HTTPCHALLENGE=true + #- TRAEFIK_CERTIFICATESRESOLVERS_letsencrypt_ACME_HTTPCHALLENGE_ENTRYPOINT=web + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik_https.rule=Host(`${site}.${domain}`)" + - "traefik.http.routers.traefik_https.entrypoints=websecure" + # - "traefik.http.routers.traefik_https.tls=true" + - "traefik.http.routers.traefik_https.service=api@internal" + - "traefik.http.routers.traefik_https.middlewares=test-adminipwhitelist@file,traefik-auth" + # - "traefik.http.routers.traefik_https.tls.certresolver=letsencrypt" + - "traefik.http.middlewares.traefik-auth.basicauth.usersfile=/etc/traefik/passfile" + networks: + - traefikNet +{{web + - webNet +}} +{{jirafeau + - jirafeauNet +}} +{{ethercalc + - ethercalcNet +}} +{{etherpad + - etherpadNet +}} +{{framadate + - framadateNet +}} +{{ldap + - ldapNet +}} +{{mobilizon + - mobilizonNet +}} +{{cloud + - cloudNet +}} +{{collabora + - collaboraNet +}} +{{garradin + - garradinNet +}} +{{mattermost + - mattermostNet +}} +{{roundcube + - roundcubeNet +}} +{{gitea + - giteaNet +}} +{{dokuwiki + - dokuwikiNet +}} +{{postfix + - postfixNet +}} +{{vaultwarden + - vaultwardenNet +}} +#### BEGIN ORGA USE_NET +#### END ORGA USE_NET + +networks: + traefikNet: + external: true + name: traefikNet +{{web + webNet: + external: true + name: webNet +}} +{{jirafeau + jirafeauNet: + external: true + name: jirafeauNet +}} +{{ethercalc + ethercalcNet: + external: true + name: ethercalcNet +}} +{{etherpad + etherpadNet: + external: true + name: etherpadNet +}} +{{framadate + framadateNet: + external: true + name: framadateNet +}} +{{ldap + ldapNet: + external: true + name: ldapNet +}} +{{mobilizon + mobilizonNet: + external: true + name: mobilizonNet +}} +{{cloud + cloudNet: + external: true + name: cloudNet +}} +{{collabora + collaboraNet: + external: true + name: collaboraNet +}} +{{garradin + garradinNet: + external: true + name: garradinNet +}} +{{mattermost + mattermostNet: + external: true + name: mattermostNet +}} +{{roundcube + roundcubeNet: + external: true + name: roundcubeNet +}} +{{gitea + giteaNet: + external: true + name: giteaNet +}} +{{dokuwiki + dokuwikiNet: + external: true + name: dokuwikiNet +}} +{{postfix + postfixNet: + external: true + name: postfixNet +}} +{{vaultwarden + vaultwardenNet: + external: true + name: vaultwardenNet +}} +#### BEGIN ORGA DEF_NET +#### END ORGA DEF_NET + +volumes: + letsencrypt: diff --git a/dockers/traefik/proxy-gen.sh b/dockers/traefik/proxy-gen.sh new file mode 100755 index 0000000..73241b4 --- /dev/null +++ b/dockers/traefik/proxy-gen.sh @@ -0,0 +1,165 @@ +#!/bin/bash + +KAZ_ROOT=$(cd "$(dirname $0)/../.."; pwd) +. "${KAZ_ROOT}/bin/.commonFunctions.sh" +setKazVars +. "${DOCKERS_ENV}" +. "${KAZ_ROOT}/secret/SetAllPass.sh" + +printKazMsg "\n *** Proxy update config" + +#NGINX_TMPL=config/nginx.tmpl.conf +#NGINX_CONF=config/nginx.conf +DOCKER_DIST=docker-compose.tmpl.yml.dist +DOCKER_TMPL=docker-compose.tmpl.yml +DOCKER_CONF=docker-compose.yml +PASSFILE=conf/passfile + +ALLOW_ADMIN_IP_FILE="/kaz/secret/allow_admin_ip" +ALLOW_IP_FILE="/kaz/config/proxy/allow_ip" + +# TODO +# for service in agora cloud garradin wiki wp; do +# touch "${KAZ_CONF_PROXY_DIR}/${service}_kaz_map" +# touch "${KAZ_CONF_PROXY_DIR}/${service}_kaz_name" +# done + +cd $(dirname $0) +# update ip allowed +TRAEFIK_ALLOW_IP_FILE=conf/dynamic/allow_ip.yml +if [ ! -f "${TRAEFIK_ALLOW_IP_FILE}" ]; then + cat > "${TRAEFIK_ALLOW_IP_FILE}" < "${PROXY_PORT_CFG}" < "${PROXY_REDIRECT}" <> ${PASSFILE} +[[ -f "${DOCKER_TMPL}" ]] || cp "${DOCKER_DIST}" "${DOCKER_TMPL}" +"${APPLY_TMPL}" -time "${DOCKER_TMPL}" "${DOCKER_CONF}" +# "${APPLY_TMPL}" -time "${NGINX_TMPL}" "${NGINX_CONF}" + +#("${KAZ_COMP_DIR}/web/web-gen.sh" ) & diff --git a/dockers/traefik/reload.sh b/dockers/traefik/reload.sh new file mode 100755 index 0000000..bbe95cf --- /dev/null +++ b/dockers/traefik/reload.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Do nothing +# Théoriquement traefik gère tout seul sauf les changements dans le traefik.yml \ No newline at end of file