├── .gitignore ├── README.md ├── examples ├── docker-swarming-dind │ ├── .gitignore │ ├── README.md │ ├── docker-compose-stack-swarmpit.yml │ ├── docker-compose-whoami-stack.yml │ ├── docker-swarm-gui.sh │ ├── show-metrics.sh │ ├── start-dind.sh │ ├── start-portainer.sh │ ├── start-swarmpit.sh │ ├── start-traefik.sh │ ├── start-whoami.sh │ ├── start-worker.sh │ ├── stop-dind.sh │ └── test-traefik.sh ├── drill │ ├── Dockerfile │ ├── README.md │ ├── build.sh │ └── drill.sh ├── httpd │ ├── Dockerfile │ ├── README.md │ ├── docker-compose.yml │ └── hello │ │ └── index.html ├── nginx │ └── docker-compose.yml ├── orbiter │ ├── README.md │ ├── orbiter.yml │ └── start-orbiter.sh ├── prometheus │ ├── .gitignore │ ├── Dockerfile │ ├── Dockerfile.simple │ ├── README.md │ ├── build.sh │ ├── build.simple.sh │ ├── dashboards │ │ └── 179.dashboard │ ├── docker-compose.yml │ ├── etc │ │ ├── alert.rules_nodes │ │ ├── alert.rules_service-groups │ │ ├── alert.rules_tasks │ │ └── prometheus.yml │ ├── prometheus.yml │ ├── start-exporter.sh │ ├── start-prom-services.sh │ ├── start-prom.sh │ ├── start-whoami.sh │ └── stop-prom-services.sh ├── proxy │ ├── README.md │ ├── traefik-stack-v2.yml │ ├── traefik-stack.yml │ └── whoami-stack.yml └── simple │ ├── README.md │ └── docker-compose.yml ├── images └── usemethod_flow.png └── slidefire └── traefik-with-docker ├── .gitignore ├── Description.md ├── LICENSE ├── build.sh ├── images ├── bee42-TOP2POTt.png ├── bee42_logo.png ├── build4friends.png ├── docker-book-german-adrian.jpg ├── docker-camp.jpg ├── docker-swarm-logo.png ├── docker-swarm-visualizer-1.png ├── docker-swarm-visualizer-2.png ├── docker-swarming-dind.png ├── letsencrypt-flow.png ├── peter-rossbach.jpg ├── setlog.png ├── traefik-architecture-background.png ├── traefik-architecture.png ├── traefik-health.png ├── traefik-logo.png ├── traefik-ui.png └── traefik.png ├── picture └── traefik.graffle │ ├── data.plist │ └── image1.png ├── print.sh ├── run.sh ├── save.sh ├── slidefire.sh └── slides.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Træfɪk with Docker Swarming 2 | 3 | This example use a local DinD Swarming Cluster to show 4 | how you can use docker swarming for your microservices. 5 | 6 | We use [træfɪk](https://traefik.io/) for simplify your dynamic service publishing and http reverse proxy. 7 | 8 | We add a lot of more example and fix some scripts for better handling. 9 | 10 | ## Loadbalancing with Træfɪk at a docker swarming fleet 11 | 12 | Proudly present first at : Docker Meetup Bochum 1.12.2016 : Træfɪk and more Træfɪk 13 | 14 | * https://www.meetup.com/de-DE/Docker-Bochum/events/235649414/ 15 | 16 | We explain the Træfɪk basics 17 | 18 | ![](slidefire/traefik-with-docker/images/traefik-architecture-background.png) 19 | 20 | but also some useful tips to use Træfɪk with docker swarming mode 21 | 22 | ![](slidefire/traefik-with-docker/images/traefik.png) 23 | 24 | Test your setup with DinD... 25 | 26 | ![](slidefire/traefik-with-docker/images/docker-swarming-dind.png) 27 | 28 | 29 | Start this presentation with 30 | * `docker run -d -ti -p 4212:80 infrabricks/traefik-with-docker` 31 | * `open http://:4212/traefik-with-docker` 32 | 33 | Regards 34 | Peter Rossbach (peter.rossbach@bee42.com) @PRossbach 35 | Niclas Mietz (niclas.mietz@bee42.com) @solidnerd 36 | 37 | ## Links 38 | 39 | * https://codefresh.io/blog/deploy-docker-compose-v3-swarm-mode-cluster/ 40 | * https://traefik.io/ 41 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/.gitignore: -------------------------------------------------------------------------------- 1 | rdata 2 | swarmpit 3 | *.dab 4 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/README.md: -------------------------------------------------------------------------------- 1 | # start a local docker swarming DinD 2 | 3 | 4 | ```shell 5 | # use this at Docker for Mac 6 | # docker <= 18.09 7 | # export DOCKER_ORCHESTRATOR=swarm 8 | $ export DOCKER_STACK_ORCHESTRATOR=swarm 9 | $ docker network inspect bridge 10 | [ 11 | { 12 | "Name": "bridge", 13 | "Id": "59eb10f40b080bfc9a124092e20be0136d26a8c74bd3eb4be078332a012c1634", 14 | "Created": "2019-10-18T07:36:26.009159148Z", 15 | "Scope": "local", 16 | "Driver": "bridge", 17 | "EnableIPv6": false, 18 | "IPAM": { 19 | "Driver": "default", 20 | "Options": null, 21 | "Config": [ 22 | { 23 | "Subnet": "172.17.0.0/16", 24 | "Gateway": "172.17.0.1" 25 | } 26 | ] 27 | }, 28 | ... 29 | # 30 | $ export GATEWAY_IP=$(docker network inspect bridge |jq -r '.[] | .IPAM.Config|.[0].Gateway') 31 | $ ./start-dind.sh --advertise-addr $GATEWAY_IP 32 | # https://doc.traefik.io/traefik/v1.7/configuration/backends/docker/#on-containers 33 | $ ./start-traefik.sh 34 | $ ./start-whoami.sh 35 | ``` 36 | 37 | start dind at private network interface 38 | 39 | ```shell 40 | $ ./start-dind.sh --advertise-addr 10.14.0.11 41 | ``` 42 | 43 | Lookup and scale 44 | 45 | ```shell 46 | $ docker service update --replicas 2 whoami1 47 | $ docker service scale whoami1=3 48 | $ curl -H Host:whoami1.traefik http://localhost 49 | $ curl -H Host:whoami1.traefik http://localhost 50 | ``` 51 | 52 | stop the swarming DinD cluster 53 | 54 | ``` 55 | $ ./stop-dind.sh 56 | ``` 57 | 58 | ## Push your own image to insecure registry 59 | 60 | ```yaml 61 | docker tag nginx:1.19.3 127.0.0.1:5004/bee42/nginx:1.19.3 62 | docker push 127.0.0.1:5004/bee42/nginx:1.19.3 63 | # create a service 64 | docker service create \ 65 | --name web1 \ 66 | --label orbiter=true \ 67 | --label traefik.port=80 \ 68 | --label traefik.enable=true \ 69 | --label traefik.backend.loadbalancer.method=drr \ 70 | --network traefik-net \ 71 | 172.17.0.1:5004/bee42/nginx:1.19.3 72 | 73 | ``` 74 | 75 | ## Links 76 | 77 | * https://hub.docker.com/_/docker/ 78 | * https://github.com/swarmpit/swarmpit 79 | * https://doc.traefik.io/traefik/v1.7/configuration/backends/docker/#on-containers -------------------------------------------------------------------------------- /examples/docker-swarming-dind/docker-compose-stack-swarmpit.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | app: 5 | image: swarmpit/swarmpit:latest 6 | environment: 7 | SWARMPIT_DB: http://db:5984 8 | volumes: 9 | - /var/run/docker.sock:/var/run/docker.sock:ro 10 | ports: 11 | - 888:8080 12 | networks: 13 | - net 14 | deploy: 15 | resources: 16 | limits: 17 | cpus: '0.50' 18 | memory: 1024M 19 | reservations: 20 | cpus: '0.25' 21 | memory: 512M 22 | placement: 23 | constraints: 24 | - node.role == manager 25 | 26 | db: 27 | image: klaemo/couchdb:2.0.0 28 | volumes: 29 | - db-data:/opt/couchdb/data 30 | networks: 31 | - net 32 | deploy: 33 | resources: 34 | limits: 35 | cpus: '0.30' 36 | memory: 512M 37 | reservations: 38 | cpus: '0.15' 39 | memory: 256M 40 | 41 | event-collector: 42 | image: swarmpit/event-collector:latest 43 | volumes: 44 | - /var/run/docker.sock:/var/run/docker.sock:ro 45 | networks: 46 | - net 47 | environment: 48 | - DOCKER_API_VERSION=1.35 49 | deploy: 50 | mode: global 51 | resources: 52 | limits: 53 | cpus: '0.10' 54 | memory: 64M 55 | reservations: 56 | cpus: '0.05' 57 | memory: 32M 58 | 59 | networks: 60 | net: 61 | driver: overlay 62 | 63 | volumes: 64 | db-data: 65 | driver: local 66 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/docker-compose-whoami-stack.yml: -------------------------------------------------------------------------------- 1 | version: "3.0" 2 | 3 | networks: 4 | traefik-net: 5 | external: 6 | name: traefik-net 7 | 8 | services: 9 | whoami: 10 | image: 127.0.0.1:5000/emilevauge/whoami 11 | networks: 12 | - traefik-net 13 | labels: 14 | - com.docker.stack.namespace=traefik-net 15 | - orbiter=true 16 | - traefik.port=80 17 | - traefik.enable=true 18 | - traefik.backend.loadbalancer=drr 19 | deploy: 20 | mode: global 21 | placement: 22 | constraints: [node.role == worker] -------------------------------------------------------------------------------- /examples/docker-swarming-dind/docker-swarm-gui.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | docker run -it -d -p 5090:8080 \ 5 | -v /var/run/docker.sock:/var/run/docker.sock \ 6 | julienbreux/docker-swarm-gui:latest 7 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/show-metrics.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run --rm --network=host alpine sh -c 'apk add --no-cache -q curl && curl localhost:4999/metrics' 3 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/start-dind.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e -x 3 | export DOCKER_STACK_ORCHESTRATOR=swarm 4 | DOCKER_WORKER_VERSION="20.10.12-dind" 5 | export GATEWAY_IP=$(docker network inspect bridge |jq -r '.[] | .IPAM.Config|.[0].Gateway') 6 | 7 | if [ "$(docker info --format '{{ json .Swarm }}' |jq '.NodeID')" == "\"\"" ];then 8 | docker swarm init $@ 9 | fi 10 | 11 | SWARM_TOKEN=$(docker swarm join-token -q worker) 12 | SWARM_MASTER=$(docker info | grep -w 'Node Address' | awk '{print $3}') 13 | : NUM_WORKERS=${NUM_WORKERS:=3} 14 | 15 | mkdir -p $PWD/rdata 16 | 17 | if [ ! "$(docker service ls --filter name=mirror_registry -q)" ];then 18 | docker service create --name mirror_registry \ 19 | --detach=true \ 20 | --constraint 'node.role == manager' \ 21 | --mount type=bind,source=$PWD/rdata,target=/var/lib/registry \ 22 | -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \ 23 | --publish 5001:5000 \ 24 | registry:2 25 | 26 | sleep 5 27 | fi 28 | 29 | echo "Start swarm worker" 30 | 31 | for WORKER_NUMBER in $(seq ${NUM_WORKERS}); do 32 | if [ ! "$(docker ps --filter name=worker-${WORKER_NUMBER} -q)" ];then 33 | docker run -d --privileged --name worker-${WORKER_NUMBER} \ 34 | --hostname=worker-${WORKER_NUMBER} \ 35 | -p ${WORKER_NUMBER}2375:2375 \ 36 | -e DOCKER_TLS_CERTDIR= \ 37 | docker:${DOCKER_WORKER_VERSION} \ 38 | --storage-driver=overlay2 \ 39 | --registry-mirror http://${GATEWAY_IP}:5001 \ 40 | --insecure-registry http://${GATEWAY_IP}:5004 \ 41 | --metrics-addr 0.0.0.0:4999 \ 42 | --experimental 43 | sleep 30 44 | docker --host=127.0.0.1:${WORKER_NUMBER}2375 swarm join \ 45 | --token ${SWARM_TOKEN} \ 46 | ${SWARM_MASTER}:2377 47 | fi 48 | done 49 | 50 | if [ ! "$(docker ps --filter name=visualizer -q)" ];then 51 | docker run -it -d \ 52 | -p 5080:8080 \ 53 | --name visualizer \ 54 | --restart always \ 55 | -v /var/run/docker.sock:/var/run/docker.sock \ 56 | dockersamples/visualizer 57 | fi 58 | 59 | if [ ! "$(docker service ls --filter name=registry -q)" ];then 60 | docker service create --name registry \ 61 | --detach=true \ 62 | --constraint 'node.role == manager' \ 63 | --publish 5004:5000 registry:2 64 | fi 65 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/start-portainer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | 5 | if [ ! "$(docker ps --filter name=portainer -q)" ];then 6 | docker run -d -p 9000:9000 \ 7 | --name portainer \ 8 | -v /var/run/docker.sock:/var/run/docker.sock \ 9 | portainer/portainer 10 | fi 11 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/start-swarmpit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | export DOCKER_ORCHESTRATOR=swarm 5 | if [ ! "$(docker service ls --filter name=swarmpit_app -q)" ];then 6 | docker stack deploy -c docker-compose-stack-swarmpit.yml swarmpit 7 | fi 8 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/start-traefik.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # create traefik-net network 4 | : NETWORK=${NETWORK:=traefik-net} 5 | if [ ! "$(docker network ls --filter name=$NETWORK -q)" ];then 6 | docker network create --driver=overlay --attachable $NETWORK 7 | fi 8 | 9 | if [ ! "$(docker service ls --filter name=traefik -q)" ];then 10 | 11 | docker service create \ 12 | --name traefik \ 13 | --constraint=node.role==manager \ 14 | --publish 80:80 \ 15 | --publish 8080:8080 \ 16 | --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \ 17 | --network ${NETWORK} \ 18 | traefik:v1.7.34 \ 19 | --accesslogsfile=/access.log \ 20 | --checknewversion=false \ 21 | --api.dashboard=true \ 22 | --metrics.prometheus \ 23 | --metrics.prometheus.buckets= [0.1,0.3,1.2,5.0] \ 24 | --docker \ 25 | --docker.exposedbydefault=false \ 26 | --docker.swarmmode=true \ 27 | --docker.domain=traefik \ 28 | --docker.watch 29 | fi 30 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/start-whoami.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | 5 | # create traefik-net network 6 | 7 | : NETWORK=${NETWORK:=traefik-net} 8 | if [ ! "$(docker network ls --filter name=$NETWORK -q)" ];then 9 | docker network create --driver=overlay --attachable $NETWORK 10 | fi 11 | 12 | 13 | # pull image if not available 14 | whoami=bee42/whoami:2.1.0 15 | #if [ ! "$(docker images -q 127.0.0.1:5000/$whoami)" ];then 16 | # docker pull $whoami 17 | # docker tag $whoami 127.0.0.1:5000/$whoami 18 | # docker push 127.0.0.1:5000/$whoami 19 | #fi 20 | 21 | : SERVICES_COUNT=${SERVICES_COUNT:=1} 22 | 23 | if [ ! -z "$1" ] ; then 24 | SERVICES_COUNT=$1 25 | fi 26 | 27 | for i in $(seq $SERVICES_COUNT); do 28 | if [ ! "$(docker service ls --filter name=whoami${i} -q)" ];then 29 | docker service create \ 30 | --name whoami${i} \ 31 | --label orbiter=true \ 32 | --label traefik.port=80 \ 33 | --label traefik.enable=true \ 34 | --label traefik.backend.loadbalancer.method=drr \ 35 | --network $NETWORK \ 36 | $whoami 37 | fi 38 | done 39 | -------------------------------------------------------------------------------- /examples/docker-swarming-dind/start-worker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e -x 4 | export DOCKER_STACK_ORCHESTRATOR=swarm 5 | DOCKER_WORKER_VERSION="20.10.12-dind" 6 | export GATEWAY_IP=$(docker network inspect bridge |jq -r '.[] | .IPAM.Config|.[0].Gateway') 7 | 8 | if [ ! -z "$1" ] ; then 9 | WORKER_NUMBER=$1 10 | else 11 | echo "usage: $0 apk add --update curl apache2-utils drill 9 | > drill app2 10 | > ping app2 11 | > drill tasks.app2 12 | ``` 13 | -------------------------------------------------------------------------------- /examples/drill/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker build -t 127.0.0.1:5000/bee42/drill . 4 | docker push 127.0.0.1:5000/bee42/drill 5 | 6 | -------------------------------------------------------------------------------- /examples/drill/drill.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | : NETWORK=${NETWORK:=traefik-net} 4 | if [ ! "$(docker network ls --filter name=$NETWORK -q)" ];then 5 | docker network create --driver=overlay --attachable $NETWORK 6 | fi 7 | 8 | if [ ! $(docker ps -q --filter label=com.docker.swarm.service.name=debug-$NETWORK) ];then 9 | docker service create --network $NETWORK --name debug-$NETWORK --constraint=node.role==manager \ 10 | 127.0.0.1:5000/bee42/drill sleep 1000000000 11 | sleep 2 12 | fi 13 | 14 | CID=$(docker ps -q --filter label=com.docker.swarm.service.name=debug-$NETWORK) 15 | docker exec -ti $CID /bin/sh 16 | -------------------------------------------------------------------------------- /examples/httpd/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM httpd 2 | RUN mkdir -p $HTTPD_PREFIX/htdocs/hello 3 | COPY hello/* $HTTPD_PREFIX/htdocs/hello 4 | 5 | -------------------------------------------------------------------------------- /examples/httpd/README.md: -------------------------------------------------------------------------------- 1 | # check 2 | 3 | ``` 4 | $ echo "bee42" | docker secret create my_secret - 5 | $ docker stack deploy --compose-file=docker-compose.yml ìndex 6 | $ docker exec -ti index.1.xxx /bin/sh 7 | > cd /run/secrets/ 8 | > ls 9 | my_secret 10 | > cat my_secret 11 | bee42 12 | > exit 13 | ``` 14 | -------------------------------------------------------------------------------- /examples/httpd/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # http://stackoverflow.com/questions/42139605/how-do-you-manage-secret-values-with-docker-compose-v3-1 2 | # Here's an example of using a secret, my_secret, that's been created on the swarm via docker secret create: 3 | 4 | version: "3.1" 5 | networks: 6 | traefik-net: 7 | external: true 8 | services: 9 | index: 10 | build: . 11 | image: 127.0.0.1:5000/bee42/index 12 | ports: 13 | - "5091:80" 14 | networks: 15 | - traefik-net 16 | labels: 17 | - traefik.enable=true 18 | - traefik.port=80 19 | - traefik.frontend.rule=Path=/hello 20 | deploy: 21 | mode: replicated 22 | labels: [com.docker.stack.namespace=index] 23 | placement: 24 | constraints: [node.role == worker] 25 | 26 | -------------------------------------------------------------------------------- /examples/httpd/hello/index.html: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /examples/nginx/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # http://stackoverflow.com/questions/42139605/how-do-you-manage-secret-values-with-docker-compose-v3-1 2 | # Here's an example of using a secret, my_secret, that's been created on the swarm via docker secret create: 3 | 4 | version: "3.1" 5 | networks: 6 | traefik-net: 7 | external: true 8 | services: 9 | web: 10 | image: 172.17.0.1:5004/bee42/nginx:1.19.3 11 | networks: 12 | - traefik-net 13 | labels: 14 | - traefik.enable=true 15 | - traefik.port=80 16 | deploy: 17 | mode: replicated 18 | labels: [com.docker.stack.namespace=web] 19 | placement: 20 | constraints: [node.role == worker] 21 | 22 | -------------------------------------------------------------------------------- /examples/orbiter/README.md: -------------------------------------------------------------------------------- 1 | # Start orbiter to scale up and down 2 | 3 | ``` 4 | $ docker service create --name whoami --label orbiter=true emilevauge/whoami 5 | $ ./start-orbiter.sh 6 | $ curl -v -X POST http://127.0.0.1:8000/handle/autodetect_swarm/whoami/up 7 | $ docker service ls 8 | b0fdp2ty71co whoami replicated 2/2 9 | $ curl -v -X POST http://127.0.0.1:8000/handle/autodetect_swarm/whoami/down 10 | 11 | ``` 12 | 13 | ## Links 14 | 15 | * https://github.com/gianarb/orbiter 16 | 17 | -------------------------------------------------------------------------------- /examples/orbiter/orbiter.yml: -------------------------------------------------------------------------------- 1 | utoscalers: 2 | events: 3 | provider: swarm 4 | parameters: 5 | policies: 6 | autodetect_swarm/whoami: 7 | up: 4 8 | down: 3 9 | -------------------------------------------------------------------------------- /examples/orbiter/start-orbiter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e -x 3 | 4 | if [ ! "$(docker ps --filter name=orbiter -q)" ];then 5 | docker run -d -it --name orbiter \ 6 | -v /var/run/docker.sock:/var/run/docker.sock \ 7 | -v ${PWD}/orbiter.yml:/etc/orbiter.yml \ 8 | -p 8000:8000 gianarb/orbiter daemon 9 | fi 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/prometheus/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | -------------------------------------------------------------------------------- /examples/prometheus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM prom/prometheus 2 | 3 | LABEL maintainer Peter Rossbach 4 | 5 | ARG "VERSION=0.1.0-dev" 6 | ARG "BUILD_DATE=unknown" 7 | ARG "VCS_URL=unknown" 8 | ARG "VCS_REF=unkown" 9 | ARG "VCS_BRANCH=unknown" 10 | 11 | LABEL org.label-schema.build-date=$BUILD_DATE \ 12 | org.label-schema.docker.dockerfile="/Dockerfile" \ 13 | org.label-schema.license="Apache 2.0" \ 14 | org.label-schema.name="prometheus" \ 15 | org.label-schema.url="https://github.com/bee42/traefik-with-docker/" \ 16 | org.label-schema.vcs-branch=$VCS_BRANCH \ 17 | org.label-schema.vcs-ref=$VCS_REF \ 18 | org.label-schema.vcs-url=$VCS_URL \ 19 | org.label-schema.vcs-type="Git" \ 20 | org.label-schema.version=$VERSION \ 21 | org.label-schema.schema-version="1.0" \ 22 | org.label-schema.vendor="bee42 solutions gmbh" \ 23 | org.label-schema.description="Scrapes node-exporter, cadvisor, prometheus and swarm metrics (4999 port)." \ 24 | org.label-schema.usage="examples/prometheus/README.md" \ 25 | org.label-schema.url="https://github.com/bee42/traefik-with-docker/blob/master/examples/prometheus/README.md" 26 | 27 | COPY etc /etc/prometheus 28 | -------------------------------------------------------------------------------- /examples/prometheus/Dockerfile.simple: -------------------------------------------------------------------------------- 1 | FROM prom/prometheus 2 | 3 | LABEL maintainer Peter Rossbach 4 | 5 | ARG "VERSION=0.1.0-dev" 6 | ARG "BUILD_DATE=unknown" 7 | ARG "VCS_URL=unknown" 8 | ARG "VCS_REF=unkown" 9 | ARG "VCS_BRANCH=unknown" 10 | 11 | LABEL org.label-schema.build-date=$BUILD_DATE \ 12 | org.label-schema.docker.dockerfile="/Dockerfile.simple" \ 13 | org.label-schema.license="Apache 2.0" \ 14 | org.label-schema.name="prometheus" \ 15 | org.label-schema.url="https://github.com/bee42/traefik-with-docker/" \ 16 | org.label-schema.vcs-branch=$VCS_BRANCH \ 17 | org.label-schema.vcs-ref=$VCS_REF \ 18 | org.label-schema.vcs-url=$VCS_URL \ 19 | org.label-schema.vcs-type="Git" \ 20 | org.label-schema.version=$VERSION \ 21 | org.label-schema.schema-version="1.0" \ 22 | org.label-schema.vendor="bee42 solutions gmbh" \ 23 | org.label-schema.description="Scrapes node-exporter and cadvisor" \ 24 | org.label-schema.usage="examples/prometheus/README.md" \ 25 | org.label-schema.url="https://github.com/bee42/traefik-with-docker/blob/master/examples/prometheus/README.md" 26 | 27 | COPY prometheus.yml /etc/prometheus/prometheus.yml 28 | -------------------------------------------------------------------------------- /examples/prometheus/README.md: -------------------------------------------------------------------------------- 1 | # Prometheus Swarm 2 | 3 | **Experiment** 4 | 5 | More info available about this idea and its configuration you can find in this post [Docker Daemon Metrics in Prometheus](https://medium.com/@basilio.vera/docker-swarm-metrics-in-prometheus-e02a6a5745a#.ei8n7eykb) 6 | 7 | A sample image that can be used as a base for collecting Swarm mode metrics in Prometheus 8 | 9 | ## How to use it 10 | 11 | You can configure the full system with the next commands, that create the Prometheus, Grafana and exporters services needed. 12 | 13 | Please add your Slack Token! 14 | 15 | __ToDo__: check running and setup slack Token 16 | 17 | ``` 18 | $ ./build.sh 19 | $ docker-compose build 20 | $ docker-compose push 21 | $ GF_PASSWORD=12345678 SLACK_TOKEN=xxx docker stack deploy --compose-file docker-compose.yml prometheus 22 | $ docker service ls 23 | ``` 24 | If your need a attachable network it is currently not supported by docker-compose use an external network 25 | 26 | * http://blog.alexellis.io/docker-stacks-attachable-networks/ 27 | 28 | Once everyting is running you just need to connect to grafana and import the [Docker Swarm & Container Overview](https://grafana.net/dashboards/609) 29 | 30 | __ToDo__: remove Elasticsearch dependency 31 | 32 | In case you don't have an Elasticsearch instance with logs and errors you could provide an invalid configuration. But I suggest you to have it correctly configured to get all the dashboard offers. 33 | 34 | ### Docker Engine Metrics 35 | 36 | In case you have activated the metrics endpoint in your docker swarm cluster you could import the [Docker Engine Metrics](https://grafana.net/dashboards/1229) dashboard as well, which offers complementary data about the docker daemon itself. 37 | 38 | ## Setup Grafana 39 | 40 | * https://github.com/grafana/grafana-docker 41 | * https://grafana.net/plugins 42 | * https://grafana.net/dashbords 43 | 44 | 45 | ``` 46 | docker run \ 47 | -d \ 48 | -p 3000:3000 \ 49 | --name=grafana \ 50 | -e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" \ 51 | grafana/grafana 52 | ``` 53 | 54 | ### Grafana Dashboards 55 | 56 | | Link | description | 57 | |:-----------------------------------|:------------------------------------------------| 58 | | https://grafana.net/dashboards/179 | Docker Basic dashbaord | 59 | | https://grafana.net/dashboards/893 | This dashboard display Docker and system metric | 60 | 61 | ### Setup Grafana datasources 62 | 63 | Use the grafana API to finish the setup! 64 | 65 | * http://docs.grafana.org/reference/http_api/ 66 | 67 | ToDo: 68 | 69 | * Check if datasoure available! 70 | * Check first start, and only then configure! 71 | * Setup this as start script 72 | * Setup some default dashboards 73 | 74 | ``` 75 | echo 'Starting Grafana...' 76 | /run.sh "$@" & 77 | AddDataSource() { 78 | curl 'http://admin:${GF_SECURITY_ADMIN_PASSWORD}@127.0.0.1:3000/api/datasources' \ 79 | -X POST \ 80 | -H 'Content-Type: application/json;charset=UTF-8' \ 81 | --data-binary \ 82 | '{"name":"Prometheus","type":"prometheus","url":"http://prometheus:9090","access":"proxy","isDefault":true}' 83 | } 84 | until AddDataSource; do 85 | echo 'Configuring Grafana...' 86 | sleep 1 87 | done 88 | echo 'Done!' 89 | wait 90 | ``` 91 | 92 | ``` 93 | 94 | $ export GF_SECURITY_ADMIN_PASSWORD=12345678 95 | $ mkdir -p dashboards 96 | $ cd dashboards 97 | $ curl "http://admin:${GF_SECURITY_ADMIN_PASSWORD}@127.0.0.1:3000/api/datasources" \ 98 | -X POST \ 99 | -H 'Content-Type: application/json;charset=UTF-8' \ 100 | --data-binary \ 101 | '{"name":"Prometheus","type":"prometheus","url":"http://prometheus:9090","access":"proxy","isDefault":true}' 102 | $ curl -s https://grafana.net/api/dashboards/179/revisions/5/download >179.dashboard 103 | $ vi 179.dashboard 104 | # Add {"dashboard": {...}, "overwrite":false} 105 | # replace ${DS_PROMETHEUS} with Prometheus 106 | $ curl "http://admin:${GF_SECURITY_ADMIN_PASSWORD}@127.0.0.1:3000/api/dashboards/db" \ 107 | -X POST \ 108 | -H 'Content-Type: application/json;charset=UTF-8' \ 109 | -d @179.dashboard 110 | ``` 111 | 112 | __Warning__: Adjust Timeslot of dashboard to 2h! 113 | 114 | The time between the dashboard user and the container / host appears to be different. 115 | 116 | ### Monitoring the Rate, Error and Duration of every service 117 | 118 | * https://www.weave.works/prometheus-and-kubernetes-monitoring-your-applications/ 119 | * PROM QL queries 120 | * Alertrules 121 | * Scraping from kubernetes service 122 | 123 | * https://github.com/weaveworks/grafanalib 124 | * Generation of Grafana dashboards 125 | * RED Method 126 | 127 | * http://www.brendangregg.com/usemethod.html 128 | 129 | ![](images/usemethod_flow.png) 130 | 131 | ## Prometheus 132 | 133 | ### cli 134 | 135 | * https://github.com/prometheus-junkyard/prometheus_cli 136 | 137 | __Warning__ 138 | ``` 139 | $ docker run --rm -ti --network monitoring prom/prometheus-cli -server="http://prometheus:9090" metrics 140 | ``` 141 | 142 | ## Links 143 | 144 | * https://github.com/bvis/docker-node-exporter 145 | * https://github.com/bvis/docker-prometheus-swarm 146 | -------------------------------------------------------------------------------- /examples/prometheus/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | IMAGE=prometheus 3 | ACCOUNT=127.0.0.1:5000/bee42 4 | TAG_LONG=0.1.0 5 | 6 | BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` 7 | DATE=`date -u +"%Y-%m-%dT%H-%M-%SZ"` 8 | 9 | docker build \ 10 | -f Dockerfile \ 11 | --build-arg BUILD_DATE=$BUILD_DATE \ 12 | --build-arg VCS_REF=`git rev-parse --short HEAD` \ 13 | --build-arg VERSION=$(git describe --tags) \ 14 | --build-arg VCS_URL=$(git config --get remote.origin.url) \ 15 | --build-arg VCS_BRANCH=$(git rev-parse --abbrev-ref HEAD) \ 16 | -t="${ACCOUNT}/$IMAGE" \ 17 | -t="${ACCOUNT}/$IMAGE:$DATE" \ 18 | -t="${ACCOUNT}/$IMAGE:$TAG_LONG" \ 19 | . 20 | -------------------------------------------------------------------------------- /examples/prometheus/build.simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | IMAGE=prometheus 3 | ACCOUNT=127.0.0.1:5000/bee42 4 | TAG_LONG=0.1.0 5 | 6 | BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` 7 | DATE=`date -u +"%Y-%m-%dT%H-%M-%SZ"` 8 | 9 | docker build \ 10 | -f Dockerfile.simple \ 11 | --build-arg BUILD_DATE=$BUILD_DATE \ 12 | --build-arg VCS_REF=`git rev-parse --short HEAD` \ 13 | --build-arg VERSION=$(git describe --tags) \ 14 | --build-arg VCS_URL=$(git config --get remote.origin.url) \ 15 | --build-arg VCS_BRANCH=$(git rev-parse --abbrev-ref HEAD) \ 16 | -t="${ACCOUNT}/$IMAGE" \ 17 | -t="${ACCOUNT}/$IMAGE:$DATE" \ 18 | -t="${ACCOUNT}/$IMAGE:$TAG_LONG" \ 19 | . 20 | -------------------------------------------------------------------------------- /examples/prometheus/dashboards/179.dashboard: -------------------------------------------------------------------------------- 1 | { 2 | "dashboard": 3 | { 4 | "id": null, 5 | "title": "Docker Dashboard", 6 | "description": "Docker Monitoring Template", 7 | "tags": [ 8 | "docker" 9 | ], 10 | "style": "dark", 11 | "timezone": "browser", 12 | "editable": true, 13 | "hideControls": false, 14 | "sharedCrosshair": true, 15 | "rows": [ 16 | { 17 | "collapse": false, 18 | "editable": true, 19 | "height": "250px", 20 | "panels": [ 21 | { 22 | "cacheTimeout": null, 23 | "colorBackground": false, 24 | "colorValue": false, 25 | "colors": [ 26 | "rgba(50, 172, 45, 0.97)", 27 | "rgba(237, 129, 40, 0.89)", 28 | "rgba(245, 54, 54, 0.9)" 29 | ], 30 | "datasource": "Prometheus", 31 | "editable": true, 32 | "error": false, 33 | "format": "percent", 34 | "gauge": { 35 | "maxValue": 100, 36 | "minValue": 0, 37 | "show": true, 38 | "thresholdLabels": false, 39 | "thresholdMarkers": true 40 | }, 41 | "id": 4, 42 | "interval": null, 43 | "isNew": true, 44 | "links": [], 45 | "mappingType": 1, 46 | "mappingTypes": [ 47 | { 48 | "name": "value to text", 49 | "value": 1 50 | }, 51 | { 52 | "name": "range to text", 53 | "value": 2 54 | } 55 | ], 56 | "maxDataPoints": 100, 57 | "nullPointMode": "connected", 58 | "nullText": null, 59 | "postfix": "", 60 | "postfixFontSize": "50%", 61 | "prefix": "", 62 | "prefixFontSize": "50%", 63 | "rangeMaps": [ 64 | { 65 | "from": "null", 66 | "text": "N/A", 67 | "to": "null" 68 | } 69 | ], 70 | "span": 4, 71 | "sparkline": { 72 | "fillColor": "rgba(31, 118, 189, 0.18)", 73 | "full": false, 74 | "lineColor": "rgb(31, 120, 193)", 75 | "show": false 76 | }, 77 | "targets": [ 78 | { 79 | "expr": "(sum(node_memory_MemTotal) - sum(node_memory_MemFree+node_memory_Buffers+node_memory_Cached) ) / sum(node_memory_MemTotal) * 100", 80 | "interval": "10s", 81 | "intervalFactor": 1, 82 | "refId": "A", 83 | "step": 10 84 | } 85 | ], 86 | "thresholds": "65, 90", 87 | "title": "Memory usage", 88 | "type": "singlestat", 89 | "valueFontSize": "80%", 90 | "valueMaps": [ 91 | { 92 | "op": "=", 93 | "text": "N/A", 94 | "value": "null" 95 | } 96 | ], 97 | "valueName": "current" 98 | }, 99 | { 100 | "cacheTimeout": null, 101 | "colorBackground": false, 102 | "colorValue": false, 103 | "colors": [ 104 | "rgba(50, 172, 45, 0.97)", 105 | "rgba(237, 129, 40, 0.89)", 106 | "rgba(245, 54, 54, 0.9)" 107 | ], 108 | "datasource": "Prometheus", 109 | "decimals": 2, 110 | "editable": true, 111 | "error": false, 112 | "format": "percent", 113 | "gauge": { 114 | "maxValue": 100, 115 | "minValue": 0, 116 | "show": true, 117 | "thresholdLabels": false, 118 | "thresholdMarkers": true 119 | }, 120 | "id": 6, 121 | "interval": null, 122 | "isNew": true, 123 | "links": [], 124 | "mappingType": 1, 125 | "mappingTypes": [ 126 | { 127 | "name": "value to text", 128 | "value": 1 129 | }, 130 | { 131 | "name": "range to text", 132 | "value": 2 133 | } 134 | ], 135 | "maxDataPoints": 100, 136 | "nullPointMode": "connected", 137 | "nullText": null, 138 | "postfix": "", 139 | "postfixFontSize": "50%", 140 | "prefix": "", 141 | "prefixFontSize": "50%", 142 | "rangeMaps": [ 143 | { 144 | "from": "null", 145 | "text": "N/A", 146 | "to": "null" 147 | } 148 | ], 149 | "span": 4, 150 | "sparkline": { 151 | "fillColor": "rgba(31, 118, 189, 0.18)", 152 | "full": false, 153 | "lineColor": "rgb(31, 120, 193)", 154 | "show": false 155 | }, 156 | "targets": [ 157 | { 158 | "expr": "sum(sum by (container_name)( rate(container_cpu_usage_seconds_total{image!=\"\"}[1m] ) )) / count(node_cpu{mode=\"system\"}) * 100", 159 | "interval": "10s", 160 | "intervalFactor": 1, 161 | "refId": "A", 162 | "step": 10 163 | } 164 | ], 165 | "thresholds": "65, 90", 166 | "title": "CPU usage", 167 | "type": "singlestat", 168 | "valueFontSize": "80%", 169 | "valueMaps": [ 170 | { 171 | "op": "=", 172 | "text": "N/A", 173 | "value": "null" 174 | } 175 | ], 176 | "valueName": "current" 177 | }, 178 | { 179 | "cacheTimeout": null, 180 | "colorBackground": false, 181 | "colorValue": false, 182 | "colors": [ 183 | "rgba(50, 172, 45, 0.97)", 184 | "rgba(237, 129, 40, 0.89)", 185 | "rgba(245, 54, 54, 0.9)" 186 | ], 187 | "datasource": "Prometheus", 188 | "decimals": 2, 189 | "editable": true, 190 | "error": false, 191 | "format": "percent", 192 | "gauge": { 193 | "maxValue": 100, 194 | "minValue": 0, 195 | "show": true, 196 | "thresholdLabels": false, 197 | "thresholdMarkers": true 198 | }, 199 | "id": 7, 200 | "interval": null, 201 | "isNew": true, 202 | "links": [], 203 | "mappingType": 1, 204 | "mappingTypes": [ 205 | { 206 | "name": "value to text", 207 | "value": 1 208 | }, 209 | { 210 | "name": "range to text", 211 | "value": 2 212 | } 213 | ], 214 | "maxDataPoints": 100, 215 | "nullPointMode": "connected", 216 | "nullText": null, 217 | "postfix": "", 218 | "postfixFontSize": "50%", 219 | "prefix": "", 220 | "prefixFontSize": "50%", 221 | "rangeMaps": [ 222 | { 223 | "from": "null", 224 | "text": "N/A", 225 | "to": "null" 226 | } 227 | ], 228 | "span": 4, 229 | "sparkline": { 230 | "fillColor": "rgba(31, 118, 189, 0.18)", 231 | "full": false, 232 | "lineColor": "rgb(31, 120, 193)", 233 | "show": false 234 | }, 235 | "targets": [ 236 | { 237 | "expr": "sum (container_fs_limit_bytes - container_fs_usage_bytes) / sum(container_fs_limit_bytes)", 238 | "interval": "10s", 239 | "intervalFactor": 1, 240 | "metric": "", 241 | "refId": "A", 242 | "step": 10 243 | } 244 | ], 245 | "thresholds": "65, 90", 246 | "title": "Filesystem usage", 247 | "type": "singlestat", 248 | "valueFontSize": "80%", 249 | "valueMaps": [ 250 | { 251 | "op": "=", 252 | "text": "N/A", 253 | "value": "null" 254 | } 255 | ], 256 | "valueName": "current" 257 | } 258 | ], 259 | "title": "Row" 260 | }, 261 | { 262 | "collapse": false, 263 | "editable": true, 264 | "height": "250px", 265 | "panels": [ 266 | { 267 | "aliasColors": {}, 268 | "bars": false, 269 | "datasource": "Prometheus", 270 | "decimals": 3, 271 | "editable": true, 272 | "error": false, 273 | "fill": 0, 274 | "grid": { 275 | "threshold1": null, 276 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 277 | "threshold2": null, 278 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 279 | }, 280 | "id": 3, 281 | "isNew": true, 282 | "legend": { 283 | "alignAsTable": true, 284 | "avg": true, 285 | "current": true, 286 | "max": false, 287 | "min": false, 288 | "rightSide": true, 289 | "show": true, 290 | "sort": "current", 291 | "sortDesc": true, 292 | "total": false, 293 | "values": true 294 | }, 295 | "lines": true, 296 | "linewidth": 2, 297 | "links": [], 298 | "nullPointMode": "connected", 299 | "percentage": false, 300 | "pointradius": 5, 301 | "points": false, 302 | "renderer": "flot", 303 | "seriesOverrides": [], 304 | "span": 12, 305 | "stack": false, 306 | "steppedLine": false, 307 | "targets": [ 308 | { 309 | "expr": "sort_desc(sum(rate(container_cpu_user_seconds_total{image!=\"\"}[1m])) by (name))", 310 | "interval": "10s", 311 | "intervalFactor": 1, 312 | "legendFormat": "{{ name }}", 313 | "metric": "container_cpu_user_seconds_total", 314 | "refId": "A", 315 | "step": 10 316 | } 317 | ], 318 | "timeFrom": null, 319 | "timeShift": null, 320 | "title": "Container CPU usage", 321 | "tooltip": { 322 | "msResolution": true, 323 | "shared": true, 324 | "sort": 0, 325 | "value_type": "cumulative" 326 | }, 327 | "type": "graph", 328 | "xaxis": { 329 | "show": true 330 | }, 331 | "yaxes": [ 332 | { 333 | "format": "percentunit", 334 | "label": null, 335 | "logBase": 1, 336 | "max": null, 337 | "min": null, 338 | "show": true 339 | }, 340 | { 341 | "format": "short", 342 | "label": null, 343 | "logBase": 1, 344 | "max": null, 345 | "min": null, 346 | "show": true 347 | } 348 | ] 349 | } 350 | ], 351 | "title": "New row" 352 | }, 353 | { 354 | "collapse": false, 355 | "editable": true, 356 | "height": "250px", 357 | "panels": [ 358 | { 359 | "aliasColors": {}, 360 | "bars": false, 361 | "datasource": "Prometheus", 362 | "decimals": 2, 363 | "editable": true, 364 | "error": false, 365 | "fill": 0, 366 | "grid": { 367 | "threshold1": null, 368 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 369 | "threshold2": null, 370 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 371 | }, 372 | "id": 2, 373 | "isNew": true, 374 | "legend": { 375 | "alignAsTable": true, 376 | "avg": true, 377 | "current": true, 378 | "max": false, 379 | "min": false, 380 | "rightSide": true, 381 | "show": true, 382 | "sideWidth": 200, 383 | "sort": "current", 384 | "sortDesc": true, 385 | "total": false, 386 | "values": true 387 | }, 388 | "lines": true, 389 | "linewidth": 2, 390 | "links": [], 391 | "nullPointMode": "connected", 392 | "percentage": false, 393 | "pointradius": 5, 394 | "points": false, 395 | "renderer": "flot", 396 | "seriesOverrides": [], 397 | "span": 12, 398 | "stack": false, 399 | "steppedLine": false, 400 | "targets": [ 401 | { 402 | "expr": "sort_desc(sum(container_memory_usage_bytes{image!=\"\"}) by (name))", 403 | "interval": "10s", 404 | "intervalFactor": 1, 405 | "legendFormat": "{{ name }}", 406 | "metric": "container_memory_usage:sort_desc", 407 | "refId": "A", 408 | "step": 10 409 | } 410 | ], 411 | "timeFrom": null, 412 | "timeShift": null, 413 | "title": "Container Memory Usage", 414 | "tooltip": { 415 | "msResolution": false, 416 | "shared": true, 417 | "sort": 0, 418 | "value_type": "cumulative" 419 | }, 420 | "type": "graph", 421 | "xaxis": { 422 | "show": true 423 | }, 424 | "yaxes": [ 425 | { 426 | "format": "bytes", 427 | "label": null, 428 | "logBase": 1, 429 | "max": null, 430 | "min": null, 431 | "show": true 432 | }, 433 | { 434 | "format": "short", 435 | "label": null, 436 | "logBase": 1, 437 | "max": null, 438 | "min": null, 439 | "show": true 440 | } 441 | ] 442 | }, 443 | { 444 | "aliasColors": {}, 445 | "bars": false, 446 | "datasource": "Prometheus", 447 | "decimals": 2, 448 | "editable": true, 449 | "error": false, 450 | "fill": 0, 451 | "grid": { 452 | "threshold1": null, 453 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 454 | "threshold2": null, 455 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 456 | }, 457 | "id": 8, 458 | "isNew": true, 459 | "legend": { 460 | "alignAsTable": true, 461 | "avg": true, 462 | "current": true, 463 | "max": false, 464 | "min": false, 465 | "rightSide": true, 466 | "show": true, 467 | "sideWidth": 200, 468 | "sort": "current", 469 | "sortDesc": true, 470 | "total": false, 471 | "values": true 472 | }, 473 | "lines": true, 474 | "linewidth": 2, 475 | "links": [], 476 | "nullPointMode": "connected", 477 | "percentage": false, 478 | "pointradius": 5, 479 | "points": false, 480 | "renderer": "flot", 481 | "seriesOverrides": [], 482 | "span": 12, 483 | "stack": false, 484 | "steppedLine": false, 485 | "targets": [ 486 | { 487 | "expr": "sort_desc(sum by (name) (rate(container_network_receive_bytes_total{image!=\"\"}[1m] ) ))", 488 | "interval": "10s", 489 | "intervalFactor": 1, 490 | "legendFormat": "{{ name }}", 491 | "metric": "container_network_receive_bytes_total", 492 | "refId": "A", 493 | "step": 10 494 | } 495 | ], 496 | "timeFrom": null, 497 | "timeShift": null, 498 | "title": "Container Network Input", 499 | "tooltip": { 500 | "msResolution": false, 501 | "shared": true, 502 | "sort": 0, 503 | "value_type": "cumulative" 504 | }, 505 | "type": "graph", 506 | "xaxis": { 507 | "show": true 508 | }, 509 | "yaxes": [ 510 | { 511 | "format": "bytes", 512 | "label": null, 513 | "logBase": 1, 514 | "max": null, 515 | "min": null, 516 | "show": true 517 | }, 518 | { 519 | "format": "short", 520 | "label": null, 521 | "logBase": 1, 522 | "max": null, 523 | "min": null, 524 | "show": true 525 | } 526 | ] 527 | }, 528 | { 529 | "aliasColors": {}, 530 | "bars": false, 531 | "datasource": "Prometheus", 532 | "decimals": 2, 533 | "editable": true, 534 | "error": false, 535 | "fill": 0, 536 | "grid": { 537 | "threshold1": null, 538 | "threshold1Color": "rgba(216, 200, 27, 0.27)", 539 | "threshold2": null, 540 | "threshold2Color": "rgba(234, 112, 112, 0.22)" 541 | }, 542 | "id": 9, 543 | "isNew": true, 544 | "legend": { 545 | "alignAsTable": true, 546 | "avg": true, 547 | "current": true, 548 | "max": false, 549 | "min": false, 550 | "rightSide": true, 551 | "show": true, 552 | "sideWidth": 200, 553 | "sort": "current", 554 | "sortDesc": true, 555 | "total": false, 556 | "values": true 557 | }, 558 | "lines": true, 559 | "linewidth": 2, 560 | "links": [], 561 | "nullPointMode": "connected", 562 | "percentage": false, 563 | "pointradius": 5, 564 | "points": false, 565 | "renderer": "flot", 566 | "seriesOverrides": [], 567 | "span": 12, 568 | "stack": false, 569 | "steppedLine": false, 570 | "targets": [ 571 | { 572 | "expr": "sort_desc(sum by (name) (rate(container_network_transmit_bytes_total{image!=\"\"}[1m] ) ))", 573 | "intervalFactor": 2, 574 | "legendFormat": "{{ name }}", 575 | "metric": "container_network_transmit_bytes_total", 576 | "refId": "B", 577 | "step": 4 578 | } 579 | ], 580 | "timeFrom": null, 581 | "timeShift": null, 582 | "title": "Container Network Output", 583 | "tooltip": { 584 | "msResolution": false, 585 | "shared": true, 586 | "sort": 0, 587 | "value_type": "cumulative" 588 | }, 589 | "type": "graph", 590 | "xaxis": { 591 | "show": true 592 | }, 593 | "yaxes": [ 594 | { 595 | "format": "bytes", 596 | "label": null, 597 | "logBase": 1, 598 | "max": null, 599 | "min": null, 600 | "show": true 601 | }, 602 | { 603 | "format": "short", 604 | "label": null, 605 | "logBase": 1, 606 | "max": null, 607 | "min": null, 608 | "show": false 609 | } 610 | ] 611 | } 612 | ], 613 | "title": "New row" 614 | } 615 | ], 616 | "time": { 617 | "from": "now-1h", 618 | "to": "now" 619 | }, 620 | "timepicker": { 621 | "refresh_intervals": [ 622 | "5s", 623 | "10s", 624 | "30s", 625 | "1m", 626 | "5m", 627 | "15m", 628 | "30m", 629 | "1h", 630 | "2h", 631 | "1d" 632 | ], 633 | "time_options": [ 634 | "5m", 635 | "15m", 636 | "1h", 637 | "6h", 638 | "12h", 639 | "24h", 640 | "2d", 641 | "7d", 642 | "30d" 643 | ] 644 | }, 645 | "templating": { 646 | "list": [] 647 | }, 648 | "annotations": { 649 | "list": [] 650 | }, 651 | "refresh": "10s", 652 | "schemaVersion": 12, 653 | "version": 3, 654 | "links": [], 655 | "gnetId": 179 656 | }, 657 | "overwrite": false 658 | } 659 | -------------------------------------------------------------------------------- /examples/prometheus/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.0" 2 | 3 | networks: 4 | monitoring: 5 | driver: overlay 6 | 7 | services: 8 | cadvisor: 9 | image: google/cadvisor 10 | networks: 11 | - monitoring 12 | labels: 13 | - com.docker.stack.namespace=monitoring 14 | volumes: 15 | - /:/rootfs:ro 16 | - /var/run:/var/run:rw 17 | - /sys:/sys:ro 18 | - /var/lib/docker/:/var/lib/docker:ro 19 | deploy: 20 | mode: global 21 | labels: [com.docker.stack.namespace=monitoring] 22 | placement: 23 | constraints: [node.role == worker] 24 | 25 | node-exporter: 26 | image: basi/node-exporter:latest 27 | networks: 28 | - monitoring 29 | labels: 30 | - com.docker.stack.namespace=monitoring 31 | volumes: 32 | - /proc:/host/proc 33 | - /sys:/host/sys 34 | - /:/rootfs:ro 35 | - /etc/hostname:/etc/host_hostname 36 | environment: 37 | - "HOST_HOSTNAME=/etc/host_hostname" 38 | command: [ "-collector.procfs", "/host/proc", "-collector.sysfs", "/host/sys", "-collector.filesystem.ignored-mount-points", '^/(sys|proc|dev|host|etc)($$|/)', "--collector.textfile.directory", "/etc/node-exporter/", "--collectors.enabled", "conntrack,diskstats,entropy,filefd,filesystem,loadavg,mdadm,meminfo,netdev,netstat,stat,textfile,time,vmstat,ipvs" ] 39 | deploy: 40 | mode: global 41 | labels: [com.docker.stack.namespace=monitoring] 42 | placement: 43 | constraints: [node.role == manager] 44 | 45 | # docker-exporter: 46 | # image: basi/socat:v0.1.0 47 | # networks: 48 | # - monitoring 49 | # labels: 50 | # - com.docker.stack.namespace=monitoring 51 | # ports: 52 | # - "4999:4999" 53 | # environment: 54 | # - IN=172.18.0.1:4999 55 | # deploy: 56 | # mode: global 57 | # labels: [com.docker.stack.namespace=monitoring] 58 | # 59 | alertmanager: 60 | image: basi/alertmanager 61 | depends_on: 62 | - prometheus 63 | networks: 64 | - monitoring 65 | labels: 66 | - com.docker.stack.namespace=monitoring 67 | ports: 68 | - "9093:9093" 69 | environment: 70 | - SLACK_API=https://hooks.slack.com/services/${SLACK_TOKEN} 71 | command: ["-config.file=/etc/alertmanager/config.yml"] 72 | deploy: 73 | mode: replicated 74 | labels: [com.docker.stack.namespace=monitoring] 75 | placement: 76 | constraints: [node.role == manager] 77 | 78 | prometheus: 79 | build: 80 | context: . 81 | ports: 82 | - "9090:9090" 83 | image: 127.0.0.1:5000/bee42/prometheus:latest 84 | depends_on: 85 | - node-exporter 86 | - cadvisor 87 | # - docker-exporter 88 | networks: 89 | - monitoring 90 | labels: 91 | - com.docker.stack.namespace=monitoring 92 | command: [ "-config.file=/etc/prometheus/prometheus.yml", "-storage.local.path=/prometheus", "-web.console.libraries=/etc/prometheus/console_libraries", "-web.console.templates=/etc/prometheus/consoles", "-alertmanager.url=http://alertmanager:9093"] 93 | deploy: 94 | mode: replicated 95 | labels: [com.docker.stack.namespace=monitoring] 96 | placement: 97 | constraints: [node.role == manager] 98 | 99 | grafana: 100 | image: basi/grafana 101 | depends_on: 102 | - prometheus 103 | networks: 104 | - monitoring 105 | labels: 106 | - com.docker.stack.namespace=monitoring 107 | ports: 108 | - "3000:3000" 109 | environment: 110 | - "GF_SERVER_ROOT_URL=http://127.0.0.1.3000" 111 | - "GF_SECURITY_ADMIN_PASSWORD=${GF_PASSWORD}" 112 | - "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" 113 | - "PROMETHEUS_ENDPOINT=http://prometheus:9090" 114 | deploy: 115 | mode: replicated 116 | labels: [com.docker.stack.namespace=monitoring] 117 | placement: 118 | constraints: [node.role == manager] 119 | -------------------------------------------------------------------------------- /examples/prometheus/etc/alert.rules_nodes: -------------------------------------------------------------------------------- 1 | 2 | ALERT high_cpu_usage_on_node 3 | IF sum(rate(process_cpu_seconds_total[5m])) by (instance) * 100 > 70 4 | FOR 5m 5 | ANNOTATIONS { 6 | summary = "HIGH CPU USAGE WARNING ON '{{ $labels.instance }}'", 7 | description = "{{ $labels.instance }} ({{ $labels.host }}) is using a LOT of CPU. CPU usage is {{ humanize $value}}%.", 8 | } 9 | 10 | ALERT high_memory_usage_on_node 11 | IF ((node_memory_MemTotal-node_memory_MemAvailable)/node_memory_MemTotal)*100 > 80 12 | FOR 5m 13 | ANNOTATIONS { 14 | summary = "HIGH MEMORY USAGE WARNING TASK ON '{{ $labels.host }}'", 15 | description = "{{ $labels.instance }} ({{ $labels.host }}) is using a LOT of MEMORY. MEMORY usage is over {{ humanize $value}}%.", 16 | } 17 | 18 | ALERT high_la_usage_on_node 19 | IF node_load5 > 5 20 | FOR 5m 21 | ANNOTATIONS { 22 | summary = "HIGH LOAD AVERAGE WARNING ON '{{ $labels.instance }}'", 23 | description = "{{ $labels.instance }} ({{ $labels.host }}) has a high load average. CPU usage is {{ humanize $value}}%.", 24 | } 25 | 26 | ALERT monitoring_service_down 27 | IF up == 0 28 | FOR 5m 29 | ANNOTATIONS { 30 | summary = "MONITORING SERVICE DOWN WARNING: NODE '{{ $labels.host }}'", 31 | description = "The monitoring service '{{ $labels.job }}' is down.", 32 | } 33 | 34 | ALERT node_running_out_of_disk_space 35 | IF (node_filesystem_size{fstype="aufs", mountpoint="/"} - node_filesystem_free{fstype="aufs", mountpoint="/"}) * 100/ node_filesystem_size{fstype="aufs", mountpoint="/"} > 80 36 | FOR 5m 37 | ANNOTATIONS { 38 | summary = "LOW DISK SPACE WARING: NODE '{{ $labels.host }}'", 39 | description = "More than 80% of disk used. Disk usage {{ humanize $value }} GB.", 40 | } 41 | 42 | -------------------------------------------------------------------------------- /examples/prometheus/etc/alert.rules_service-groups: -------------------------------------------------------------------------------- 1 | ALERT monitoring_service_group_missing_members 2 | IF count(rate(container_last_seen{container_label_com_monitoring_group=~"monitoring"}[5m])) < 9 3 | FOR 5m 4 | ANNOTATIONS { 5 | summary = "SERVICE GROUP WARNING: SERVICE GROUP '{{ $labels.container_label_com_monitoring_group }}'", 6 | description = "{{ $labels.container_label_com_monitoring_group }} is missing containers. Container count is {{ $value }}/9.", 7 | } 8 | -------------------------------------------------------------------------------- /examples/prometheus/etc/alert.rules_tasks: -------------------------------------------------------------------------------- 1 | 2 | ALERT high_cpu_usage_on_container 3 | IF sum(rate(container_cpu_usage_seconds_total{container_label_com_docker_swarm_task_name=~".+"}[5m])) by (container_label_com_docker_swarm_task_name,instance) * 100 > 80 4 | FOR 5m 5 | ANNOTATIONS { 6 | summary = "HIGH CPU USAGE WARNING: TASK '{{ $labels.container_label_com_docker_swarm_task_name }}' on '{{ $labels.instance }}'", 7 | description = "{{ $labels.container_label_com_docker_swarm_task_name }} is using a LOT of CPU. CPU usage is {{ humanize $value}}%.", 8 | } 9 | 10 | ALERT container_eating_memory 11 | IF sum(container_memory_rss{container_label_com_docker_swarm_task_name=~".+"}) by (instance,name) > 2400000000 12 | FOR 5m 13 | ANNOTATIONS { 14 | summary = "HIGH MEMORY USAGE WARNING: TASK '{{ $labels.container_label_com_docker_swarm_task_name }}' on '{{ $labels.instance }}'", 15 | description = "{{ $labels.container_label_com_docker_swarm_task_name }} is eating up a LOT of memory. Memory consumption of {{ $labels.container_label_com_docker_swarm_task_name }} is at {{ humanize $value}}.", 16 | } 17 | -------------------------------------------------------------------------------- /examples/prometheus/etc/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 30s 3 | evaluation_interval: 30s 4 | 5 | labels: 6 | cluster: swarm 7 | replica: "1" 8 | 9 | # Attach these labels to any time series or alerts when communicating with 10 | # external systems (federation, remote storage, Alertmanager). 11 | external_labels: 12 | monitor: 'prometheus-swarm' 13 | 14 | rule_files: 15 | - "alert.rules_nodes" 16 | - "alert.rules_tasks" 17 | - "alert.rules_service-groups" 18 | 19 | scrape_configs: 20 | - job_name: 'prometheus' 21 | dns_sd_configs: 22 | - names: 23 | - 'tasks.prometheus' 24 | type: 'A' 25 | port: 9090 26 | 27 | - job_name: 'cadvisor' 28 | dns_sd_configs: 29 | - names: 30 | - 'tasks.cadvisor' 31 | type: 'A' 32 | port: 8080 33 | 34 | - job_name: 'node-exporter' 35 | dns_sd_configs: 36 | - names: 37 | - 'tasks.node-exporter' 38 | type: 'A' 39 | port: 9100 40 | 41 | # - job_name: 'docker-exporter' 42 | # dns_sd_configs: 43 | # - names: 44 | # - 'tasks.docker-exporter' 45 | # type: 'A' 46 | # port: 4999 47 | -------------------------------------------------------------------------------- /examples/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 1s 3 | scrape_configs: 4 | - job_name: 'prometheus' 5 | static_configs: 6 | - targets: ['localhost:9090'] 7 | - job_name: 'node' 8 | dns_sd_configs: 9 | - names: ['tasks.node'] 10 | type: 'A' 11 | port: 9100 12 | - job_name: 'cadvisor' 13 | dns_sd_configs: 14 | - names: ['tasks.cadvisor'] 15 | type: 'A' 16 | port: 8080 17 | - job_name: 'docker-exporter' 18 | dns_sd_configs: 19 | - names: 20 | - 'tasks.docker-exporter' 21 | type: 'A' 22 | port: 4999 23 | -------------------------------------------------------------------------------- /examples/prometheus/start-exporter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | network=prometheus 5 | if [ ! "$(docker network ls --filter name=$network -q)" ];then 6 | docker network create --driver=overlay --attachable $network 7 | fi 8 | 9 | # pull image if not available 10 | for image in "prom/node-exporter google/cadvisor:latest"; do 11 | if [ ! "$(docker images -q $image)" ];then 12 | docker pull $image 13 | docker tag $image 127.0.0.1:5000/$image 14 | docker push 127.0.0.1:5000/$image 15 | fi 16 | done 17 | 18 | if [ ! "$(docker service ls --filter name=node-exporter -q)" ];then 19 | 20 | docker service create --name node-exporter \ 21 | --mode global \ 22 | --network $network \ 23 | --mount type=bind,source=/proc,target=/host/proc \ 24 | --mount type=bind,source=/sys,target=/host/sys \ 25 | --mount type=bind,source=/,target=/rootfs \ 26 | 127.0.0.1:5000/prom/node-exporter \ 27 | -collector.procfs /host/proc \ 28 | -collector.sysfs /host/proc \ 29 | -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)" 30 | fi 31 | 32 | if [ ! "$(docker service ls --filter name=cadvisor -q)" ];then 33 | 34 | docker service create --name cadvisor \ 35 | --mode global \ 36 | --network $network \ 37 | --mount type=bind,source=/,target=/rootfs \ 38 | --mount type=bind,source=/var/run,target=/var/run \ 39 | --mount type=bind,source=/sys,target=/sys \ 40 | --mount type=bind,source=/var/lib/docker,target=/var/lib/docker \ 41 | 127.0.0.1:5000/google/cadvisor:latest 42 | fi 43 | -------------------------------------------------------------------------------- /examples/prometheus/start-prom-services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | : NETWORK=${NETWORK:=monitoring} 6 | if [ ! "$(docker network ls --filter name=${NETWORK} -q)" ];then 7 | echo "create overlay swarm network ${NETWORK}" 8 | docker network create --driver=overlay --attachable ${NETWORK} 9 | fi 10 | 11 | if [ ! "$(docker service ls --filter name=cadvisor -q)" ];then 12 | echo "start service cadvisor at network ${NETWORK}" 13 | docker \ 14 | service create --name cadvisor \ 15 | --mode global \ 16 | --network ${NETWORK} \ 17 | --constraint node.role==worker \ 18 | --label com.docker.stack.namespace=${NETWORK} \ 19 | --container-label com.docker.stack.namespace=${NETWORK} \ 20 | --mount type=bind,src=/,dst=/rootfs:ro \ 21 | --mount type=bind,src=/var/run,dst=/var/run:rw \ 22 | --mount type=bind,src=/sys,dst=/sys:ro \ 23 | --mount type=bind,src=/var/lib/docker/,dst=/var/lib/docker:ro \ 24 | google/cadvisor:v0.24.1 25 | fi 26 | 27 | if [ ! "$(docker service ls --filter name=node-exporter -q)" ];then 28 | echo "start service node-exporter at network ${NETWORK}" 29 | docker \ 30 | service create --name node-exporter \ 31 | --mode global \ 32 | --network ${NETWORK} \ 33 | --constraint node.role==worker \ 34 | --label com.docker.stack.namespace=${NETWORK} \ 35 | --container-label com.docker.stack.namespace=${NETWORK} \ 36 | --mount type=bind,source=/proc,target=/host/proc \ 37 | --mount type=bind,source=/sys,target=/host/sys \ 38 | --mount type=bind,source=/,target=/rootfs \ 39 | --mount type=bind,source=/etc/hostname,target=/etc/host_hostname \ 40 | -e HOST_HOSTNAME=/etc/host_hostname \ 41 | basi/node-exporter \ 42 | -collector.procfs /host/proc \ 43 | -collector.sysfs /host/sys \ 44 | -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)" \ 45 | --collector.textfile.directory /etc/node-exporter/ \ 46 | --collectors.enabled="conntrack,diskstats,entropy,filefd,filesystem,loadavg,mdadm,meminfo,netdev,netstat,stat,textfile,time,vmstat,ipvs" 47 | fi 48 | 49 | if [ ! "$(docker service ls --filter name=alertmanager -q)" ];then 50 | echo "start service alertmanager at network ${NETWORK}" 51 | docker \ 52 | service create --name alertmanager \ 53 | --network ${NETWORK} \ 54 | --label com.docker.stack.namespace=${NETWORK} \ 55 | --container-label com.docker.stack.namespace=${NETWORK} \ 56 | --publish 9093:9093 \ 57 | --constraint node.role==manager \ 58 | -e "SLACK_API=https://hooks.slack.com/services/${SLACK_TOKEN}" \ 59 | basi/alertmanager \ 60 | -config.file=/etc/alertmanager/config.yml 61 | fi 62 | 63 | if [ ! "$(docker service ls --filter name=prometheus -q)" ];then 64 | echo "start service prometheus at network ${NETWORK}" 65 | docker \ 66 | service create \ 67 | --name prometheus \ 68 | --network ${NETWORK} \ 69 | --label com.docker.stack.namespace=${NETWORK} \ 70 | --container-label com.docker.stack.namespace=${NETWORK} \ 71 | --constraint node.role==manager \ 72 | --publish 9090:9090 \ 73 | 127.0.0.1:5000/bee42/prometheus \ 74 | -config.file=/etc/prometheus/prometheus.yml \ 75 | -storage.local.path=/prometheus \ 76 | -web.console.libraries=/etc/prometheus/console_libraries \ 77 | -web.console.templates=/etc/prometheus/consoles \ 78 | -alertmanager.url=http://alertmanager:9093 79 | fi 80 | 81 | if [ ! "$(docker service ls --filter name=grafana -q)" ];then 82 | echo "start service grafana at network ${NETWORK}" 83 | docker \ 84 | service create \ 85 | --name grafana \ 86 | --network ${NETWORK} \ 87 | --label com.docker.stack.namespace=${NETWORK} \ 88 | --container-label com.docker.stack.namespace=${NETWORK} \ 89 | --constraint node.role==manager \ 90 | --publish 3000:3000 \ 91 | -e "GF_SERVER_ROOT_URL=http://grafana" \ 92 | -e "GF_SECURITY_ADMIN_PASSWORD=$GF_PASSWORD" \ 93 | -e "PROMETHEUS_ENDPOINT=http://prometheus:9090" \ 94 | -e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" \ 95 | basi/grafana 96 | fi 97 | -------------------------------------------------------------------------------- /examples/prometheus/start-prom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | : NETWORK=${NETWORK:=prometheus} 6 | if [ ! "$(docker network ls --filter name=$NETWORK -q)" ];then 7 | docker network create --driver=overlay --attachable $network 8 | fi 9 | 10 | if [ ! "$(docker service ls --filter name=prometheus -q)" ];then 11 | docker service create --network $NETWORK --name prometheus \ 12 | --constraint=node.role==manager \ 13 | --publish 9090:9090 \ 14 | 127.0.0.1:5000/bee42/prometheus 15 | fi 16 | -------------------------------------------------------------------------------- /examples/prometheus/start-whoami.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | network=traefik-net 3 | if [ ! "$(docker network ls --filter name=$network -q)" ];then 4 | docker network create --driver=overlay --attachable $network 5 | fi 6 | 7 | if [ ! "$(docker service ls --filter name=whoami -q)" ];then 8 | docker service create \ 9 | --name whoami \ 10 | --label traefik.port=80 \ 11 | --label traefik.enable=true \ 12 | --network $network \ 13 | emilevauge/whoami 14 | fi 15 | -------------------------------------------------------------------------------- /examples/prometheus/stop-prom-services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | : NETWORK=${NETWORK:=monitoring} 6 | 7 | if [ "$(docker service ls --filter name=grafana -q)" ];then 8 | echo "remove service grafana at network ${NETWORK}" 9 | docker service rm grafana 10 | fi 11 | 12 | if [ "$(docker service ls --filter name=alertmanager -q)" ];then 13 | echo "remove service alertmanager at network ${NETWORK}" 14 | docker service rm alertmanager 15 | fi 16 | 17 | if [ "$(docker service ls --filter name=prometheus -q)" ];then 18 | echo "remove service prometheus at network ${NETWORK}" 19 | docker service rm prometheus 20 | fi 21 | 22 | if [ "$(docker service ls --filter name=node-exporter -q)" ];then 23 | echo "remove service node-exporter at network ${NETWORK}" 24 | docker service rm node-exporter 25 | fi 26 | 27 | if [ "$(docker service ls --filter name=cadvisor -q)" ];then 28 | echo "remove service cadvisor at network ${NETWORK}" 29 | docker service rm cadvisor 30 | fi 31 | 32 | if [ "$(docker network ls --filter name=${NETWORK} -q)" ];then 33 | echo "remove overlay swarm network ${NETWORK}" 34 | docker network rm ${NETWORK} 35 | fi 36 | -------------------------------------------------------------------------------- /examples/proxy/README.md: -------------------------------------------------------------------------------- 1 | # start Traefik ingress at worker nodes 2 | 3 | * use a docker sock proxy at swarm manager 4 | * Set Labels from template Metadata at whoami service deployment 5 | 6 | -------------------------------------------------------------------------------- /examples/proxy/traefik-stack-v2.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | services: 4 | proxy: 5 | image: traefik:1.4.6-alpine 6 | networks: 7 | traefik: 8 | dockersock: 9 | ports: 10 | - "80:80" 11 | - "443:443" 12 | - "8080:8080" 13 | depends_on: 14 | - dockerproxy 15 | deploy: 16 | mode: global 17 | placement: 18 | constraints: 19 | - node.role == worker 20 | tty: true 21 | command: 22 | - --debug 23 | - --docker 24 | - --docker.endpoint=tcp://dockerproxy:2375 25 | - --docker.exposedbydefault=false 26 | - --docker.swarmmode 27 | - --docker.watch 28 | - --docker.trace 29 | - --accesslog.filepath=/access.log 30 | - --accesslog 31 | - --checknewversion=false 32 | - --web 33 | - --web.metrics.prometheus 34 | dockerproxy: 35 | image: tecnativa/docker-socket-proxy 36 | networks: 37 | dockersock: 38 | volumes: 39 | - /var/run/docker.sock:/var/run/docker.sock 40 | environment: 41 | CONTAINERS: 1 42 | NETWORKS: 1 43 | SERVICES: 1 44 | SWARM: 1 45 | TASKS: 1 46 | deploy: 47 | mode: global 48 | placement: 49 | constraints: 50 | - node.role == manager 51 | 52 | networks: 53 | traefik: 54 | attachable: true 55 | dockersock: 56 | attachable: true 57 | 58 | -------------------------------------------------------------------------------- /examples/proxy/traefik-stack.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | services: 4 | proxy: 5 | image: traefik:1.4.6-alpine 6 | networks: 7 | traefik: 8 | dockersock: 9 | ports: 10 | - "80:80" 11 | - "443:443" 12 | depends_on: 13 | - dockerproxy 14 | deploy: 15 | mode: global 16 | placement: 17 | constraints: 18 | - node.role == worker 19 | tty: true 20 | command: 21 | - --docker 22 | - --docker.EndPoint=http://dockerproxy:2375 23 | - --docker.ExposedByDefault=false 24 | - --docker.SwarmMode 25 | - --docker.Watch 26 | dockerproxy: 27 | image: tecnativa/docker-socket-proxy 28 | networks: 29 | dockersock: 30 | volumes: 31 | - /var/run/docker.sock:/var/run/docker.sock 32 | environment: 33 | CONTAINERS: 1 34 | NETWORKS: 1 35 | SERVICES: 1 36 | SWARM: 1 37 | TASKS: 1 38 | deploy: 39 | mode: global 40 | placement: 41 | constraints: 42 | - node.role == manager 43 | 44 | networks: 45 | traefik: 46 | dockersock: 47 | driver_opts: 48 | encrypted: 1 49 | 50 | -------------------------------------------------------------------------------- /examples/proxy/whoami-stack.yml: -------------------------------------------------------------------------------- 1 | version: '3.3' 2 | services: 3 | whoami: 4 | image: emilevauge/whoami 5 | hostname: 'whoami-{{.Task.Slot}}' 6 | environment: 7 | SLOT: '{{.Task.Slot}}' 8 | SERVICE: '{{.Service.Name}}' 9 | STACK: '{{index .Service.Labels "com.docker.stack.namespace"}}' 10 | networks: 11 | traefik: 12 | deploy: 13 | replicas: 3 14 | labels: 15 | - traefik.port=80 16 | - traefik.enable=true 17 | - traefik.backend=whoami 18 | - traefik.frontend.rule=Host:whoami.server.test 19 | - traefik.docker.network=traefik_traefik 20 | 21 | networks: 22 | traefik: 23 | external: 24 | name: traefik_traefik 25 | -------------------------------------------------------------------------------- /examples/simple/README.md: -------------------------------------------------------------------------------- 1 | # Træfɪk 2 | 3 | start this simple traefik docker loadbalancer example 4 | 5 | ``` 6 | $ docker-compose up -d 7 | $ curl -L -H Host:whoami.docker.localhost http://localhost 8 | $ docker-compose scale whoami=3 9 | $ curl -L -H Host:whoami.docker.localhost http://localhost 10 | $ curl -L -H Host:whoami.docker.localhost http://localhost 11 | $ docker-compose down 12 | ``` 13 | -------------------------------------------------------------------------------- /examples/simple/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | services: 3 | traefik: 4 | image: traefik 5 | command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG 6 | ports: 7 | - "80:80" 8 | - "8080:8080" 9 | volumes: 10 | - /var/run/docker.sock:/var/run/docker.sock 11 | - /dev/null:/traefik.toml 12 | labels: 13 | - "traefik.enable=false" 14 | whoami: 15 | image: emilevauge/whoami 16 | labels: 17 | - "traefik.backend=whoami" 18 | - "traefik.frontend.rule=Host:whoami.docker.localhost" 19 | -------------------------------------------------------------------------------- /images/usemethod_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/images/usemethod_flow.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build 3 | -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/Description.md: -------------------------------------------------------------------------------- 1 | **Træfɪk with Docker talk** 2 | 3 | Here you can find my docker slide container decks from my træfɪk docker orchestration talks: 4 | 5 | - [Docker Meetup Bochum 2016 - Traefik with docker][1]. 6 | - open slidefire presentation container with `docker run -d -p 8000:80 infrabricks/traefik-with-docker:docker-meetup-bochum-2016-12` 7 | - pdf [Traefik with Docker][2] is now avaiable! 8 | 9 | 10 | Open slidefire presentation container with your browser `http :8000/traefik-with-docker` 11 | 12 | Source and examples can be find at 13 | 14 | * https://github.com/bee42/traefik-with-docker 15 | 16 | Feedback welcome 17 | 18 | [Peter Rossbach][3] 19 | 20 | 21 | [1]: https://www.meetup.com/de-DE/Docker-Bochum/events/235649414/ 22 | [2]: https://speakerdeck.com/rossbachp/traefik-with-docker-docker-meetup-bochum-2016-12 23 | [3]: http://twitter.com/PRossbach 24 | -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2016 bee42 solutions gmbh 3 | && Peter Rossbach 4 | 5 | Redistribution and use in source and binary forms, with 6 | or without modification, are permitted provided that the 7 | following conditions are met: 8 | 9 | * You can only redistribution the source code, parts or a binary 10 | with a written permission from Peter Rossbach. 11 | 12 | * Redistributions of source code must retain the above 13 | copyright notice, this list of conditions and the 14 | following disclaimer. 15 | * Redistributions in binary form must reproduce the 16 | above copyright notice, this list of conditions and 17 | the following disclaimer in the documentation and/ 18 | or other materials provided with the distribution. 19 | * Neither the name of the www.infrabricks.de, www.bee42.com, 20 | or the name of Peter Rossbach 21 | nor the names of its contributors may be used to endorse 22 | or promote products derived from this software 23 | without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 26 | HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 27 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 28 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 31 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 32 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 35 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 36 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 37 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 38 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 39 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 40 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 41 | THE POSSIBILITY OF SUCH DAMAGE. 42 | 43 | Contact: 44 | bee42 solutions gmbh 45 | Peter Rossbach 46 | Am Josephsschacht 72 47 | 44879 Bochum 48 | Germany 49 | Tel +49-234-9413228 50 | peter.rossbach@bee42.com 51 | 52 | http://www.bee42.com 53 | -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DECK=traefik-with-docker 3 | TAG=docker-meetup-bochum_2016-12 4 | docker build -t="infrabricks/$DECK" . 5 | DATE=`date +'%Y%m%d%H%M'` 6 | ID=$(docker inspect -f "{{.Id}}" infrabricks/$DECK) 7 | docker tag $ID infrabricks/$DECK:$DATE 8 | docker tag $ID infrabricks/$DECK:$TAG 9 | #docker push infrabricks/$DECK 10 | -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/bee42-TOP2POTt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/bee42-TOP2POTt.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/bee42_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/bee42_logo.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/build4friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/build4friends.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/docker-book-german-adrian.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/docker-book-german-adrian.jpg -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/docker-camp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/docker-camp.jpg -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/docker-swarm-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/docker-swarm-logo.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/docker-swarm-visualizer-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/docker-swarm-visualizer-1.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/docker-swarm-visualizer-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/docker-swarm-visualizer-2.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/docker-swarming-dind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/docker-swarming-dind.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/letsencrypt-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/letsencrypt-flow.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/peter-rossbach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/peter-rossbach.jpg -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/setlog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/setlog.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/traefik-architecture-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/traefik-architecture-background.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/traefik-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/traefik-architecture.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/traefik-health.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/traefik-health.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/traefik-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/traefik-logo.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/traefik-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/traefik-ui.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/images/traefik.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/images/traefik.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/picture/traefik.graffle/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bee42/traefik-with-docker/c1691beeb2935e96ac49e65049593617ffbc1d42/slidefire/traefik-with-docker/picture/traefik.graffle/image1.png -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/print.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TAG=docker-meetup-bochum_2016-12 3 | CID=$1 4 | LOCATION="Docker Meetup Bochum 12/2016" 5 | TITLE="Traefik wiht Docker" 6 | docker exec -ti ${CID} /bin/bash -c "cd print ; ./print.sh /build/traefik_with_docker-${TAG}-PeterRossbach.pdf '${LOCATION}'" 7 | docker exec -ti ${CID} /bin/bash -c "cd print ; ./exif.sh /build/traefik_with_docker-${TAG}-PeterRossbach.pdf '${TITLE}'" 8 | -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker run -d -ti -p 4212:8000 -v `pwd`/build:/build -v `pwd`/images:/opt/presentation/images -v `pwd`:/opt/presentation/lib/md rossbachp/presentation 3 | -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/save.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker save infrabricks/traefik-with-docker:latest >infrabricks-traefik-with-docker.tar 3 | -------------------------------------------------------------------------------- /slidefire/traefik-with-docker/slidefire.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DATE=`date +'%Y%m%d%H%M'` 3 | ACCOUNT=infrabricks 4 | DECK=traefik-with-docker 5 | EDITION_TAG=docker-meetup-bochum_2016-12 6 | if [ ! "x" == "x`docker ps -a | grep $DECK`" ]; then 7 | docker rm $DECK 8 | fi 9 | 10 | mkdir -p build 11 | PWD=`pwd` 12 | mkdir -p build/md 13 | cp slides.md build/md 14 | docker run -ti --rm -v $PWD/images:/opt/presentation/images -v $PWD/build/md:/opt/presentation/lib/md -v $PWD/build:/build -p 8000:8000 rossbachp/presentation /bin/bash -c "grunt package && mv reveal-js-presentation.zip /build/$DECK.zip" 15 | cd build 16 | mkdir -p $DECK 17 | cd $DECK 18 | #you must have zip installed - apt-get install -y zip 19 | unzip ../$DECK.zip 20 | cd .. 21 | tar czf slidefire.tar.gz $DECK 22 | rm -rf build/$DECK.zip 23 | rm -rf build/$DECK 24 | rm -rf build/md 25 | 26 | COPYDATE=`date +'%Y'` 27 | cp ../LICENSE LICENSE 28 | cat <Dockerfile 29 | FROM rossbachp/slidefire 30 | MAINTAINER Peter Rossbach 31 | ADD LICENSE /etc/LICENSE 32 | RUN echo "slidefire" >/etc/provisioned && date >>/etc/provisioned && echo >>/etc/provisioned && echo " Copyright ${COPYDATE} by bee42 solutions gmbh" >>/etc/provisioned 33 | EOT 34 | cat >.dockerignore < @PRossbach 18 | * Nicals Mietz - bee42 solutions gmbh 19 | * @solidnerd 20 | 21 | --- 22 | ## Reverse Proxy: Træfɪk 23 | 24 | ![](images/traefik-architecture-background.png) 25 | 26 | *** 27 | * https://traefik.io 28 | * @traefikproxy 29 | * @emilevauge 30 | 31 | - 32 | ### Important Træfɪk facts 33 | 34 | * Project founder is Emile Vauge (23.8.2015) 35 | * Status at 29.11.2016 36 | * 5419 Stars 37 | * 309 issues closed 38 | * 78 Contributors 39 | * 6 Maintainer 40 | 41 | *** 42 | * https://github.com/containous/traefik 43 | 44 | - 45 | ### Træfɪk Features I 46 | 47 | * It's fast 48 | * No dependency hell, single binary made with go 49 | * Rest API 50 | * Multiple backends supported: 51 | * Docker, Swarm, Kubernetes, Marathon, Mesos, 52 | * Consul, Etcd, and more to come 53 | * Watchers for backends, can listen for changes in backends to apply a new configuration automatically 54 | * Hot-reloading of configuration. No need to restart the process 55 | * Graceful shutdown http connections 56 | * Circuit breakers on backends 57 | * Round Robin, rebalancer load-balancers 58 | 59 | - 60 | ### Træfɪk Features II 61 | 62 | * Rest Metrics 63 | * Tiny official docker image included 64 | * SSL backends support 65 | * SSL frontend support (with SNI) 66 | * Clean AngularJS Web UI 67 | * Websocket support 68 | * HTTP/2 support 69 | * Retry request if network error 70 | * Let's Encrypt support (Automatic HTTPS with renewal) 71 | * High Availability with cluster mode 72 | 73 | --- 74 | ## Use an easy loadbalancer like Træfɪk 75 | 76 | ![](images/traefik.png) 77 | 78 | *** 79 | * https://traefik.io/ 80 | 81 | - 82 | ### Have fun with Træfɪk community 83 | 84 | ![](images/traefik-logo.png) 85 | 86 | - 87 | ### ByExample: 88 | #### Simple Træfɪk on your docker localhost 89 | 90 | ``` 91 | $ cat >docker-compose.yml < 0.5` 290 | * create a circuit breaker to be used against the backend 291 | * `traefik.port=80` 292 | * register this port. Useful when the container exposes multiples ports. 293 | * `traefik.protocol=https` 294 | * override the default http protocol 295 | 296 | - 297 | ### Træfɪk labels II 298 | 299 | * `traefik.weight=10` 300 | * assign this weight to the container 301 | * `traefik.enable=false` 302 | * disable this container in Træfɪk 303 | * `traefik.frontend.rule=Host:test.traefik.io` 304 | * override the default frontend rule (Default: `Host:{containerName}.{domain}`). 305 | * `traefik.frontend.passHostHeader=true` 306 | * forward client Host header to the backend. 307 | * `traefik.frontend.priority=10` 308 | * override default frontend priority 309 | * `traefik.frontend.entryPoints=http,https` 310 | * assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`. 311 | * `traefik.docker.network` 312 | * Set the docker network to use for connections to this container 313 | 314 | - 315 | ### Træfɪk Dashboard 316 | 317 | ![](images/traefik-ui.png) 318 | 319 | - 320 | ### Træfɪk Health 321 | 322 | ![](images/traefik-health.png) 323 | 324 | - 325 | #### Træfɪk health api 326 | 327 | ``` 328 | $ curl -L http://localhost:8080/health 329 | { 330 | "pid": 1, 331 | "uptime": "32m13.34712143s", 332 | "uptime_sec": 1933.34712143, 333 | "time": "2016-12-01 05:35:52.819831303 +0000 UTC", 334 | "unixtime": 1480570552, 335 | "status_code_count": {}, 336 | "total_status_code_count": { 337 | "200": 12, 338 | "504": 5 339 | }, 340 | "count": 0, 341 | "total_count": 17, 342 | "total_response_time": "2m30.038738015s", 343 | "total_response_time_sec": 150.038738015, 344 | "average_response_time": "8.825808118s", 345 | "average_response_time_sec": 8.825808118 346 | } 347 | ``` 348 | 349 | - 350 | ### Build your own service 351 | 352 | * start registry at your swarm 353 | * localhost trick! 354 | * push your build to registry 355 | * start service from your local registry 356 | 357 | --- 358 | ## Letsencrypt support 359 | 360 | * Public TLS certs 361 | * Automatic certs rotation 362 | * Træfɪk use [Lego](https://github.com/xenolf/lego): The best Let's Encrypt library in go 363 | 364 | *** 365 | * https://letsencrypt.org/ 366 | * https://github.com/xenolf/lego 367 | * https://docs.traefik.io/user-guide/examples/#lets-encrypt-support 368 | 369 | - 370 | ### Letsencrypt flow 371 | 372 | ![](images/letsencrypt-flow.png) 373 | 374 | *** 375 | * https://docs.traefik.io/toml/#acme-lets-encrypt-configuration 376 | 377 | - 378 | ### Better TSL support 379 | 380 | * Check your certs A+ 381 | * https://www.ssllabs.com/ssltest/ 382 | * Talk from WJAX 2016 383 | * https://github.com/tboeghk/terrific-tls-tuning-tips 384 | 385 | --- 386 | ### Sneak Peak: Træfɪk >1.2... 387 | 388 | * Redirect http to https on a per container (per frontend) basis 389 | * Support Opentracing 390 | * Traefik Stats System + Prometheus Exporter 391 | * Docker - 2 independant rules on same container 392 | * X-Forwarded-Proto and Websockets 393 | * Add arbitrary headers to requests 394 | 395 | *** 396 | * https://github.com/containous/traefik/projects/2 397 | 398 | --- 399 | ## Summary 400 | 401 | * Træfɪk is a reverse proxy with easy setup and config 402 | * Is supports static and dynamic Loadbalacing 403 | * HTTP/1.1, HTTP/2 and websocket support 404 | * Auto config with multiple service discoveries 405 | * Kubernetes 406 | * Docker + Docker swarming 407 | * Consul 408 | * ETCD 409 | * ... 410 | * Designed in mind for dynamic infrastructure and microservices 411 | * Cool simple dashboard 412 | * Metrics support 413 | * Easy and free TLS support is now possible! 414 | 415 | --- 416 | ## Build your systems for friends 417 | 418 | ![](images/build4friends.png) 419 | 420 | --- 421 | ## Many Thanks for following! 422 | 423 | * Start this presentation with 424 | * `docker run -d -ti -p 4212:80 infrabricks/traefik-with-docker` 425 | * `open http://:4212/traefik-with-docker` 426 | 427 | *** 428 | Peter Rossbach 429 | 430 | follow the blog [www.infrabricks.de](http://www.infrabricks.de) 431 | 432 | @PRossbach 433 | 434 | More Training: http://www.bee42.com/training/ 435 | 436 | - 437 | ### Docker Camp 438 | 439 | ![](images/docker-camp.jpg) 440 | 441 | * 1.12 Docker Meetup Bochum - Træfɪk 442 | * 5.12 DevOpsCon Docker Basic Workshop (Munich) 443 | * 8.12 DevOpsCOn Docker Expert OpenSpace Workshop (Munich) 444 | * 12-14.12 Docker Camp at Berlin 445 | * 21.12 Docker Meetup Dortmund 446 | 447 | *** 448 | * http://devops-training.de/ 449 | 450 | - 451 | ### bee42 solutions gmbh - Devops Bochum 452 | ### rethink IT at the POTT 453 | 454 | ![bee42](images/bee42-TOP2POTt.png) 455 | 456 | We offer TOP-IT jobs... 457 | 458 | *** 459 | * http://bee42.github.io 460 | * http://www.bee42.com 461 | 462 | - 463 | #### DevOps Engineer 464 | 465 | * Living an Agile culture 466 | * Influence us to DevOps-Journey 467 | * Enable people to use modern technologies 468 | * Build applications that living at the clouds 469 | * Design services with clever API's 470 | * Think infrastructure first 471 | 472 | *** 473 | * send your offering to peter.rossbach@bee42.com 474 | 475 | - 476 | #### Website Engineer 477 | 478 | * Create beautiful human responsive services 479 | * Find new ways to create creative web service 480 | * Find good solutions with HTML/CSS/Javascript to create simple services 481 | * Think mobile first 482 | 483 | *** 484 | * send your offering to peter.rossbach@bee42.com 485 | 486 | - 487 | ### Setlog GmbH - Supply Chain Management 488 | 489 | ![Setlog](images/setlog.png) 490 | 491 | We offer jobs... 492 | 493 | * Administrator 494 | * Experiences with 495 | * Maintain a cluster of linux machines 496 | * Setup Docker infrastructure 497 | * Config management with ansible 498 | * Release java applications 499 | * Linux and mysql skills 500 | * Developer 501 | * Experiences with 502 | * Create java based *micro*services 503 | * Spring Boot and Netflix Stack 504 | * Docker knowledge 505 | 506 | *** 507 | * send your offering to p.rossbach@setlog.com 508 | 509 | - 510 | ### German Docker Book 511 | 512 | ![](images/docker-book-german-adrian.jpg) 513 | 514 | *** 515 | * http://www.dpunkt.de/docker 516 | 517 | - 518 | ### Give the navigator the rudder! 519 | ![Peter Rossbach](images/peter-rossbach.jpg) 520 | 521 | --- 522 | ## Appendix 523 | 524 | This slides shows shell commands executed in different places. The line prefix shows where to run them: 525 | 526 | ``` 527 | $ ... – local machine 528 | > ... – remote machine 529 | # ... – docker container 530 | ``` 531 | 532 | --- 533 | ## Links 534 | 535 | * https:/traefik.io 536 | * http://programmableinfrastructure.com/guides/load-balancing/traefik/ 537 | * http://www.abhishekamralkar.com/2015-11-20-traefik-reverse-proxy-microservice 538 | * http://www.infrabricks.de 539 | * http://www.bee42.com 540 | * https://www.docker.com 541 | * https://github.com/docker/docker 542 | * https://github.com/docker/machine 543 | * https://github.com/docker/swarmkit 544 | --------------------------------------------------------------------------------