From c78fa84d5da2838002a0318c6961154fc60885f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Tue, 15 Jan 2019 17:18:37 +0400 Subject: [PATCH] Add alternative Traefik deployment with HTTPS Add Traefik version with HTTPS and domains Fix grafana domain in Traefik Fix ports in Traefik labels Set defaults for the Traefik public tag Fix prometheus name Add alternative instructions for Traefik with HTTPS to the README --- README.md | 108 +++++++++++++++++ docker-compose.traefik.yml | 237 +++++++++++++++++++++++++++++++++++++ 2 files changed, 345 insertions(+) create mode 100644 docker-compose.traefik.yml diff --git a/README.md b/README.md index 769e875..57768c8 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,114 @@ Services: * caddy (reverse proxy and basic auth provider for prometheus, alertmanager and unsee) +## Alternative install with Traefik and HTTPS + +If you have a Docker Swarm cluster with a global Traefik [set up as described in this article](https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232), you can deploy Swarmprom integrated with that global Traefik proxy. + +This way, each Swarmprom service will have its own domain, and each of them will be served using HTTPS, with certificates generated (and renewed) automatically. + +### Requisites + +These instructions assume you already have Traefik set up following that guide above, in short: + +* With automatic HTTPS certificate generation. +* A Docker Swarm network `traefik-public`. +* Filtering to only serve containers with a tag `traefik-public`. + +### Instructions + +* Clone this repository and enter into the directory: + +```bash +$ git clone https://github.com/stefanprodan/swarmprom.git +$ cd swarmprom +``` + +* Set and export an `ADMIN_USER` environment variable: + +```bash +export ADMIN_USER=admin +``` + +* Set and export an `ADMIN_PASSWORD` environment variable: + + +```bash +export ADMIN_PASSWORD=changethis +``` + +* Set and export a hashed version of the `ADMIN_PASSWORD` using `openssl`, it will be used by Traefik's HTTP Basic Auth for most of the services: + +```bash +export HASHED_PASSWORD=$(openssl passwd -apr1 $ADMIN_PASSWORD) +``` + +* Set and export a single variable with the username and password in "`htpasswd`" format: + +```bash +export USERNAME_PASSWORD=$ADMIN_USER:$HASHED_PASSWORD +``` + +* You can check the contents with: + +```bash +echo $USERNAME_PASSWORD +``` + +it will look like: + +``` +admin:$apr1$89eqM5Ro$CxaFELthUKV21DpI3UTQO. +``` + +* Create and export an environment variable `DOMAIN`, e.g.: + +```bash +export DOMAIN=example.com +``` + +and make sure that the following sub-domains point to your Docker Swarm cluster IPs: + +* `grafana.example.com` +* `alertmanager.example.com` +* `unsee.example.com` +* `prometheus.example.com` + +(and replace `example.com` with your actual domain). + +**Note**: You can also use a subdomain, like `swarmprom.example.com`. Just make sure that the subdomains point to (at least one of) your cluster IPs. Or set up a wildcard subdomain (`*`). + +* Set and export an environment variable with the tag used by Traefik public to filter services (by default, it's `traefik-public`): + +```bash +export TRAEFIK_PUBLIC_TAG=traefik-public +``` + +* If you are using Slack and want to integrate it, set the following environment variables: + +```bash +export SLACK_URL=https://hooks.slack.com/services/TOKEN +export SLACK_CHANNEL=devops-alerts +export SLACK_USER=alertmanager +``` + +**Note**: by using `export` when declaring all the environment variables above, the next command will be able to use them. + +* Deploy the Traefik version of the stack: + + +```bash +docker stack deploy -c docker-compose.traefik.yml swarmprom +``` + +To test it, go to each URL: + +* `https://grafana.example.com` +* `https://alertmanager.example.com` +* `https://unsee.example.com` +* `https://prometheus.example.com` + + ## Setup Grafana Navigate to `http://:3000` and login with user ***admin*** password ***admin***. diff --git a/docker-compose.traefik.yml b/docker-compose.traefik.yml new file mode 100644 index 0000000..773615e --- /dev/null +++ b/docker-compose.traefik.yml @@ -0,0 +1,237 @@ +version: "3.3" + +networks: + net: + driver: overlay + attachable: true + traefik-public: + external: true + +volumes: + prometheus: {} + grafana: {} + alertmanager: {} + +configs: + dockerd_config: + file: ./dockerd-exporter/Caddyfile + node_rules: + file: ./prometheus/rules/swarm_node.rules.yml + task_rules: + file: ./prometheus/rules/swarm_task.rules.yml + +services: + dockerd-exporter: + image: stefanprodan/caddy + networks: + - net + environment: + - DOCKER_GWBRIDGE_IP=172.18.0.1 + configs: + - source: dockerd_config + target: /etc/caddy/Caddyfile + deploy: + mode: global + resources: + limits: + memory: 128M + reservations: + memory: 64M + + cadvisor: + image: google/cadvisor + networks: + - net + command: -logtostderr -docker_only + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - /:/rootfs:ro + - /var/run:/var/run + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + deploy: + mode: global + resources: + limits: + memory: 128M + reservations: + memory: 64M + + grafana: + image: stefanprodan/swarmprom-grafana:5.3.4 + networks: + - net + environment: + - GF_SECURITY_ADMIN_USER=${ADMIN_USER:-admin} + - GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin} + - GF_USERS_ALLOW_SIGN_UP=false + #- GF_SERVER_ROOT_URL=${GF_SERVER_ROOT_URL:-localhost} + #- GF_SMTP_ENABLED=${GF_SMTP_ENABLED:-false} + #- GF_SMTP_FROM_ADDRESS=${GF_SMTP_FROM_ADDRESS:-grafana@test.com} + #- GF_SMTP_FROM_NAME=${GF_SMTP_FROM_NAME:-Grafana} + #- GF_SMTP_HOST=${GF_SMTP_HOST:-smtp:25} + #- GF_SMTP_USER=${GF_SMTP_USER} + #- GF_SMTP_PASSWORD=${GF_SMTP_PASSWORD} + volumes: + - grafana:/var/lib/grafana + deploy: + mode: replicated + replicas: 1 + placement: + constraints: + - node.role == manager + resources: + limits: + memory: 128M + reservations: + memory: 64M + labels: + - traefik.frontend.rule=Host:grafana.${DOMAIN} + - traefik.enable=true + - traefik.port=3000 + - traefik.tags=${TRAEFIK_PUBLIC_TAG:-traefik-public} + - traefik.docker.network=traefik-public + # Traefik service that listens to HTTP + - traefik.redirectorservice.frontend.entryPoints=http + - traefik.redirectorservice.frontend.redirect.entryPoint=https + # Traefik service that listens to HTTPS + - traefik.webservice.frontend.entryPoints=https + networks: + - default + - net + - traefik-public + + alertmanager: + image: stefanprodan/swarmprom-alertmanager:v0.14.0 + networks: + - net + environment: + - SLACK_URL=${SLACK_URL:-https://hooks.slack.com/services/TOKEN} + - SLACK_CHANNEL=${SLACK_CHANNEL:-general} + - SLACK_USER=${SLACK_USER:-alertmanager} + command: + - '--config.file=/etc/alertmanager/alertmanager.yml' + - '--storage.path=/alertmanager' + volumes: + - alertmanager:/alertmanager + deploy: + mode: replicated + replicas: 1 + placement: + constraints: + - node.role == manager + resources: + limits: + memory: 128M + reservations: + memory: 64M + labels: + - traefik.frontend.rule=Host:alertmanager.${DOMAIN} + - traefik.enable=true + - traefik.port=9093 + - traefik.tags=${TRAEFIK_PUBLIC_TAG:-traefik-public} + - traefik.docker.network=traefik-public + # Traefik service that listens to HTTP + - traefik.redirectorservice.frontend.entryPoints=http + - traefik.redirectorservice.frontend.redirect.entryPoint=https + # Traefik service that listens to HTTPS + - traefik.webservice.frontend.entryPoints=https + - traefik.frontend.auth.basic=${USERNAME_PASSWORD} + networks: + - default + - net + - traefik-public + + unsee: + image: cloudflare/unsee:v0.8.0 + networks: + - net + environment: + - "ALERTMANAGER_URIS=default:http://alertmanager:9093" + deploy: + mode: replicated + replicas: 1 + labels: + - traefik.frontend.rule=Host:unsee.${DOMAIN} + - traefik.enable=true + - traefik.port=8080 + - traefik.tags=${TRAEFIK_PUBLIC_TAG:-traefik-public} + - traefik.docker.network=traefik-public + # Traefik service that listens to HTTP + - traefik.redirectorservice.frontend.entryPoints=http + - traefik.redirectorservice.frontend.redirect.entryPoint=https + # Traefik service that listens to HTTPS + - traefik.webservice.frontend.entryPoints=https + - traefik.frontend.auth.basic=${USERNAME_PASSWORD} + networks: + - default + - net + - traefik-public + + node-exporter: + image: stefanprodan/swarmprom-node-exporter:v0.16.0 + networks: + - net + environment: + - NODE_ID={{.Node.ID}} + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + - /:/rootfs:ro + - /etc/hostname:/etc/nodename + command: + - '--path.sysfs=/host/sys' + - '--path.procfs=/host/proc' + - '--collector.textfile.directory=/etc/node-exporter/' + - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)' + - '--no-collector.ipvs' + deploy: + mode: global + resources: + limits: + memory: 128M + reservations: + memory: 64M + + prometheus: + image: stefanprodan/swarmprom-prometheus:v2.5.0 + networks: + - net + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--storage.tsdb.retention=24h' + volumes: + - prometheus:/prometheus + configs: + - source: node_rules + target: /etc/prometheus/swarm_node.rules.yml + - source: task_rules + target: /etc/prometheus/swarm_task.rules.yml + deploy: + mode: replicated + replicas: 1 + placement: + constraints: + - node.role == manager + resources: + limits: + memory: 2048M + reservations: + memory: 128M + labels: + - traefik.frontend.rule=Host:prometheus.${DOMAIN} + - traefik.enable=true + - traefik.port=9090 + - traefik.tags=${TRAEFIK_PUBLIC_TAG:-traefik-public} + - traefik.docker.network=traefik-public + # Traefik service that listens to HTTP + - traefik.redirectorservice.frontend.entryPoints=http + - traefik.redirectorservice.frontend.redirect.entryPoint=https + # Traefik service that listens to HTTPS + - traefik.webservice.frontend.entryPoints=https + - traefik.frontend.auth.basic=${USERNAME_PASSWORD} + networks: + - default + - net + - traefik-public