web-dev-qa-db-fra.com

Transférer le port de l'hôte au conteneur de menu fixe

Est-il possible d'avoir un port d'accès au conteneur Docker ouvert par l'hôte? Concrètement, MongoDB et RabbitMQ s'exécutent sur l'hôte et j'aimerais exécuter un processus dans un conteneur Docker pour écouter la file d'attente et (éventuellement) écrire dans la base de données.

Je sais que je peux transférer un port du conteneur vers l'hôte (via l'option -p) et disposer d'une connexion vers le monde extérieur (par exemple, Internet) depuis le conteneur Docker, mais je souhaite ne pas exposer les ports RabbitMQ et MongoDB. de l'hôte au monde extérieur.

EDIT: quelques éclaircissements:

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

joelkuiper@vps20528 ~ % docker run -i -t base /bin/bash
root@f043b4b235a7:/# apt-get install nmap
root@f043b4b235a7:/# 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

Je devais faire cette astuce pour obtenir une connexion Internet avec le conteneur: Mon pare-feu bloque les connexions réseau du conteneur docker vers l'extérieur

EDIT: J'ai fini par créer un pont personnalisé à l'aide de pipework et de laisser les services écouter sur les adresses IP du pont. Je suis allé avec cette approche au lieu de laisser MongoDB et RabbitMQ écouter sur le docker bridge car cela donne plus de flexibilité.

136
JoelKuiper

Votre hôte docker expose un adaptateur à tous les conteneurs. En supposant que vous êtes sur Ubuntu récent, vous pouvez exécuter

ip addr

Cela vous donnera une liste d’adaptateurs réseau, dont l’un ressemblera à quelque chose comme:

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

Vous devrez dire à lapin/mongo de se lier à cette adresse IP (172.17.42.1). Après cela, vous devriez pouvoir ouvrir des connexions vers 172.17.42.1 à partir de vos conteneurs.

46
Seldo

Un moyen simple mais relativement peu sûr serait d'utiliser l'option --net=Host pour docker run.

Cette option permet au conteneur d'utiliser la pile de mise en réseau de l'hôte. Ensuite, vous pouvez vous connecter aux services s'exécutant sur l'hôte en utilisant simplement "localhost" comme nom d'hôte.

C’est plus facile à configurer car vous n’aurez pas à configurer le service pour accepter les connexions de l’adresse IP de votre conteneur de menu fixe, ni à indiquer au conteneur de menu fixe une adresse IP ou un nom d’hôte spécifique auquel vous connecter, un port.

Par exemple, vous pouvez le tester en exécutant la commande suivante, qui suppose que votre image s'appelle my_image, qu'elle inclut l'utilitaire telnet et que le service auquel vous souhaitez vous connecter se trouve sur le port 25:

docker run --rm -i -t --net=Host my_image telnet localhost 25

Si vous envisagez de le faire de cette manière, veuillez consulter la mise en garde concernant la sécurité sur cette page:

https://docs.docker.com/articles/networking/

Ça dit:

--net = Host - Indique à Docker de ne pas placer le conteneur dans une pile réseau distincte. En substance, ce choix indique à Docker de ne pas conteneuriser la mise en réseau du conteneur! Bien que les processus de conteneur restent limités à leur propre système de fichiers, à leur liste de processus et à leurs ressources limitées, une commande rapide ip addr vous montrera que, du point de vue du réseau, ils vivent "à l'extérieur" de l'hôte principal Docker et ont un accès complet à ses interfaces réseau. . Notez que cela ne permet pas au conteneur de reconfigurer la pile réseau de l'hôte - cela nécessiterait --privileged = true -, mais aux processus de conteneur d'ouvrir des ports avec un numéro peu élevé, comme tout autre processus racine. Il permet également au conteneur d'accéder à des services de réseau locaux tels que D-bus. Cela peut amener les processus du conteneur à effectuer des opérations inattendues, telles que le redémarrage de votre ordinateur. Vous devez utiliser cette option avec prudence.

95
David Grayson

Vous pouvez également créer un tunnel SSH.

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

Ainsi, la elasticsearch dispose d'un tunnel vers le serveur avec le service en cours d'exécution (Elasticsearch, MongoDB, PostgreSQL) et expose le port 9200 avec ce service.

9
czerasz

J'ai eu un problème similaire lors de l'accès à un serveur LDAP à partir d'un conteneur Docker. J'ai défini une adresse IP fixe pour le conteneur et ajouté une règle de pare-feu.

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

règle iptables:

iptables -A INPUT -j ACCEPT -p tcp -s 192.168.50.2 -d $192.168.50.1 --dport portnumberOnHost

Dans l'accès au conteneur dockerhost:portnumberOnHost

3
Arigion

Si MongoDB et RabbitMQ s'exécutent sur l'hôte, le port devrait déjà être exposé car il ne se trouve pas dans Docker.

Vous n'avez pas besoin de l'option -p pour exposer les ports du conteneur à l'hôte. Par défaut, tous les ports sont exposés. L'option -p vous permet d'exposer un port du conteneur à l'extérieur de l'hôte.

Donc, je suppose que vous n'avez pas du tout besoin de -p et que cela devrait fonctionner correctement :)

3
creack