DEV Community

Nico Braun
Nico Braun

Posted on

Label-Based Docker Swarm HAProxy Ingress Controller

Hi, I have created an ingress controller for docker swarm, stack deployments.

It is using HAProxy and the go docker SDK to create dynamic configuration based on labels, similar to Kubernetes ingress controller.

GitHub logo bluebrown / swarm-haproxy-ingress

Label based HAProxy ingress-controller for docker swarm

Docker Swarm Haproxy Ingress Controller

The aim of the project is it to create dynamic ingress rules for swarm services through labels. This allows to create new services and change the haproxy configuration without any downtime or container rebuild.

The manager service is responsible for generating a valid haproxy configuration file from the labels. The loadbalancer instances scrape the configuration periodically and reload the worker "hitless" if the content has changed.

Synopsis

version: "3.9"
services:
    # the lb service fetches the dynamic configuration,
    # from the manager endpoint, periodically
    loadbalancer:
        image: bluebrown/swarm-haproxy-loadbalancer
        # default values for env vars are below
        environment: 
            MANAGER_ENDPOINT: http://manager:8080/
            SCRAPE_INTERVAL: '60'
            STARTUP_DELAY: '5'
        ports:
            - 3000:80 # ingress port
            - 4450:4450 # stats page

    # the manager service defines global defaults and frontend configs
    manager:
        image: bluebrown/swarm-haproxy-manager
        # default
Enter fullscreen mode Exit fullscreen mode

The images are also on docker hub.

If you want to try a one shot command, after making sure it's no malicious code, you can deploy the below config via swarm.
It will pull the images from docker hub and run the stack without further configuration.
Once deployed, get the webpage with curl -i localhost.

version: "3.9"
services:
    loadbalancer:
        image: bluebrown/swarm-haproxy-loadbalancer
        ports: [80:80]
    manager:
        image: bluebrown/swarm-haproxy-manager
        volumes: 
            -  /var/run/docker.sock:/var/run/docker.sock
        labels:
            ingress.global: |
                spread-checks 15
            ingress.defaults: |
                timeout connect 5s
                timeout check 5s
                timeout client 2m
                timeout server 2m
            ingress.frontend.default: |
                bind *:80
        deploy:
            placement:
                constraints: ["node.role==manager"]
    app:
        image: nginx
        deploy:
            replicas: 2
            labels:
                ingress.port: "80"
                ingress.frontend.default: |
                    default_backend {{ .Name }}
                ingress.backend: |
                    balance roundrobin
                    option httpchk GET /

Enter fullscreen mode Exit fullscreen mode

The labels correspond to the equally named sections in the HAProxy configuration files.

Currently, the system isn't rigid in that multiline snippets are provided. This requires a deeper knowledge of HAProxy, on one side, but provides greater flexility, on the other side.
A similar technique is used in the official HAProxy Kubernetes ingress controller.

I would be glad to get some feedback or other kind of inspiration.

Have a nice day.

Discussion (0)