Docker Desktop for Windows のネットワーク機能

Docker Desktop では、より簡単に利用できるネットワーク機能をいくつも提供しています。

機能

VPN パススルー

Docker Desktop のネットワークは VPN に接続して利用することができます。 このとき Docker Desktop は、コンテナーからのトラフィックを捕捉し Windows へ受け渡します。 まるで Docker アプリケーションから発信されたかのように扱います。

ポートマッピング

コンテナーの起動時に、たとえば以下のように-p引数をつけたとします。

$ docker run -p 80:80 -d nginx

Docker Desktop は、コンテナー上のポート 80 を使って稼動するものすべて(この場合はnginx)、localhostのポート 80 から利用できるようにします。 この例では、ホストとコンテナーのそれぞれのポート番号は同一にしています。 ホストのポートを別のものに指定する必要があるとしたら、どうなるでしょう。 つまり、ホストマシン上においてすでにポート 80 を利用して起動しているアプリケーションがあるなら、コンテナーのポートを別のものに接続したらよいことになります。

$ docker run -p 8000:80 -d nginx

こうするとlocalhost:8000への接続が、コンテナー内のポート 80 へ接続されます。 -p の文法はホストポート:クライアントポートです。

HTTP/HTTPS プロキシーサポート

Proxies タブ を参照してください。

既知の制約、利用状況、回避策

以下では、Docker Desktop for Windows の現状のネットワーク機能における制約と回避方法についてまとめます。

Windows 上に docker0 ブリッジがない

Docker Desktop for Windows におけるネットワーク機能の実装方法により、ホスト上からdocker0インターフェースを見ることはできません。 このインターフェースは仮想マシン内にあります。

コンテナーに ping ができない

Docker Desktop for Windows が Linux コンテナーに対して、トラフィックをルーティングできません。 ただし Windows コンテナーであれば ping を通すことができます。

コンテナー単位の IP アドレス割り当てができない

Docker の(Linux における)ブリッジネットワークが Windows ホストからアクセスできません。 ただし Windows コンテナーでは動作します。

利用状況と回避策

上記の制約から影響を受ける利用状況が 2 つあります。

コンテナーからホスト上のサービスに接続したい

ホストには可変の IP アドレスがあります(もっともネットワークを利用しなければ何もありません)。 推奨されるのは、特別な DNS 名host.docker.internalに接続することです。 この DNS は、ホストが利用する内部 IP アドレスを名前解決します。 これは開発環境において用いられるものであり、Docker Desktop for Windows の範囲外にある本番環境では動作しません。

ゲートウェイもgateway.docker.internalを利用してアクセス可能です。

マシン上に Python をインストールしている場合は、例として以下の手順に従い、コンテナーからホスト上のサービスに接続します。

  1. 以下のコマンドを実行して、単純な HTTP サーバーをポート 8000 で起動します。

    python -m http.server 8000

    Python 2.x をインストールしている場合は、python -m SimpleHTTPServer 8000を実行します。

  2. そしてコンテナーの実行とcurlのインストールを行って、以下のコマンドのようにホストへの接続を試してみます。

     $ docker run --rm -it alpine sh
     # apk add curl
     # curl http://host.docker.internal:8000
     # exit
    

Windows からコンテナーに接続したい

localhost に対するポート転送(port forwarding)が動作します。 つまり--publish-p-Pはすべて動きます。 Linux コンテナーから公開されたポートは、ホストに転送されます。

今のところ推奨される方法は、ポートを公開するか、あるいはもう 1 つ別のコンテナーから接続することです。 Linux 上であっても、コンテナーがブリッジネットワーク上ではなく、オーバーレイネットワーク上にある場合には、こういった方法が必要になります。 その場合にはルートが解決されないからです。

たとえばnginxウェブサーバーは以下のように実行します。

$ docker run -d -p 80:80 --name webserver nginx

文法を明確にする目的で、以下の 2 つのコマンドを実行します。 両方ともコンテナー上のポート80を、ホスト上のポート8000に向けて公開するものです。

$ docker run --publish 8000:80 --name webserver nginx

$ docker run -p 8000:80 --name webserver nginx

ポートをすべて公開するには-Pフラグを使います。 たとえば以下のコマンドは(デタッチモードで)コンテナーを起動し、-Pフラグによってコンテナー上の全ポートを、ホスト上のランダムなポートとして公開します。

$ docker run -d -P --name webserver nginx

docker runコマンドにて利用できる、ポート公開に関するオプションの詳細については run コマンド を参照してください。

windows, networking