web-dev-qa-db-ja.com

Dockerコマンドの--net = Hostオプションは実際に何をしますか?

私はDockerの初心者です。 docker runコマンドでこのオプションが何をするかについての明確な説明は、それについて深く、少し混乱して見つけることができませんでした。

ポートを指定せずに、Dockerコンテナで実行されているアプリケーションにアクセスするために使用できますか?例として、オプション-p 8080:8080をdocker runコマンドを使用してポート8080のdockerイメージ経由でデプロイされたwebappを実行する場合、Dockerコンテナーip/theWebAppNameの8080ポートでアクセスする必要があることがわかります。しかし、--net=Hostオプションがどのように機能するかを本当に考えることはできません。

45

Dockerのインストール後、デフォルトで3つのネットワークがあります:

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f3be8b1ef7ce        bridge              bridge              local
fbff927877c1        Host                Host                local
023bb5940080        none                null                local

これをシンプルにしようとしています。そのため、デフォルトでコンテナを起動すると、ブリッジ(docker0)ネットワーク内にコンテナが作成されます。

$ docker run -d jenkins
1498e581cdba        jenkins             "/bin/tini -- /usr..."   3 minutes ago       Up 3 minutes        8080/tcp, 50000/tcp   friendly_bell

Jenkinsのdockerfileでは、ポート8080および50000が公開されています。これらのポートは、ブリッジネットワーク上のコンテナに対して開かれます。そのため、そのブリッジネットワーク内のすべてがポート8080および50000でコンテナにアクセスできます。ブリッジネットワーク内のすべては"Subnet": "172.17.0.0/16",のプライベート範囲にあります。外部からアクセスする場合は、-p 8080:8080でポートをマッピングする必要があります。これにより、コンテナのポートが実サーバー(ホストネットワーク)のポートにマップされます。したがって、8080でサーバーにアクセスすると、ポート8080でブリッジネットワークにルーティングされます。

これで、ホストネットワークもできました。コンテナネットワーキングはコンテナ化されません。したがって、ホストネットワークでコンテナを起動すると、次のようになります(最初のコンテナです)。

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
1efd834949b2        jenkins             "/bin/tini -- /usr..."   6 minutes ago       Up 6 minutes                              eloquent_panini
1498e581cdba        jenkins             "/bin/tini -- /usr..."   10 minutes ago      Up 10 minutes       8080/tcp, 50000/tcp   friendly_bell

違いはポートにあります。これで、コンテナはホストネットワーク内にあります。したがって、ホストでポート8080を開くと、すぐにコンテナにアクセスします。

$ Sudo iptables -I INPUT 5 -p tcp -m tcp --dport 8080 -j ACCEPT

ファイアウォールでポート8080を開いており、ポート8080でサーバーにアクセスしているときに、ジェンキンにアクセスしています。 このブログ は、それをよりよく理解するのにも役立ちます。

81
lvthillo

--net=Hostオプションは、ネットワークの観点から、Dockerコンテナー内のプログラムをホスト自体で実行されているように見せるために使用されます。コンテナが通常取得できるよりも多くのネットワークアクセスを許可します。

通常、ホストマシンからコンテナにポートを転送する必要がありますが、コンテナがホストのネットワークを共有する場合、ネットワークアクティビティはホストマシン上で直接発生します。プログラムがコンテナ内ではなくローカルで実行されている場合と同じです。

これは、ポートを公開してコンテナポートにマップする必要がなくなったことを意味しますが、Dockerfilesを編集して各コンテナがリッスンするポートを調整し、同じコンテナで2つのコンテナを操作できないため、競合を回避する必要がありますホストポート。ただし、このオプションの本当の理由は、ポートレベルでコンテナーに転送するのが難しいネットワークアクセスを必要とするアプリを実行するためです。

たとえば、DHCPサーバーを実行する場合、ネットワーク上のブロードキャストトラフィックをリッスンし、パケットからMACアドレスを抽出できる必要があります。この情報はポート転送プロセス中に失われるため、Docker内でDHCPサーバーを実行する唯一の方法は、コンテナーを--net=Hostとして実行することです。

一般的に、--net=Hostは、非常に特殊で異常なネットワークニーズを持つプログラムを実行している場合にのみ必要です。

最後に、セキュリティの観点から、Dockerコンテナは1つのポートのみをアドバタイズ(公開)している場合でも、多くのポートでリッスンできます。通常、これは単一の予期されるポートのみを転送するので問題ありませんが、--Host=netを使用すると、リストにないポートでも、ホストでリッスンするallを取得できますDockerfileで。これは、コンテナを厳密にチェックする必要がある場合(特に、それがソフトウェアプロジェクトによって提供される公式のコンテナなどではない場合)、マシンで余分なサービスを誤って公開しないようにする必要がある場合を意味します。

1
Malvineous