Introducing Lexa

DNS & HTTP Service Discovery for LXD Containers

Lexa is a instance and service discovery tool for LXD containers that exposes DNS, DoT and a JSON REST endpoint to make discovery of containers and services within containers on LXD instances easier.

Lexa can be used as a stand-alone service to identify what LXD containers are running on a given host, or can be used in conjunction with tools such as HaProxy, Traefik, or even your own DNS server to automate load balancing between hosts, blue/green or red/black deployments, CNAME to hosts, and other scenariors. Lexa also provides a local agent (wip) that notifies the main server of any defines services running in the container. Think of it like a local, slimmed down Consul agent.

TL;DR: Lexa facilitates container instance and service discovery for LXD containers over DNS, DoT, DoH, and HTTPS. Checkout the documentation on Github (https://github.com/kaidyth/lexa) for more information!


LXD is a pretty awesome container system - however connecting to and discovering containers themselves and services that they provide is difficult especially when trying to use tools such as Traefik or HAProxy, and while tools like Consul can help with service discovery you’re still left with needing to do discovery on the actual containers themselves, especially if you’re using an internally bridged interface like lxdbr0.

To solve both the problem of “discovering” the correct IPs for LXD containers I have built Lexa, a single Golang binary that you can run both on your LXD hosts, and within your LXD containers via systemd.

A few examples to showcase what you can do with Lexa:

JSON REST API for all containers on a given host

Discovery all of your containers running on a given host. Change the .lexa suffix to .lexa.host to easily identify LXD instances running on a specific host, find all IP address (including Docker IPs for Docker in LXD) running on a given container, and list all the services, ports, protocols, and tags exposed by a specific container

curl -qqsk https://127.0.0.1:18443/containers/ | jq .
{
  "hosts": [
    {
      "name": "nginx-php-74.lexa",
      "interfaces": {
        "ipv4": [
          {
            "eth0": "10.123.201.141"
          }
        ],
        "ipv6": [
          {
            "eth0": "fd42:aa04:d9d5:3541:216:3eff:fe06:6996"
          }
        ]
      },
      "services": [
        {
          "name": "http",
          "port": 80,
          "proto": "tcp",
          "tags": [
            "foo",
            "bar"
          ]
        },
        {
          "name": "https",
          "port": 443,
          "proto": "tcp",
          "tags": [
            "foo2",
            "bar2"
          ]
        }
      ]
    },
    {
      "name": "nginx-php-80.lexa",
      "interfaces": {
        "ipv4": [
          {
            "eth0": "10.123.201.178"
          }
        ],
        "ipv6": [
          {
            "eth0": "fd42:aa04:d9d5:3541:216:3eff:fe39:b94d"
          }
        ]
      },
      "services": null
    }
  ]
}

DNS, DoT, and DoH Discovery

Pair with tools such as Traefik or HAPRoxy to do load balancing, black/red // green/blue deployments of your containers for 0 downtime, rolling LXD deployments on a single host.

dig hostname.lexa @127.0.0.1 -p 18053

Or load balance against a specific interface name

dig eth0.interface.hostname.lexa @127.0.0.1 -p 18053

Alternatively, do service based DNS discovery with HAProxy using HAProxy’s DNS server-template feature:

server-template web 5 app.https.service.lexa check resolvers lexa init-addr none  ssl verify none
server-template web 5 _https._tcp.service.lexa check resolvers lexa init-addr none  ssl verify none

Integrate with your DNS Server

Or integrate Lexa with your DNS resolver to advertise DNS names across your entire network!

Example for CoreDNS

lexa {
    bind 127.0.0.53
    reload
    errors
    forward . 127.0.0.1:18053 {
            health_check 5s
    }

    # Or use the DoT resolver
    # forward . tls://127.0.0.1 {
    #     tls_servername <servername>
    #     health_check 5s
    # }
}

I’d love to hear what more you can do with LXD containers combined with Lexa! Lexa is currently alpha (but stable) software and works both in home deployments, and in production environments. I’d love to see what you can build with Lexa, and if you have comments, feedback (or bugs) please connect with me within the Github Issues for Lexa!

  • 611 Words
  • 3 minutes