3

Let's says that we have some backends hosted in Docker containers, with their DNS entries handled by Docker Compose.

With the following docker-compose.yml, it would make the host foo resolve to whatever IP Docker registers the service to when started.

services:
  foo:
    # ...

Obvisouly, until the container is started, the IP address bound to the alias is not known.

This makes Varnish impossible to start, using such a VCL:

backend foo {
    .host = "foo ";
}
VCL compilation failed
Error:
Message from VCC-compiler:
Backend host '"foo"' could not be resolved to an IP address:
        Temporary failure in name resolution
(Sorry if that error message is gibberish.)
('/etc/varnish/default.vcl' Line 6 Pos 13)
    .host = "foo";
------------#####-

In a world where we have multiple backends for one single Varnish instance, it renders the instance incapable of starting as soon as one container is not up.

I was wondering if there is a way to configure Varnish so that it does not try to resolve the IP at boot-time, and resolve it only when a fetch request to the backend is actually done.

1 Answer 1

4

Currently, the open source version of Varnish only supports static DNS, where the DNS resolution happens at compile time. Any resolution failure will prevent VCL compilation, as you're experience now. Another caveat as that DNS records that return multiple IP addresses aren't supported either.

vmod_activedns & vmod_udo

The most reliable way to tackle the issue is by leveraging Varnish Enterprise's vmod_activedns for dynamic DNS resolution & vmod_udo to create backends dynamically by subscribing to the DNS group.

The resolution happens at runtime. This allows for dynamic backends, but also for your use case of a hostname that is not yet resolvable.

Here's the VCL code:

vcl 4.1;

import activedns;
import udo;

backend default none;

sub vcl_init {
    new group = activedns.dns_group("example.com");
    group.set_ttl_rule(force);
    group.set_ttl(30s);
    new director = udo.director(random);
    director.subscribe(group.get_tag());
}

sub vcl_recv {
    set req.backend_hint = director.backend();
}

It's worth noting that Varnish Enterprise and the corresponding VMODs I featured, are part of a commercial subscription model and currently not available free of charge.

vmod_dynamic using the official Docker image

There's also vmod_dynamic, which is an open source module, but that is not packaged with Varnish Cache.

However, there is an expection: we package this module as part of the official Varnish Docker image.

Here's the code:

vcl 4.1;

import dynamic;

backend default none;

sub vcl_init {
    new d = dynamic.director(ttl = 60s);
}

sub vcl_backend_fetch {
    set bereq.backend = d.backend("example.com");
}

And again, the hostname is resolved dynamically and caters to your use case. If the hostname cannot be resolved, Varnish will start, the VCL will compile, but the backend selection process will fail at runtime, causing a 503 error.

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.