460

完全な仮想マシンのように機能する Docker コンテナーを作成しようとしています。Dockerfile 内で EXPOSE 命令を使用してポートを公開し、-pフラグを使用しdocker runてポートを割り当てることができることはわかっていますが、コンテナーが実際に実行されたら、追加のポートをライブで開いたりマップしたりするコマンドはありますか?

たとえば、sshd を実行している Docker コンテナーがあるとします。コンテナ ssh を使用している別の誰かが httpd をインストールします。コンテナーのポート 80 を公開し、それをホストのポート 8080 にマップして、コンテナーを再起動せずにコンテナーで実行されている Web サーバーにアクセスできるようにする方法はありますか?

4

15 に答える 15

377

Docker 経由でこれを行うことはできませんが、ホスト マシンからコンテナの公開されていないポートにアクセスできます。

ポート 8000 で何かが実行されているコンテナーがある場合は、実行できます。

wget http://container_ip:8000

コンテナーの IP アドレスを取得するには、次の 2 つのコマンドを実行します。

docker ps
docker inspect container_name | grep IPAddress

内部的には、Docker はイメージを実行するときに iptables を呼び出すシェルを実行するため、これに関するいくつかのバリエーションが機能する可能性があります。

ローカルホストのポート 8001 でコンテナーのポート 8000 を公開するには:

iptables -t nat -A  DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

これを解決する 1 つの方法は、必要なポート マッピングを使用して別のコンテナーをセットアップし、 iptables-saveコマンドの出力を比較することです(ただし、トラフィックを強制的に docker プロキシ経由にする他のオプションのいくつかを削除する必要がありました)。

注: これは docker を破壊するため、青い煙が発生する可能性があることを認識して実行する必要があります。

また

もう 1 つの方法は、(新しい? post 0.6.6?) -P オプションを調べることです。これは、ランダムなホスト ポートを使用し、それらを接続します。

また

0.6.5 では、LINKs 機能を使用して、既存のコンテナーと対話する新しいコンテナーを起動し、そのコンテナーの -p フラグに追加の中継を行うことができますか? (私はまだ LINK を使用していません。)

また

ドッカー0.11で?を使用docker run --net host ..して、コンテナーをホストのネットワーク インターフェイスに直接接続することができます (つまり、net は名前空間ではありません)。したがって、コンテナーで開くすべてのポートが公開されます。

于 2013-11-11T11:47:07.667 に答える
150

これが私がすることです:

  • ライブ コンテナをコミットします。
  • ポートを開いた状態で、新しいイメージでコンテナーを再度実行します (共有ボリュームをマウントし、ssh ポートも開くことをお勧めします)。
sudo docker ps 
sudo docker commit <containerid> <foo/live>
sudo docker run -i -p 22 -p 8000:80 -m /data:/data -t <foo/live> /bin/bash
于 2014-01-27T07:15:51.920 に答える
38

IPtables のハックは、少なくとも Docker 1.4.1 では機能しません。

最善の方法は、公開されたポートで別のコンテナーを実行し、socat でリレーすることです。これは、SQLPlus を使用してデータベースに (一時的に) 接続するために行ったことです。

docker run -d --name sqlplus --link db:db -p 1521:1521 sqlplus

Dockerfile:

FROM debian:7

RUN apt-get update && \
    apt-get -y install socat && \
    apt-get clean

USER nobody

CMD socat -dddd TCP-LISTEN:1521,reuseaddr,fork TCP:db:1521
于 2015-01-26T23:02:41.180 に答える
37

ここに別のアイデアがあります。SSH を使用してポート転送を行います。これには、Docker ホストが VM の場合に OS X (およびおそらく Windows) でも機能するという利点があります。

docker exec -it <containterid> ssh -R5432:localhost:5432 <user>@<hostip>
于 2015-03-26T14:32:11.207 に答える
8

これと同じ問題に対処する必要があり、実行中のコンテナーを停止することなく解決できました。これは、2016 年 2 月現在、Docker 1.9.1 を使用した最新のソリューションです。とにかく、この回答は @ricardo-branco の回答の詳細版ですが、新しいユーザー向けにさらに詳しく説明しています。

私のシナリオでは、コンテナーで実行されている MySQL に一時的に接続したいと考えていました。他のアプリケーション コンテナーがそれにリンクされているため、データベース コンテナーを停止、再構成、および再実行することはまずありませんでした。

外部から (SSH トンネリング経由で Sequel Pro から) MySQL データベースにアクセスしたいので33306、ホスト マシンのポートを使用します。(そう3306ではありません。外部の MySQL インスタンスが実行されている場合に備えてです。)

約 1 時間のiptablesの微調整は無益であることが判明しました。

段階的に、これが私がしたことです:

mkdir db-expose-33306
cd db-expose-33306
vim Dockerfile

Edit dockerfile、これを内部に配置します:

# Exposes port 3306 on linked "db" container, to be accessible at host:33306
FROM ubuntu:latest # (Recommended to use the same base as the DB container)

RUN apt-get update && \
    apt-get -y install socat && \
    apt-get clean

USER nobody
EXPOSE 33306

CMD socat -dddd TCP-LISTEN:33306,reuseaddr,fork TCP:db:3306

次に、イメージをビルドします。

docker build -t your-namespace/db-expose-33306 .

次に、実行中のコンテナにリンクして実行します。(明示的に停止して削除されるまでバックグラウンドで保持する-d代わりに使用-rmします。この場合、一時的に実行するだけです。)

docker run -it --rm --name=db-33306 --link the_live_db_container:db -p 33306:33306  your-namespace/db-expose-33306
于 2016-02-14T00:19:35.650 に答える
5

SSH を使用してトンネルを作成し、ホストでコンテナーを公開できます。

コンテナーからホストへ、およびホストからコンテナーへの両方の方法で実行できます。ただし、両方で OpenSSH のような SSH ツールが必要です (1 つはクライアント、もう 1 つはサーバー)。

たとえば、コンテナーでは、次のことができます。

$ yum install -y openssh openssh-server.x86_64
service sshd restart
Stopping sshd:                                             [FAILED]
Generating SSH2 RSA host key:                              [  OK  ]
Generating SSH1 RSA host key:                              [  OK  ]
Generating SSH2 DSA host key:                              [  OK  ]
Starting sshd:                                             [  OK  ]
$ passwd # You need to set a root password..

コンテナーの IP アドレスは、コンテナー内の次の行から確認できます。

$ ifconfig eth0 | grep "inet addr" | sed 's/^[^:]*:\([^ ]*\).*/\1/g'
172.17.0.2

次に、ホストで次のことができます。

sudo ssh -NfL 80:0.0.0.0:80 root@172.17.0.2
于 2015-05-07T21:43:26.433 に答える
2

Weave Netのようなオーバーレイ ネットワークを使用できます。これは、一意の IP アドレスを各コンテナーに割り当て、すべてのポートをネットワークのすべてのコンテナー部分に暗黙的に公開します。

Weave は、ホスト ネットワークの統合も提供します。デフォルトでは無効になっていますが、ホストからコンテナーの IP アドレス (およびそのすべてのポート) にもアクセスしたい場合は、単純に run を実行できますweave expose

完全開示: 私は Weaveworks で働いています。

于 2016-01-09T19:17:28.453 に答える