In the previous post, we setup a Swarm cluster. That’s fine and dandy but that cluster, as far as we’re concerned, is useless. Let’s change that.
I’ve talked and played with Traefik previously on this blog and here we go
again, with another orchestration technology. As always, we need an ingress to
our cluster. Traefik makes a great ingress that’s easily configurable with
Let’s not forget, we’re working with Swarm this time around. Swarm stacks
look very similar to
But, before we do that, there is a small piece of information that we need to be aware of. For Traefik to be able to route traffic to our services, both Traefik and the service need to be on the same network. Let’s make this a bit more predictable and manage that network ourselves.
manager nodes will allow interaction with the Swarm
worker nodes will not give you any useful information about the
We started with Ansible and we shall continue with Ansible. We begin with creating the network.
--- - name: Create a Traefik Ingress network community.docker.docker_network: name: traefik-ingress driver: overlay scope: swarm
Once the network is in place, we can go ahead and deploy Traefik.
This setup is not meant to be deploy in a production setting. SSL certificates require extra configuration steps that might come in a future post.
--- - name: Deploy Traefik Stack community.docker.docker_stack: state: present name: Traefik compose: - version: '3' services: traefik: image: traefik:latest restart: unless-stopped command: - --entrypoints.web.address=:80 - --providers.docker=true - --providers.docker.swarmMode=true - --accesslog - --log.level=INFO - --api - --api.insecure=true ports: - "80:80" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" networks: - traefik-ingress deploy: replicas: 1 resources: limits: cpus: '1' memory: 80M reservations: cpus: '0.5' memory: 40M placement: constraints: - node.role == manager labels: - traefik.protocol=http - traefik.docker.network=traefik-ingress - traefik.http.routers.traefik-api.rule=Host(`traefik.our-domain.com`) - [email protected] - traefik.http.services.taefik-api.loadbalancer.server.port=8080 networks: traefik-ingress: external: true
Even though these are Ansible tasks, Swarm stack manifests are not much different as I’m using mostly the raw format.
Let’s talk a bit about what we did.
- We configure Traefik to enable both docker and swarm mode providers.
- We enable the API which offers the UI and we allow it to run insecure.
The rest, I believe, have been explained in the previous blog post.
If everything went well, and we configured our DNS properly, we should be
welcomed by a Traefik dashboard on
Now I know most people install the Pi-hole straight on the Pi. Well, I’m not most people and I’d like to deploy it in a container. I feel it’s easier all around than installing it on the system, you’ll see.
--- - name: Deploy PiHole Stack community.docker.docker_stack: state: present name: PiHole compose: - version: '3' services: pihole: image: pihole/pihole:latest restart: unless-stopped ports: - "53:53" - "53:53/udp" cap_add: - NET_ADMIN environment: TZ: "Europe/Vienna" VIRTUAL_HOST: pihole.our-domain.com VIRTUAL_PORT: 80 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:80/"] interval: 30s timeout: 20s retries: 3 volumes: - /opt/pihole/data/pihole-config:/etc/pihole - /opt/pihole/data/pihole-dnsmasq.d:/etc/dnsmasq.d networks: - traefik-ingress deploy: replicas: 1 placement: constraints: - node.role == worker labels: - traefik.docker.network=traefik-ingress - traefik.http.routers.pihole-http.entrypoints=web - traefik.http.routers.pihole-http.rule=Host(`pihole.our-domain.com`) - traefik.http.routers.pihole-http.service=pihole-http - traefik.http.services.pihole-http.loadbalancer.server.port=80 - traefik.http.routers.pihole-http.middlewares=pihole-main - traefik.http.middlewares.pihole-main.chain.middlewares=frame-deny,browser-xss-filter - traefik.http.middlewares.frame-deny.headers.framedeny=true - traefik.http.middlewares.browser-xss-filter.headers.browserxssfilter=true networks: traefik-ingress: external: true
We make sure to expose port
53 for DNS on all nodes, and configure the
labels to our service so that Traefik can pick it up.
Once deployed and your DNS is pointing properly then
is waiting for you. This also shows us that the networking between nodes works
properly. Let’s test it out.
$ nslookup duckduckgo.com pihole.our-domain.com Server: pihole.our-domain.com Address: 192.168.1.100#53 Non-authoritative answer: Name: duckduckgo.com Address: 184.108.40.206
Alright, seems that our Pi-hole works.
On these small Raspberry Pis, the cluster seems to be working very well. The Pi-hole has been running without any issues for a few days running my internal DNS. There’s a few improvements that can be done to this setup, mainly the deployment of an SSL cert. That may come in the future, time permitting. Stay safe, until the next one !