web-dev-qa-db-ja.com

ホストポートをdockerコンテナに転送する

ホストによって開かれたDockerコンテナーアクセスポートを持つことは可能ですか?具体的には、ホストでMongoDBとRabbitMQを実行しており、Dockerコンテナーでプロセスを実行してキューをリッスンし、(オプションで)データベースに書き込みたいと考えています。

コンテナからホストにポートを転送し(-pオプションを介して)、Dockerコンテナ内から外部の世界(つまりインターネット)に接続できることは知っていますが、RabbitMQおよびMongoDBポートを公開したくないホストから外の世界へ。

編集:いくつかの説明:

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

コンテナとのインターネット接続を取得するには、このトリックを実行する必要がありました: 私のファイアウォールは、Dockerコンテナから外部へのネットワーク接続をブロックしています

EDIT:最終的に、私は pipework を使用してカスタムブリッジを作成し、ブリッジIPでサービスをリッスンさせました。 MongoDBとRabbitMQにdockerブリッジをリッスンさせる代わりに、このアプローチを採用しました。これにより、柔軟性が向上します。

131
JoelKuiper

ドッカーホストは、すべてのコンテナーにアダプターを公開します。あなたが最近のubuntuにいると仮定すると、実行できます

ip addr

これにより、ネットワークアダプターのリストが表示され、そのうちの1つは次のようになります。

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

Rabbit/mongoにそのIP(172.17.42.1)にバインドするように指示する必要があります。その後、コンテナ内から172.17.42.1への接続を開くことができるはずです。

46
Seldo

簡単だが比較的安全でない方法は、--net=Hostdocker runオプションを使用することです。

このオプションは、コンテナがホストのネットワークスタックを使用するようにします。次に、「localhost」をホスト名として使用するだけで、ホストで実行されているサービスに接続できます。

これは、ドッカーコンテナーのIPアドレスからの接続を受け入れるようにサービスを構成する必要がなく、接続する特定のIPアドレスまたはホスト名をドッカーコンテナーに伝える必要がないため、構成が簡単です。ポート。

たとえば、イメージがmy_imageと呼ばれ、イメージにtelnetユーティリティが含まれており、接続するサービスがポート25にあると仮定して、次のコマンドを実行してテストできます。

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

この方法で行うことを検討する場合は、このページのセキュリティに関する注意を参照してください。

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

それは言います:

--net = Host-コンテナを別のネットワークスタック内に配置しないようにDockerに指示します。本質的に、この選択は、コンテナのネットワークをコンテナ化しないようにDockerに指示します!コンテナプロセスは依然として独自のファイルシステムとプロセスリストとリソース制限に限定されますが、簡単なip addrコマンドを使用すると、ネットワークごとにメインDockerホストの「外部」にあり、そのネットワークインターフェイスに完全にアクセスできることがわかります。これにより、コンテナはホストネットワークスタックを再構成できません(--privileged = trueが必要です)が、コンテナプロセスは他のルートプロセスのように小さい番号のポートを開くことができます。また、コンテナがDバスなどのローカルネットワークサービスにアクセスできるようにします。これにより、コンテナ内のプロセスがコンピューターの再起動などの予期しないことを行えるようになります。このオプションは注意して使用する必要があります。

91
David Grayson

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

このようにして、elasticsearchには、実行中のサービス(Elasticsearch、MongoDB、PostgreSQL)を備えたサーバーへのトンネルがあり、そのサービスでポート9200を公開します。

8
czerasz

DockerコンテナからLDAPサーバーにアクセスするときに同様の問題が発生しました。コンテナに固定IPを設定し、ファイアウォールルールを追加しました。

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ルール:

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

コンテナ内でdockerhost:portnumberOnHostにアクセスします

3
Arigion

MongoDBとRabbitMQがホストで実行されている場合、ポートはDocker内にないため既に公開されているはずです。

ポートをコンテナからホストに公開するために-pオプションは必要ありません。デフォルトでは、すべてのポートが公開されています。 -pオプションを使用すると、コンテナからホストの外部にポートを公開できます。

したがって、私の推測では、-pはまったく必要なく、正常に動作するはずです:)

3
creack