2016-12-15 2 views
7

Curl ich wirklich nicht verstehen, was hier vorgeht. Ich möchte einfach eine http-Anfrage von innerhalb eines Andock-Containers zu einem anderen Andock-Container über den Host unter Verwendung der öffentlichen IP-Adresse des Hosts, auf einem veröffentlichten Port.Warum kann ich nicht einen Docker Container von einem anderen über den Host

Hier ist mein Setup. Ich habe meine Dev-Maschine. Und ich habe einen Docker Host-Rechner mit zwei Containern. CONT_A zuhört und veröffentlicht einen Web-Service auf Port 3000.

DEV-MACHINE 

HOST (Public IP = 111.222.333.444) 
    CONT_A (Publish 3000) 
    CONT_B 

enter image description here

Auf meiner Dev-Maschine (eine ganz andere Maschine)

ich ohne Probleme rollen kann

curl http://111.222.333.444:3000 --> OK 

Wenn ich SSH in den Host

Ich kann ohne problesm kräuseln

curl http://111.222.333.444:3000 --> OK 

Wenn ich in CONT_B ausführen

nicht möglich, nur Timeout. Ping ist in Ordnung, aber ...

docker exec -it CONT_B bash 
$ curl http://111.222.333.444:3000 --> TIMEOUT 
$ ping 111.222.333.444 --> OK 

Warum?

Ubuntu 16.04, Dockarbeiter 1.12.3 (Standard-Netzwerk-Setup)

+0

Ich denke, dies ist wahrscheinlich, weil, wie Docker Griffe mit IPTables & Bridge-Netz. Ich werde es nachschlagen müssen, aber ich vermute, die IP-Adresse, die Sie geben, ist wahrscheinlich die IP-Adresse vom Host aus gesehen, nicht die "interne IP" im Andock-Netzwerk zugeordnet. Der Grund, warum Ping aufgelöst werden kann, ist, dass es zum Docker-Host (nicht zum Container) aufgelöst wird. Aber der Docker Weg dies zu erreichen ist, den Port nicht in Container A zu veröffentlichen, sondern stattdessen ein Overlay-Netzwerk https://docs.docker.com/engine/userguide/networking/. –

+2

@RikNauta Die IP-Adresse, die ich verwende, ist der ** öffentliche Host-IP **. Sicherlich sollte das immer korrekt gelöst werden, es sei denn, es widerspricht irgendwie dem internen Docker-Netzwerk. Es ist eine '104 ....' IP-Adresse. – pqvst

+0

Das sollte funktionieren. Es gibt ein Userland-Proxy-Prozess-Andockfenster, das ausgeführt wird, um den Host zu überwachen und die TCP-Verbindung in den Container weiterzuleiten. Funktioniert das gleiche in Docker 1.11? Haben Sie 'userland-proxy' im Docker-Daemon auf false gesetzt? – Matt

Antwort

2

Ich weiß, dass dies nicht unbedingt auf die Frage beantworten, aber es gibt einen weiteren Docker-ish Weg, um Ihr Problem zu lösen. Ich würde vergessen, den Port für die Kommunikation zwischen Containern insgesamt zu veröffentlichen. Erstellen Sie stattdessen ein Overlay-Netzwerk mithilfe von Docker-Schwarm. Sie können die vollständige Anleitung here aber im Grunde finden Sie wie folgt vor:

//create network  
docker network create --driver overlay --subnet=10.0.9.0/24 my-net 
//Start Container A 
docker run -d --name=A --network=my-net producer:latest 
//Start Container B 
docker run -d --name=B --network=my-net consumer:latest 

//Magic has occured 
docker exec -it B /bin/bash 
> curl A:3000 //MIND BLOWN! 

dann im Inneren des Behälters sein kann man einfach curl Hostname A und es wird für Sie lösen (auch wenn Sie tun beginnen Skalierung etc.)

Wenn Sie nicht daran interessiert, über die Verwendung Docker Sie Docker noch Legacy-Links als auch nutzen können Schwarm:

docker run -d --name B --link A:A consumer:latest 

die (nicht veröffentlicht) Ports alle exponierten im Behälter verbinden würde.

Und schließlich, wenn Sie die Produktion in Bewegung setzen ... vergessen über Links & Overlay-Netzwerke insgesamt ... Kubernetes :-) Bit schwieriger Ersteinrichtung verwenden, aber sie führen eine Reihe von Konzepten & Tools & Skalierung machen Verknüpfung Containercluster viel einfacher! Aber das ist nur meine persönliche Meinung.

+2

Es muss nicht einmal ein Overlay-Netzwerk sein, wenn Sie sich auf einem einzelnen Host befinden, der Standard-Bridge-Treiber wird funktionieren. – BMitch

0

Ich hatte ein ähnliches Problem, ich habe einen nginx-Server in einem Container haben (nennen wir es Web) mit mehreren Server-Blöcken und Cron in einem anderen Behälter installiert (nennen wir es cron). Ich benutze Docker komponieren. Ich wollte von Zeit zu Zeit Curl von Cron zu Web verwenden, um ein PHP-Skript auf einer der Anwendungen auszuführen.Es sollte wie folgt aussehen:

curl http://app1.example.com/some_maintance.php 

Aber ich bekam immer Host unerreichbar nach einiger Zeit.

erste Lösung wurde aktualisiert/etc/hosts in cron Container und fügen:

1.2.3.4 app1.example.com 

wobei 1.2.3.4 die ip für Web-Container ist, und es funktionierte - aber das ist ein Hack - auch als Soweit ich weiß sind solche manuellen Updates nicht erwünscht. Sie sollten extra_hosts in Docker erstellen verwenden, die explizite IP-Adresse anstelle des Namens des Containers erfordert, um die IP-Adresse anzugeben.

Ich habe versucht, benutzerdefinierte Netzwerke-Lösung zu verwenden, die, wie ich gesehen habe, der richtige Weg ist, um damit umzugehen, aber ich war nie hier erfolgreich. Wenn ich jemals lerne, wie ich das mache, verspreche ich, diese Antwort zu aktualisieren.

Schließlich verwendete ich curl Fähigkeit IP-Adresse des Servers angeben, und ich pass Domain-Namen als Header in separaten Parameter:

curl -H'Host: app1.example.com' web/some_maintance.php 

nicht sehr schön, aber funktioniert.

(hier Web ist der Name meines nginx Container)

Verwandte Themen