DNS-Diensterkennung mit Consul in Docker Swarm

2

Ich versuche, die Dienstermittlung mithilfe von Consul-DNS zum Funktionieren zu bringen. Ich habe einen Docker-Schwarm mit einem Konsul-Cluster eingerichtet, der als das von swarm benötigte Schlüssel / Wert-Paar-Backend sowie als Service Discovery-Backend für die anderen Container fungiert.

Ich beginne mit 3 nackten Servern, auf denen die Docker-Engine installiert ist. Ich stelle den Cluster mit Ansible bereit.

Der Prozess zum Einrichten dieses Clusters ist bisher:

  • Stellen Sie bei der Installation von docker ein --cluster-store=consul://127.0.0.1:8500 im Docker Daemon wählt
  • Starten Sie auf dem "primären" Cluster-Knoten einen Consul-Server-Container im Modus "-bootstrap-expect 3"
  • Starten Sie auf den "sekundären" Cluster-Knoten einen Consul-Server-Container im "-join" -Modus
  • Starten Sie auf jedem Clusterknoten einen Swarm-Master und einen Swarm-Agent-Container, die auf den lokalen Consul-Server auf demselben Host verweisen

Beim Starten der Consul-Server ordne ich dem Host alle Consul-Ports wie folgt zu:

version: '2'

services:
    consul:
        image: progrium/consul
        hostname: "{{ ansible_hostname }}"
        ports:
            # Explanation of ports needed: http://stackoverflow.com/a/30692226/1514089
            - "8300:8300" # This is used by servers to handle incoming requests from other agents
            - "8301:8301/tcp" # This is used to handle gossip in the LAN. Required by all agents
            - "8301:8301/udp" # This is used to handle gossip in the LAN. Required by all agents
            - "8302:8302/tcp" # This is used by servers to gossip over the WAN to other servers
            - "8302:8302/udp" # This is used by servers to gossip over the WAN to other servers
            - "8400:8400" # This is used by all agents to handle RPC from the CLI
            - "8500:8500" # This is used by clients to talk to the HTTP API
            - "8600:8600" # Used to resolve DNS queries
         restart: always
         command: "{{ consul_command }}"

Das bringt mir einen funktionierenden Docker-Schwarm. Ich kann mich bei jedem der Clusterknoten anmelden und Docker Compose verwenden, um eine Anwendung aufzurufen. Der Schwarm verteilt die Dinge transparent auf die Server.

Jetzt möchte ich die DNS-Funktionen von Consuls verwenden, um Dienste aus jedem Container im Schwarm heraus aufzulösen. Ich möchte dazu in der Lage sein:

$ docker run -it ubuntu dig consul.service.consul

Ich habe ein paar Dinge ausprobiert, aber ich habe es nicht zum Laufen gebracht. Ich vermute, es hat etwas mit den Dockernetzwerken zu tun. Lassen Sie mich erklären...

Wenn ich die consul-Server starte, werden sie an ihr eigenes Docker-Compose-Netzwerk angeschlossen, da ich sie mit Docker-Compose starte. Da der Schwarm jedoch noch nicht betriebsbereit ist, sind offensichtlich noch keine Multi-Host-Overlay-Netzwerke eingerichtet. Somit befindet sich jeder Consul-Container in einem eigenen Bridge-Netzwerk, das nur für Hosts vorgesehen ist. Ich erstelle nur meine Docker-Netzwerke nach dem Der Schwarm wurde gebootet. Ich konnte die Konsul-Container nicht zu einem Overlay-Netzwerk hinzufügen, nachdem der Schwarm hochgefahren ist

Error response from daemon: No such container: swarm-node-1/swarmconsul_consul_1

Wie kann ich die DNS-basierte Diensterkennung in meinen Containern zum Laufen bringen?

Emmet O'Grady
quelle

Antworten:

0

Am Ende habe ich es geschafft, es zum Laufen zu bringen. Ich habe ein paar Dinge falsch gemacht.

Der größte Fehler war, dass ich Port 53 auf dem Host nicht auf Port 53 / udp im Consul-Container abgebildet hatte. Das vollständige Port-Mapping sieht nun folgendermaßen aus:

services:
    consul:
        image: progrium/consul
        hostname: "{{ ansible_hostname }}"
        ports:
          # Explanation of ports needed: http://stackoverflow.com/a/30692226/1514089
          - "8300:8300" # This is used by servers to handle incoming requests from other agents
          - "8301:8301/tcp" # This is used to handle gossip in the LAN. Required by all agents
          - "8301:8301/udp" # This is used to handle gossip in the LAN. Required by all agents
          - "8302:8302/tcp" # This is used by servers to gossip over the WAN to other servers
          - "8302:8302/udp" # This is used by servers to gossip over the WAN to other servers
          - "8400:8400" # This is used by all agents to handle RPC from the CLI
          - "8500:8500" # This is used by clients to talk to the HTTP API
          - "8600:8600" # Used to resolve DNS queries
          - "172.17.0.1:53:53/udp"
        restart: always
        command: "{{ consul_command }}"

Hier binden wir an Port 53 der docker0-Schnittstelle. Ich habe jedoch erfahren, dass sich die IP-Adresse der docker0-Brücke ändern kann. Daher habe ich sie ein wenig hartcodiert und Docker angewiesen, diese IP-Adresse immer für die docker0-Brücke zu verwenden, indem ich sie spezifizierte --bip=172.17.0.1 in den Docker-Daemon-Optionen. Der nächste Schritt bestand darin, die Standard-DNS des Docker-Daemons auf dieselbe IP einzustellen. Mein vollständiger Docker Daemon sieht folgendermaßen aus:

[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon \
    -H tcp://0.0.0.0:2375 \
    -H unix:///var/run/docker.sock \
    --bip=172.17.0.1/16 \
    --dns=172.17.0.1 \
    --dns-search=service.consul \
    --storage-driver=overlay \
    --cluster-store=consul://127.0.0.1:8500

Jetzt kann ich das machen:

$ sudo docker -H :4000 run -it joffotron/docker-net-tools
/ # dig +short consul.service.consul
10.0.0.93
10.0.0.95
10.0.0.94

Großartig!

Emmet O'Grady
quelle