Dockerのホスト側ポートを公開

Pocket

Dockerのポート関連について調べたメモです。

ポート関連

  • EXPOSE
  • docker run -P
    https://docs.docker.jp/engine/reference/run.html#expose
  • docker run -p 'ホストポート:コンテナポート'
    https://docs.docker.jp/engine/reference/run.html#expose
  • Docker Compose portプロパティ:port:ホストポート:コンテナポート
    https://docs.docker.com/compose/compose-file/#ports

EXPOSE

EXPOSE 命令だけは、実際にはポートを 公開publish しません。これは、どのポートを公開する意図なのかという、イメージの作者とコンテナ実行者の両者に対し、ある種のドキュメントとして機能します。コンテナの実行時に実際にポートを公開するには、 docker run で -p フラグを使い、公開用のポートと割り当てる( マップmap する)ポートを指定します

— https://docs.docker.jp/engine/reference/builder.html#expose

EXPOSEはホスト側のポート番号を開けるわけではないことに注意します。

ホスト側のポートを開けるにはdocker runならpオプションまたはPオプションで明示的に指定します。

httpdの例では以下のようになります。

  • ホストのポート8000番を開けます(コンテナはポート80番でリッスンすることがhttpd:latestのEXPOSEで明記されています。
$ sudo docker run -p '8000:80' httpd:latest

docker run

Pオプション

-P, –publish-all Publish all exposed ports to random ports
— docker run –help

pオプション

-p, –publish list Publish a container’s port(s) to the host
— docker run –help

docker compose

Dockerfileでportsプロパティを指定します。

version: '3'

services:
  app:
    image: httpd:latest
    volumes:
      - ./html:/var/www/html
    ports:
      - "8000:80"

例:httpd

httpd:latestEXPOSE80が指定されています。
203.0.113.100でコンテナを公開すると仮定して動作を確かめます。

$ docker run -d httpd:latest

上記コマンドではhttp://203.0.113.100にアクセスできません1
以下のとおりホストのポート番号80が閉じていることがわかります。

$ nmap 127.0.0.1 -Pn -p 80
...
PORT   STATE  SERVICE
80/tcp closed http
...

http://203.0.113.100にアクセスできるようにするには-pオプションを使ってpublishする必要があります。
ホストのポート80番をコンテナのポート80番に対応させてpublishします。

$ docker run -d -p '80:80' httpd:latest

ホストでポート番号80の状態を確認します。
以下のとおりホストのポート番号80が開いているいることが分かります。

$ nmap 127.0.0.1 -Pn -p 80
...
PORT   STATE SERVICE
80/tcp open  http
...

ポート公開(publish)

docker runpオプションやPオプション、docker composeportsプロパティでホストのポートをpublishすると、Dockerデーモンによってiptablesが変更されます。

publishしない場合のiptables

$ docker run -d httpd:latest
$ iptables -L
....
Chain DOCKER (3 references)
target     prot opt source               destination
...

publishする場合のiptables

$ docker run -d -p '80:80' httpd:latest
$ iptables -L
...
Chain DOCKER (4 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             xxxxxxxxxxxxxxxxxx  tcp dpt:http
...

参考


  1. もちろんコンテナ内では、httpdがポート80番でリッスンしています。docker execでコンテナにログインして$ curl -v 127.0.0.1でHTMLドキュメントを取得できます(curlはaptでインストールします)。 

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。