it-swarm.com.de

Host-Port an Docker-Container weiterleiten

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.

136
JoelKuiper

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.

46
Seldo

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.

95
David Grayson

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.

9
czerasz

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

3
Arigion

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 :)

3
creack