Docker ist etwas ganz feines, um schnell einen ganzen Schwarm von Containern für eine Applikation zu bauen. Die Kommunikation zwischen den Containern geht direkt über das Docker Interface (sofern konfiguriert) und man braucht damit keine EXPOSED ports, um die Container untereinander reden zu lassen.
Dafür setzt docker-compose den DNS Resolver in der /etc/resolver.conf von jedem Container. Damit kann man einen anderen Container über dessen Docker Service Namen ansprechen. Das funzt sehr gut wird aber dann zum Problem wenn die Anwendung selber keinen Hostnamen als Konfigurationsoption akzeptiert (z.B. ein DNS resolver). In dem Fall muss man die IP Adresse des Containers kennen oder eben EXPOSED ports nutzen, was aber eine hässliche Lösung wäre.
Es gibt einen überraschend einfachen Weg, um an die IP Adresse zu kommen 🙂 Solang der Zielcontainer gestartet ist gibt es einen DNS Eintrag. Den fragt man ab und verbaut ihn in die Konfiguration der Applikation beim Start des Containers.
Dazu braucht es im Container lediglich dig oder nslookup. Letzteres ist in alpine basierten Containern bereits per default installiert. Über dem ENTRYPOINT im Dockerfile kann man ein Script triggern, das dies macht und die Konfig anpasst und dann die Applikation startet
So kann dann das Dockerfile ausschauen.
1 2 3 4 5 6 7 | FROM tcely/dnsdist COPY ./dnsdist.conf /etc/dnsdist/dnsdist.conf COPY ./dnsdist_config.sh /dnsdist_config.sh ENTRYPOINT ["/dnsdist_config.sh"] CMD ["--disable-syslog", "--verbose"] |
dnsdist.conf ist das Konfigfile wo die IP Adressen rein müssen. Ich habe hier dnsdist verwendet, das Prinzip funzt aber bei jeder anderen Applikation gleich.
1 2 3 | newServer({address="HOST1:53", checkType="NS", checkName="example.com", mustResolve=true, pool="myrbl"}) newServer({address="HOST2:53", checkType="NS", checkName="google.ch", mustResolve=true, pool="recursor"}) newServer({address="HOST3:53", checkType="NS", checkName="mydomain.tld", mustResolve=true, pool="auth"}) |
Dabei stehen HOST1, HOST2 und HOST3 als Platzhalter, welche vom dnsdist_config.sh Script mit den passenden Werten ersetzt werden. DOCKER1, DOCKER2 und DOCKER3 sind die entsprechenden Docker Service Namen (normalerweise in docker-compose.yml)
1 2 3 4 5 6 | #!/bin/sh sed -ir 's/HOST1:53/'`nslookup DOCKER1 2>/dev/null|grep ^Address|awk '{print $3}'`':53/g' /etc/dnsdist/dnsdist.conf sed -ir 's/HOST2:53/'`nslookup DOCKER2 2>/dev/null|grep ^Address|awk '{print $3}'`':53/g' /etc/dnsdist/dnsdist.conf sed -ir 's/HOST3:53/'`nslookup DOCKER3 2>/dev/null|grep ^Address|awk '{print $3}'`':53/g' /etc/dnsdist/dnsdist.conf /usr/local/bin/dnsdist --uid dnsdist --gid dnsdist |
Das Script wird im Dockerfile (siehe oben) über den ENTRYPOINT eingebunden und passt die Konfig bei jedem Container Start an 🙂
Wichtig ist es sicherzustellen, dass DOCKER1-3 natürlich gestartet sind bevor sie aufgelöst werden sollen. Dies kann man z.B. mit depends_on sicherstellen
Leave a Reply