Docker Swarm
Docker Swarm is an orchestrator and so is Kubernetes.
Kubernetes is breathing down my neck too and today I am thinking, "What the hell, go for it! Why NOT run a single node with Kubernetes?" I spent an hour looking at it and it just adds more complexity.
Some day I will spin up some IoT and Edge nodes for buzzword compliance but for now it's just one node. Bellman
Note, it made me pick an ethernet address.
bellman> docker swarm init --advertise-addr 192.168.123.2 Swarm initialized: current node (isk0jocx0rb37yonoafstyvoj) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-5b81dywl9xkis6769fxnsvjahfy361w2kxkz69nc35bz3nxt6s-43jxeopl6inw8xur1vpcl23w7 192.168.123.2:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
I can add a node on another machine using that token. I won't be doing this today. It would look like this.
tern> docker swarm join --token SWMTKN-1-5b81dywl9xkis6769fxnsvjahfy361w2kxkz69nc35bz3nxt6s-43jxeopl6inw8xur1vpcl23w7 192.168.123.2:2377 This node joined a swarm as a worker.
bellman> docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION isk0jocx0rb37yonoafstyvoj * bellman Ready Active Leader 19.03.5 vjbx2h8n8280ecib2btzkwcxw tern Ready Active 18.09.1
bellman> docker network create -d overlay --attachable testing shaboxhgakqer14j1ve7zyysj
The "attachable" option is for containers not yet running in swarm. I will need that soon, when I run bash in Debian for tests.
Now ordinarily I'd use Docker Compose to start a reverse proxy (my favorite today is Varnish).
Before worrying about Varnish though I will spin up simple web server on just the one existing node. If I add tern it will spread them over the two nodes. I want it to use that "testing" network.
docker service create --name web --replicas 4 -p 80:80 --network testing --detach nginx:latest
Now I have 4 copies of nginx running. I can see that they were published on port 80 but that's inside the funny swarm network, how to see them? They are on localhost, I can do this "curl http://localhost". I can get the id (or just use the name "web") and then kill them off,
docker service ls docker service rm pmbrvm6wow7q curl http://localhost
When I do the "curl" with the nginx replicas shut down, I see the page served by Varnish (still running in Compose), it's the Home Assistant instance. So I guess the swarm takes precedence over whatever is running in Compose.
I skipped the "--network testing" parameter and everything still worked. I think maybe that's just so I can attach more services later?? Like this. This looks the way I expected.
docker run -it --rm --network testing debian:bullseye bash # apt update # apt install -y bind9-dnsutils # nslookup web Server: 127.0.0.11 Address: 127.0.0.11#53 Non-authoritative answer: Name: web Address: 10.0.1.27 # apt install -y curl # curl http://10.0.1.27 # curl http://web/
The standard nginx page is returned from curl both times, so I know it's hitting a replica and running under the name "web", which is what I assigned. Inside the container I can see my local LAN too, for example from the Debian instance I can "curl http://bellman.wildsong.biz:8123/" and get the Home Assistant page. So far, easy easy.
That healthcheck thing
It's not too soon to think about it. ;-)
With nginx I can create my own Docker image and build the healthcheck right into the image.
Yes I know "curl" is not the answer. https://blog.sixeyed.com/docker-healthchecks-why-not-to-use-curl-or-iwr/ but for now it's what I am using! In my Dockerfile,
FROM nginx:latest HEALTHCHECK CMD curl --fail http://localhost || exit 1
$ docker build -t wildsong/nginx . $ docker service rm web $ docker service create --name web --replicas 1 -p 80:80 --network testing --detach wildsong/nginx $ docker ps | grep web 01a3f36f7580 wildsong/nginx:latest "/docker-entrypoint.…" About a minute ago Up About a minute (healthy) 80/tcp web.1.ssssfmwmwp8je7g1dnsabevew
When I create the service, I will get a warning because I have not pushed that image (wildsong/nginx) to a registry, but it still works because I am running only one node for now. When I do the "docker ps" I can see that the container is marked as "healthy".
LUNCH BREAK NOW.
How do volumes work in a swarm?
docker service create --name proxy \ -p 80:80 -p 443:443 \ -e DHPARAM_GENERATION="false" \ -v /var/run/docker.sock:/tmp/docker.sock:ro \ -v ./network_internal.conf:/etc/nginx/network_internal.conf \ -v ./vhost.d:/etc/nginx/vhost.d \ -v proxy_html:/usr/share/nginx/html \ -v proxy_dhparam:/etc/nginx/dhparam \ -v proxy_certs:/etc/nginx/certs:ro \ jwilder/nginx-proxy:alpine
Bring in Compose
By that I mean I want to deploy a stack of containers using a docker-compose.yml file as the configuration. So far I have not needed it, if I start just one container per project then "docker service" commands are fine.