私はDockerの初心者です。 docker runコマンドでこのオプションが何をするかについての明確な説明は、それについて深く、少し混乱して見つけることができませんでした。
ポートを指定せずに、Dockerコンテナで実行されているアプリケーションにアクセスするために使用できますか?例として、オプション-p 8080:8080
をdocker runコマンドを使用してポート8080のdockerイメージ経由でデプロイされたwebappを実行する場合、Dockerコンテナーip/theWebAppNameの8080ポートでアクセスする必要があることがわかります。しかし、--net=Host
オプションがどのように機能するかを本当に考えることはできません。
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
でサーバーにアクセスしているときに、ジェンキンにアクセスしています。 このブログ は、それをよりよく理解するのにも役立ちます。
--net=Host
オプションは、ネットワークの観点から、Dockerコンテナー内のプログラムをホスト自体で実行されているように見せるために使用されます。コンテナが通常取得できるよりも多くのネットワークアクセスを許可します。
通常、ホストマシンからコンテナにポートを転送する必要がありますが、コンテナがホストのネットワークを共有する場合、ネットワークアクティビティはホストマシン上で直接発生します。プログラムがコンテナ内ではなくローカルで実行されている場合と同じです。
これは、ポートを公開してコンテナポートにマップする必要がなくなったことを意味しますが、Dockerfilesを編集して各コンテナがリッスンするポートを調整し、同じコンテナで2つのコンテナを操作できないため、競合を回避する必要がありますホストポート。ただし、このオプションの本当の理由は、ポートレベルでコンテナーに転送するのが難しいネットワークアクセスを必要とするアプリを実行するためです。
たとえば、DHCPサーバーを実行する場合、ネットワーク上のブロードキャストトラフィックをリッスンし、パケットからMACアドレスを抽出できる必要があります。この情報はポート転送プロセス中に失われるため、Docker内でDHCPサーバーを実行する唯一の方法は、コンテナーを--net=Host
として実行することです。
一般的に、--net=Host
は、非常に特殊で異常なネットワークニーズを持つプログラムを実行している場合にのみ必要です。
最後に、セキュリティの観点から、Dockerコンテナは1つのポートのみをアドバタイズ(公開)している場合でも、多くのポートでリッスンできます。通常、これは単一の予期されるポートのみを転送するので問題ありませんが、--Host=net
を使用すると、リストにないポートでも、ホストでリッスンするallを取得できますDockerfileで。これは、コンテナを厳密にチェックする必要がある場合(特に、それがソフトウェアプロジェクトによって提供される公式のコンテナなどではない場合)、マシンで余分なサービスを誤って公開しないようにする必要がある場合を意味します。