Transfert du port d'accueil au conteneur docker
est-il possible d'avoir un docker des ports d'accès aux conteneurs ouverts par l'hôte? Concrètement, J'ai MongoDB et RabbitMQ tournant sur l'hôte et j'aimerais lancer un processus dans un conteneur Docker pour écouter la file d'attente et (optionnellement) écrire dans la base de données.
je sais que je peux transmettre du conteneur à l'hôte (via l'option-p) et j'ai une connexion au monde extérieur (i.e. internet) à partir de l'intérieur du conteneur Docker mais je voudrais ne pas exposer le RabbitMQ et MongoDB ports de l'hôte au monde extérieur.
EDIT: quelques précisions:
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
j'ai dû faire cette astuce pour obtenir n'importe quelle connexion internet avec le container: mon pare-feu bloque les connexions réseau du container docker à l'extérieur
EDIT : finalement je suis allé avec la création d'un pont personnalisé en utilisant tuyauteries et que les services écoutent les IPS. J'ai opté pour cette approche au lieu d'avoir MongoDB et RabbitMQ à l'écoute sur le pont docker parce que cela donne plus de flexibilité.
5 réponses
votre Docker hôte expose un adaptateur à tous les conteneurs. En supposant que vous êtes sur ubuntu récente, vous pouvez exécuter
ip addr
cela vous donnera une liste d'adaptateurs de 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 à rabbit/mongo de se lier à cette IP (172.17.42.1). Après cela, vous devriez être en mesure d'ouvrir des connexions à 172.17.42.1 de l'intérieur de vos conteneurs.
une façon simple mais relativement peu sûre serait d'utiliser l'option --net=host
pour docker run
.
Cette option fait en sorte que le conteneur utilise la pile réseau de l'hôte. Ensuite, vous pouvez vous connecter aux services fonctionnant sur l'hôte simplement en utilisant "localhost" comme nom d'hôte.
c'est plus facile à configurer parce que vous n'aurez pas à configurer le service pour accepter les connexions à partir de l'adresse IP de votre conteneur docker, et vous vous n'aurez pas à donner au conteneur docker une adresse IP ou un nom d'hôte spécifique pour vous connecter, juste un port.
par exemple, vous pouvez le tester en exécutant la commande suivante, qui suppose que votre image s'appelle my_image
, votre image inclut l'utilitaire telnet
, et le service auquel vous voulez vous connecter est sur le port 25:
docker run --rm -i -t --net=host my_image telnet localhost 25
si vous envisagez de le faire de cette façon, s'il vous plaît voir la mise en garde sur la sécurité sur cette page:
https://docs.docker.com/articles/networking /
Il dit:
--net=host -- dit à Docker de ne pas placer le conteneur dans une pile réseau séparée. Essentiellement, ce choix indique à Docker de ne pas contenir le réseau du conteneur! Alors que les processus container seront toujours confinés à leur propre système de fichiers et leur liste de processus et leurs limites de ressources, une commande addr ip rapide vous montrera que, réseau-sage, ils vivent "à l'extérieur" dans le Panneau d'accueil et avoir un accès complet à ses interfaces réseau. Notez que cela ne permet pas au conteneur de reconfigurer la pile du réseau hôte - ce qui nécessiterait --privileged=true - mais cela permet aux processus container d'ouvrir des ports bas-numérotés comme tout autre processus racine. Il permet également au conteneur d'accéder à des services de réseau local comme d-bus. Cela peut conduire à des processus dans le conteneur être en mesure de faire des choses inattendues comme redémarrer votre ordinateur. Vous utilisez cette option avec prudence.
vous pouvez aussi 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
de cette façon le elasticsearch
dispose d'un tunnel vers le serveur avec le service courant (Elasticsearch, MongoDB, PostgreSQL) et expose le port 9200 avec ce service.
si MongoDB et RabbitMQ tournent sur L'hôte, alors le port devrait déjà être exposé car il n'est 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, à mon avis, vous n'avez pas besoin de '-p' du tout et il devrait fonctionner très bien:)
j'ai eu un problème similaire en accédant à un serveur LDAP à partir d'un conteneur docker. J'ai défini une 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 2.168.50.1 --dport portnumberOnHost
à l'intérieur de l'accès au conteneur dockerhost:portnumberOnHost