Ist es möglich, dass ein Docker-Container vom Host geöffnet wird? Konkret habe ich MongoDB und RabbitMQ auf dem Host und möchte einen Prozess in einem Docker-Container ausführen, um die Warteschlange abzuhören und (optional) in die Datenbank zu schreiben.
Ich weiß, dass ich einen Port vom Container an den Host weiterleiten kann (über die Option -p) und über den Docker-Container eine Verbindung zur Außenwelt (dh zum Internet) habe, aber ich möchte die Ports RabbitMQ und MongoDB nicht offen legen vom Host nach außen.
EDIT: einige Klarstellungen:
Starting Nmap 5.21 ( http://nmap.org ) at 2013-07-22 22:39 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00027s latency).
PORT STATE SERVICE
6311/tcp open unknown
[email protected] ~ % docker run -i -t base /bin/bash
[email protected]:/# apt-get install nmap
[email protected]:/# nmap 172.16.42.1 -p 6311 # IP found via docker inspect -> gateway
Starting Nmap 6.00 ( http://nmap.org ) at 2013-07-22 20:43 UTC
Nmap scan report for 172.16.42.1
Host is up (0.000060s latency).
PORT STATE SERVICE
6311/tcp filtered unknown
MAC Address: E2:69:9C:11:42:65 (Unknown)
Nmap done: 1 IP address (1 Host up) scanned in 13.31 seconds
Ich musste diesen Trick ausführen, um eine Internetverbindung mit dem Container herzustellen: Meine Firewall blockiert Netzwerkverbindungen vom Docker-Container nach außen
[~ # ~] edit [~ # ~] : Irgendwann habe ich eine benutzerdefinierte Brücke mit Pipeline erstellt und die Dienste lauschen auf den Bridge-IPs. Ich habe diesen Ansatz gewählt, anstatt MongoDB und RabbitMQ auf der Docker-Bridge abhören zu lassen, da dies mehr Flexibilität bietet.
Ihr Docker-Host macht einen Adapter für alle Container verfügbar. Vorausgesetzt, Sie sind auf dem neuesten Ubuntu, können Sie ausführen
ip addr
Dadurch erhalten Sie eine Liste von Netzwerkadaptern, von denen einer ungefähr so aussieht
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 22:23:6b:28:6b:e0 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
inet6 fe80::a402:65ff:fe86:bba6/64 scope link
valid_lft forever preferred_lft forever
Sie müssen Rabbit/Mongo anweisen, sich an diese IP (172.17.42.1) zu binden. Danach sollten Sie in der Lage sein, Verbindungen zu 172.17.42.1 aus Ihren Containern heraus zu öffnen.
Ein einfacher, aber relativ unsicherer Weg wäre, die Option --net=Host
Für docker run
Zu verwenden.
Mit dieser Option wird festgelegt, dass der Container den Netzwerkstapel des Hosts verwendet. Anschließend können Sie eine Verbindung zu Diensten herstellen, die auf dem Host ausgeführt werden, indem Sie einfach "localhost" als Hostnamen verwenden.
Dies ist einfacher zu konfigurieren, da Sie den Dienst nicht so konfigurieren müssen, dass Verbindungen von der IP-Adresse Ihres Docker-Containers akzeptiert werden, und Sie müssen dem Docker-Container nicht nur eine bestimmte IP-Adresse oder einen bestimmten Host-Namen mitteilen, zu dem eine Verbindung hergestellt werden soll ein Hafen.
Sie können es zum Beispiel testen, indem Sie den folgenden Befehl ausführen, bei dem davon ausgegangen wird, dass Ihr Image den Namen my_image
Hat, Ihr Image das Dienstprogramm telnet
enthält und der Dienst, mit dem Sie eine Verbindung herstellen möchten, sich auf einem Port befindet 25
docker run --rm -i -t --net=Host my_image telnet localhost 25
Wenn Sie dies in Betracht ziehen, lesen Sie bitte den Sicherheitshinweis auf dieser Seite:
https://docs.docker.com/articles/networking/
Es sagt:
--net = Host - Weist Docker an, das Platzieren des Containers in einem separaten Netzwerkstapel zu überspringen. Im Wesentlichen wird Docker durch diese Auswahl angewiesen, das Netzwerk des Containers nicht zu beeinträchtigen. Während Container-Prozesse weiterhin auf ihr eigenes Dateisystem, ihre eigene Prozessliste und ihre Ressourcenbeschränkungen beschränkt sind, zeigt ein kurzer Befehl ip addr, dass sie netzwerkmäßig auf dem Haupt-Docker-Host "außerhalb" leben und uneingeschränkten Zugriff auf ihre Netzwerkschnittstellen haben . Beachten Sie, dass der Container dadurch nicht den Host-Netzwerk-Stack neu konfigurieren kann - dies würde --privileged = true erfordern -, sondern dass Container-Prozesse Ports mit niedriger Nummer wie alle anderen Root-Prozesse öffnen können. Außerdem kann der Container auf lokale Netzwerkdienste wie den D-Bus zugreifen. Dies kann dazu führen, dass Prozesse im Container unerwartete Aktionen ausführen, z. B. einen Neustart des Computers. Sie sollten diese Option mit Vorsicht verwenden.
Sie können auch einen SSH-Tunnel erstellen.
docker-compose.yml
:
---
version: '2'
services:
kibana:
image: "kibana:4.5.1"
links:
- elasticsearch
volumes:
- ./config/kibana:/opt/kibana/config:ro
elasticsearch:
build:
context: .
dockerfile: ./docker/Dockerfile.tunnel
entrypoint: ssh
command: "-N elasticsearch -L 0.0.0.0:9200:localhost:9200"
docker/Dockerfile.tunnel
:
FROM buildpack-deps:jessie
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive \
apt-get -y install ssh && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY ./config/ssh/id_rsa /root/.ssh/id_rsa
COPY ./config/ssh/config /root/.ssh/config
COPY ./config/ssh/known_hosts /root/.ssh/known_hosts
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/config && \
chown $USER:$USER -R /root/.ssh
config/ssh/config
:
# Elasticsearch Server
Host elasticsearch
HostName jump.Host.czerasz.com
User czerasz
ForwardAgent yes
IdentityFile ~/.ssh/id_rsa
Auf diese Weise hat elasticsearch
einen Tunnel zum Server mit dem ausgeführten Dienst (Elasticsearch, MongoDB, PostgreSQL) und macht Port 9200 mit diesem Dienst verfügbar.
Ich hatte ein ähnliches Problem beim Zugriff auf einen LDAP-Server aus einem Docker-Container. Ich habe eine feste IP für den Container festgelegt und eine Firewall-Regel hinzugefügt.
docker-compose.yml:
version: '2'
services:
containerName:
image: dockerImageName:latest
extra_hosts:
- "dockerhost:192.168.50.1"
networks:
my_net:
ipv4_address: 192.168.50.2
networks:
my_net:
ipam:
config:
- subnet: 192.168.50.0/24
iptables-Regel:
iptables -A INPUT -j ACCEPT -p tcp -s 192.168.50.2 -d $192.168.50.1 --dport portnumberOnHost
Innerhalb des Containerzugangs dockerhost:portnumberOnHost
Wenn MongoDB und RabbitMQ auf dem Host ausgeführt werden, sollte der Port bereits verfügbar sein, da er sich nicht in Docker befindet.
Sie benötigen die Option -p
Nicht, um Ports vom Container zum Host verfügbar zu machen. Standardmäßig sind alle Ports verfügbar. Mit der Option -p
Können Sie einen Port vom Container zur Außenseite des Hosts freigeben.
Also, meine Vermutung ist, dass Sie -p
Überhaupt nicht brauchen und es sollte gut funktionieren :)