Skip to content

Add possibility to resolve domains in the backend definition #347

Description

@PierreZ

Hi!

I was playing a bit with sozu yesterday. I had a configuration file like this:

#...
[applications]
[applications.ingress]
hostname   = "sozu"
path_begin = "/api/v0/update"
backends  = [ "ingress:8080" ]

[applications.egress]
hostname   = "sozu"
path_begin = "/api/v0/exec"
backends  = [ "egress:8080" ]

Here's the log:

sozu | 2018-02-15T15:05:08Z 51870899701997 1 MASTER INFO     starting up
sozu | 2018-02-15T15:05:08Z 51870922854097 1 MASTER INFO     0 launching worker
sozu | 2018-02-15T15:05:08Z 51870923186297 1 MASTER INFO     0 worker launched: 6
sozu | 7 send empty
sozu | 2018-02-15T15:05:08Z 51870923594997 1 MASTER INFO     sent listeners from master: Ok(())
sozu | 2018-02-15T15:05:08Z 51870926268397 1 MASTER INFO     1 launching worker
sozu | 2018-02-15T15:05:08Z 51870926630997 1 MASTER INFO     1 worker launched: 7
sozu | 9 send empty
sozu | 2018-02-15T15:05:08Z 51870927136197 1 MASTER INFO     sent listeners from master: Ok(())
sozu | 2018-02-15T15:05:08Z 51870927216397 1 MASTER INFO     created workers: [Worker { id: 0, run_state: Running }, Worker { id: 1, run_state: Running }]
sozu | 2018-02-15T15:05:08Z 51870927462697 1 MASTER ERROR    could not get saved state path: No such file or directory (os error 2)
sozu | 2018-02-15T15:05:08Z 51870939343597 7 WRK-01 INFO     worker 1 starting...
sozu | 2018-02-15T15:05:08Z 51870945467597 6 WRK-00 INFO     worker 0 starting...
sozu | 2018-02-15T15:05:08Z 51871060998497 7 WRK-01 INFO     will try to receive listeners
sozu | 10 received :(35, 0)
sozu | 2018-02-15T15:05:08Z 51871061689697 7 WRK-01 INFO     received listeners: Some(
sozu |     Listeners {
sozu |         http: None,
sozu |         tls: None,
sozu |         tcp: []
sozu |     }
sozu | )
sozu | 2018-02-15T15:05:08Z 51871062593397 7 WRK-01 ERROR    Couldn't parse address of HTTP proxy: invalid IP address syntax
sozu | 2018-02-15T15:05:08Z 51871064190197 1 MASTER ERROR    could not parse address: egress:8080
sozu | 2018-02-15T15:05:08Z 51871071132097 7 WRK-01 INFO     1 starting event loop
sozu | 2018-02-15T15:05:08Z 51871088278097 1 MASTER INFO     waiting for configuration client connections

As I was playing with sozu with docker-compose using links, I don't have to use IPs. From what I see in the log could not parse address: egress:8080 doesn't seems to be parsed into an IPv4 address.

Am i right? If so, is it possible to add the possibility to resolve domain using /etc/hosts file?

As I am always looking for new challenges, if it's an easy PR, I would love to give it a try!

Activity

  1. Geal commented on Feb 15, 2018

    @Geal
    Member

    Hello,

    The feature is a bit tricky, because we must think about where and how often the name check happens. The various solutions:

    • the master checks the domain regularly and updates the configuration of the workers. A bit complex to implement but very few DNS requests (not all usages of this feature would rely on /etc/hosts) and a small state to keep around
    • the worker checks the domain before connecting to the backend. Easy to do, but potentially lots of DNS requests. We can have a cache, but then each worker would end up with their own cache (or rely on the OS's DNS cache?)

    In the configuration messages, do we make an enum domain/IP to identify a backend?

    The lookup_host feature in libstd is only available on nightly. Or do we embed a DNS client in sozu? TrustDNS is nicely designed.

  2. added this to the needed for the release milestone on Mar 16, 2018
  3. modified the milestones: needed for the release, on Jun 5, 2019
  4. modified the milestones: , 0.14 on Jul 29, 2021
  5. Geal commented on Jul 29, 2021

    @Geal
    Member

    we should do this now

  6. modified the milestones: v0.14.0, v1.0.0 on Feb 18, 2022
  7. Keksoj commented on Jun 7, 2023

    @Keksoj

    Hello everyone. Is this still a thing? Do people want this? ping @PierreZ

  8. taladar commented on Oct 30, 2024

    @taladar

    How do you even run sozu in a Docker Compose or Kubernetes environment without this?

  9. NeilujD commented on Oct 31, 2024

    @NeilujD

    How do you even run sozu in a Docker Compose or Kubernetes environment without this?

    in docker compose you can define a network with static ip addresses.

    services:
      proxy:
        build:
          dockerfile: ./dockerfile.proxy
          context: .
        command: ["sozu", "start", "-c", "config.toml"]
        volumes:
          - ./sozu.toml:/etc/sozu/config.toml
        ports:
          - 8080:8080
          - 80:80
          - 443:443
        networks:
          sozu_net:
            ipv4_address: 172.20.0.99
    
       myapp:
        ...
        networks:
          sozu_net:
            ipv4_address: 172.20.0.1
    
    volumes:
      data:
    
    networks:
      sozu_net:
        driver: bridge
        ipam:
          driver: default
          config:
           - subnet: 172.20.0.0/16
             gateway: 172.20.0.1
  10. lzpel commented on Oct 4, 2025

    @lzpel

    How do you even run sozu in a Docker Compose or Kubernetes environment without this?

    this is my quick workaround (works fine in Docker Compose)
    I just let make render the config at startup and resolve service names into IPs

    docker-compose.yml

    services:
      api:
        build: api
        ports:
          - 8000:8000
    
      frontend:
        build: frontend
        ports:
          - 3000:3000
    
      proxy:
        build: proxy
        environment:
          - HOST_API=api
          - HOST_FRONTEND=frontend
        command: ["make", "run"]  # ← run the Make target
        ports:
          - 8080:8080

    Makefile

    # Grab the first IPv4 for a hostname
    DOMAIN2IP = $(shell getent ahostsv4 $(1) | sed 's/\s.*//;q')
    
    # If env is empty, fall back to localhost
    IP_API      := $(call DOMAIN2IP,$${HOST_API:-localhost})
    IP_FRONTEND := $(call DOMAIN2IP,$${HOST_FRONTEND:-localhost})
    
    run: ## generate sozu config and boot it
    	printf '%s\n' "$${SOZU_CONFIG}" > out.toml
    	sozu start -j -c ./out.toml
    
    print_sozu_config:
    	printf '%s\n' "$${SOZU_CONFIG}"
    
    define SOZU_CONFIG
    [[listeners]]
    protocol = "http"
    address  = "0.0.0.0:8080"
    
    [clusters]
    
    [clusters.Frontend]
    protocol  = "http"
    frontends = [{ address = "0.0.0.0:8080", hostname="*", path="/front" }]
    backends  = [{ address = "$(IP_FRONTEND):3000" }]
    
    [clusters.Api]
    protocol  = "http"
    frontends = [{ address = "0.0.0.0:8080", hostname="*", path="/api" }]
    backends  = [{ address = "$(IP_API):8000" }]
    endef
    export SOZU_CONFIG

    Why this? Because in Compose the service names (api, frontend) resolve nicely inside the network; I just turn them into IPs once at startup and bake them into the config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions