Wednesday, August 1, 2018

Traefik Docker Swarm Demo

In a previous post I demonstrated a proper installation of traefik with docker. Now I want to expand that demo with docker swarm. Docker Swarm has a similar ingress function to kubernetes and so that makes deployment and high availability easier. Kubernetes is a standard, however, docker swarm is very simple to operate. You are still on your own for the nitty gritty.

Bring the traefik container down:

# docker-compose down

I'm taking the previous example and expanding it to deploy a docker swarm and so the first thing to do is deploy single node swarm. In my case I deployed the VMs on digital ocean and did not deploy a private network and there is no point in setting up a non-encrypted virtual network in public space.)

$ export manager=myhost
$ docker-machine ssh ${manager} "docker swarm init \
    --listen-addr $(docker-machine ip ${manager}) \
    --advertise-addr $(docker-machine ip ${manager})"

WARNING WARNING -- while this example is simple and demonstrates a docker-machine version of the docker swarm command the listen-addr and advertise-addr parameters are seriously dangerous because in this use-case they are public and not private IP addresses.

I previously indicated that this installation was going to be on top of the plain version and that was essentially wrong. Plain docker and docker swarm may be compatible but there are differences. For example in the plain version I created a network:

# docker network create --driver=overlay web

When I tried to create a docker stack (swarm instance) I got an error that the network was a local and not a swam. So I had to delete the network and recreate it as the scope was different. Since the current running apps were running I had to stop them too.

# docker-compose down
# docker network rm web
# docker network create --driver=overlay web --attachable

UPDATE: I thought redeploying the network was a thing until I realized when the network is created after already in swarm mode then it's ok without the scope option.

UPDATE: However while debugging I determined that I needed the attachable parameter.

In the traefik.toml file I commented this line and added these two in the docker section:

[docker]
endpoint = "tcp://127.0.0.1:2376"       
swarmMode = true                         
#endpoint = "unix:///var/run/docker.sock"

Although I commented out the 'sock' volume I'm not sure whether or not it's in use so I probably will not remove that from the docker-compose.yml file. A few other changes were required so here is the file:

version: '3'

services:
  traefik:
    image: traefik
    command: --api --docker --docker.swarmMode
    ports:
      - 80:80
      - 443:443
      #- 8080:8080
    networks:
      - web
    environment:
      - DO_AUTH_TOKEN=MY TOKEN
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/traefik/traefik.toml:/traefik.toml
      - /opt/traefik/acme.json:/acme.json
    deploy:
      labels:
        - "traefik.docker.network=web"
        - "traefik.port=8080"
        - "traefik.basic.frontend.rule=Host:traefik.ooc.systems"

networks:
  web:
    external: true

Then start traefik as a stack:

docker stack deploy -c /opt/traefik/docker-compose.yml traefik

Here is the docker compose of one of my basic services ("hello"):

version: "3.4"

services:
  app:
    image: myregistry/transient/hello-web:latest
    networks:
      - web
      - default
    deploy:
      labels:
        - "traefik.docker.network=web"
        - "traefik.enable=true"
        - "traefik.basic.frontend.rule=Host:hello.ooc.systems"
        - "traefik.basic.port=80"
        - "traefik.basic.protocol=http"

networks:
  web:
    external: true

I had to make some changes...

  • change the version
  • remove the expose
  • remove the container name
  • remove restart always
My hello container is in my private registry so I needed to login first then start the stack:

docker stack deploy \
     --with-registry-auth \
     -c /root/hello/docker-compose.yml hello


CONCLUSION

So there was a lot of learning going on here and here are the key takeaways. There are few differences between the raw docker and docker swarm. The configs are pretty simple. A reasonably deployed swarm give you some options for scaling some services even though not demonstrated here. Adding a stack does not require taking down the system. And you get the benefir of let's encrypt without interruptions except for rate limits. And the goodness continues.

No comments:

Post a Comment

another bad day for open source

One of the hallmarks of a good open source project is just how complicated it is to install, configure and maintain. Happily gitlab and the ...