Hands-On Time
Setting Up
a Swarm Cluster
and
Running Services
Docker Swarm
Nodes Setup
for i in 1 2 3 4 5; do
docker-machine create -d virtualbox swarm-$i
done
docker-machine ls
Provisioning
eval $(docker-machine env swarm-1)
docker swarm init --advertise-addr $(docker-machine ip swarm-1)
TOKEN=$(docker swarm join-token -q manager)
for i in 2 3; do
eval $(docker-machine env swarm-$i)
docker swarm join --token $TOKEN \
--advertise-addr $(docker-machine ip swarm-$i) \
$(docker-machine ip swarm-1):2377
done
Provisioning
TOKEN=$(docker swarm join-token -q worker)
for i in 4 5; do
eval $(docker-machine env swarm-$i)
docker swarm join --token $TOKEN \
--advertise-addr $(docker-machine ip swarm-$i) \
$(docker-machine ip swarm-1):2377
done
Networking
docker network create --driver overlay proxy
docker network create --driver overlay go-demo
docker network ls
Service
docker service create --name go-demo-db \
--network go-demo --reserve-memory 100m mongo
docker service create --name go-demo -e DB=go-demo-db \
--network go-demo --network proxy --reserve-memory 50m \
--label com.df.notify=true --label com.df.distribute=true \
--label com.df.servicePath=/demo --label com.df.port=8080 \
vfarcic/go-demo
Reverse Proxy
docker service create --name swarm-listener \
--mount "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" \
-e DF_NOTIF_CREATE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/reconfigure \
-e DF_NOTIF_REMOVE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/remove \
--constraint 'node.role==manager' --network proxy \
vfarcic/docker-flow-swarm-listener
docker service create -e MODE=swarm -e LISTENER_ADDRESS=swarm-listener \
-p 80:80 -p 443:443 --network proxy --replicas 3 \
--name proxy vfarcic/docker-flow-proxy
docker service ls
curl -i $(docker-machine ip swarm-1)/demo/hello
Hands-On Time
Ship logs
from any container
running anywhere inside the cluster
Elastic Search Service
eval $(docker-machine env swarm-1)
docker network create --driver overlay elk
docker service create --name elasticsearch --network elk \
-p 9200:9200 --reserve-memory 500m elasticsearch:2.4
docker service ps elasticsearch
Log Stash Service
mkdir -p docker/logstash
cp conf/logstash.conf docker/logstash/logstash.conf
cat docker/logstash/logstash.conf
docker service create --name logstash \
--mount "type=bind,source=$PWD/docker/logstash,target=/conf" \
--network elk -e LOGSPOUT=ignore --reserve-memory 100m \
logstash:2.4 logstash -f /conf/logstash.conf
docker service ps logstash
Testing Log Stash
LOGSTASH_NODE=$(docker service ps logstash | tail +2 | awk '{print $4}')
eval $(docker-machine env $LOGSTASH_NODE)
LOGSTASH_ID=$(docker ps -q --filter "ancestor=logstash:2.4")
docker logs $LOGSTASH_ID
Testing Log Stash
eval $(docker-machine env swarm-1)
docker service create --name logger-test --network elk \
--restart-condition none \
debian logger -n logstash -P 51415 hello world
eval $(docker-machine env $LOGSTASH_NODE)
docker logs $LOGSTASH_ID
eval $(docker-machine env swarm-1)
docker service rm logger-test
Log Spout Service
docker service create --name logspout \
--network elk --mode global -e SYSLOG_FORMAT=rfc3164 \
--mount "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" \
gliderlabs/logspout syslog://logstash:51415
docker service ps logspout
Testing Log Spout
docker service create --name registry \
-p 5000:5000 --reserve-memory 100m \
--mount "type=bind,source=$PWD,target=/var/lib/registry" \
registry
docker service ps registry
eval $(docker-machine env $LOGSTASH_NODE)
docker logs $LOGSTASH_ID
Kibana Service
docker service create --name kibana \
--network elk --network proxy --reserve-memory 50m \
-e ELASTICSEARCH_URL=http://elasticsearch:9200 \
--label com.df.notify=true --label com.df.distribute=true \
--label com.df.servicePath=/app/kibana,/bundles,/elasticsearch \
--label com.df.port=5601 \
kibana:4.6
docker service ps kibana
open http://$(docker-machine ip swarm-1)/app/kibana
Hands-On Time
Expose metrics from
hardware,
containers,
and the proxy
Node Exporter
eval $(docker-machine env swarm-1)
docker service create --name node-exporter \
--mode global --network proxy \
--mount "type=bind,source=/proc,target=/host/proc" \
--mount "type=bind,source=/sys,target=/host/sys" \
--mount "type=bind,source=/,target=/rootfs" \
prom/node-exporter:0.12.0 -collector.procfs /host/proc -collector.sysfs /host/proc -collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"
docker service ps node-exporter
UTIL_ID=$(docker ps -q --filter label=com.docker.swarm.service.name=util)
docker exec -it $UTIL_ID apk add --update curl
docker exec -it $UTIL_ID curl http://node-exporter:9100/metrics
Container Exporter
docker service create --name cadvisor \
--network proxy --mode global \
--mount "type=bind,source=/,target=/rootfs" \
--mount "type=bind,source=/var/run,target=/var/run" \
--mount "type=bind,source=/sys,target=/sys" \
--mount "type=bind,source=/var/lib/docker,target=/var/lib/docker" \
google/cadvisor:v0.24.1
docker service ps cadvisor
docker exec -it $UTIL_ID curl http://cadvisor:8080/metrics
Proxy Exporter
docker service create --name proxy-exporter \
--network proxy \
prom/haproxy-exporter:v0.7.1 \
-haproxy.scrape-uri="http://admin:admin@proxy/admin?stats;csv"
docker service ps proxy-exporter
docker exec -it $UTIL_ID curl http://proxy-exporter:9101/metrics