Dockerコンテナのポートを後から解放する方法

ヨメレバCSS

 Dockerコンテナをrunで一度作ってしまうと、ポートフォワードの設定も一緒に固定されるようです。それのポートを変更する話です。

(※2016年当時の話で、今だとDocker Toolboxと呼ばれているもののTipsになります。当時もToolboxだったのかこれしかなかったのかは覚えてない…)

スポンサーリンク
GoogleAdSence レクタングル(大)

Dockerホストでポートフォワーディングする

 Dockerコンテナはホスト内部でLANが組まれているような状態なので、単純にポートフォワードの設定をしてやればいいです。

 Windowsの場合はVirtualBoxのコンソールからになります。

 例えば172.16.0.2に向かって6006ポートを開けたいときは、

iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 6006 -j DNAT --to-destination 172.17.0.2:6006

とします。

 これで、ブラウザから http://192.168.99.100:6006/としてやると繋がります。

 この192.168.99.100はWindowsの場合、Dockerホストが実行されているVMに設定されているIPで、VMのコンソールからifconfig eth1としてやるとついていることがわかります。

LinuxでDockerを設定してる場合は普通にhttp://localhost:6006/とかでいいと思います。

参考

## docker で後からポートを公開する docker run したときに -p を忘れたり後から公開の必要ができた場合には ``` iptables -t nat -A DOCKER ! -i docker0 -p tcp ...
久々にdockerを触ると毎回やってしまうウッカリがあるので、自戒のためメモ。 まずは試しにnginxを立ち上げる。 ``` $ docker run -dit -p 8080:80 nginx Unable to find im...

コンテナを作り直す

 とはいえ、上記の方法だと実はrunしたときと同じようにはなっていません。

 runのときのオプションでポートを指定した場合、そのコンテナを開始するとiptablesにもポートフォワード設定がなされ、停止するとiptablesの設定も一緒に消えてくれるようになっています。

 このあたりをオプションや設定ファイルの変更などで対応したかったのですが、どこにもみあたらなかったです…

 なので、コンテナの内容を引き継ぎながら作り直してしまうのがよいかもしれません。

 今度は通常のDockerを操作しているコンソールから、操作を行います。

コンテナイメージの作成

 対象のコンテナを停止してから、

docker commit hoge fuge:fuga

のようにします。hogeはCONTAINER_IDまたはNAME、fugeはREPOSITORY、fugaがTAGになります。

これで

docker images

としてイメージを確認してみると、

REPOSITORY                       TAG                 IMAGE ID            CREATED                  SIZE
fuge                             fuga                cefa656dde84        Less than a second ago   2.38 GB

というように作成されています。

イメージからコンテナを実行する

 これは普通に

docker run --name new_container -itd -p 6006:6006 fuge:fuga

で、起動した状況を確認すると、

docker ps -a

CONTAINER ID        IMAGE               COMMAND             CREATED                  STATUS              PORTS                              NAMES
f1ac66e243be        fuge:fuga           "/bin/bash"         Less than a second ago   Up 17 seconds       0.0.0.0:6006->6006/tcp, 8888/tcp   new_container

となっています。

参考:

Docker ではイメージからコンテナを起動する。 反対に様々な操作を加えたコンテナからイメージを作り直すこともできる。 今回は SSH サーバが動作するイメージを作ってみる。 ただし、作成を自動化するための Dockerfile は使わない。 まずは CentOS のイメージからコンテナを起動する。 $ sudo...

docker-composeはどうしているのか

(2019/02/07追記)

 docker-comopose.ymlにはports設定オプションがあり、ここにポートフォワードの設定をすることが出来ます。

 もちろん途中で変更もできるのですが、ではどうしているのか確認してみました。

 環境はWindows10Pro、Docker for Windowsです。

 まず次のようなdocker-compose.ymlを用意します。

version: '3'

services:
  app:
    image: nginx
    ports: 
      - "8000:80"

 nginxのイメージを使用してポート80を8000にフォワードしていいます。

 こちらをupすると、http://localhost:8000でnginxのページが見えます。

>docker-compose up

 このとき、コンテナは次のようになっていました。

>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                  NAMES
a3f3714f952e        nginx               "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:8000->80/tcp   tmp_app_1

 コンテナIDはa3f3714f952eです。

 このコンテナにexecして、ホームディレクトリにファイルを作っておいてみます。

>docker-compose exec app bash
root@a3f3714f952e:/# cd
root@a3f3714f952e:~# touch test
root@a3f3714f952e:~# ls
test
root@a3f3714f952e:~#

 このコンテナを停めてupしても、ファイルはあります。

>docker-compose stop
Stopping tmp_app_1 ... done

>docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
>docker-compose up -d
Starting tmp_app_1 ... done
>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a3f3714f952e nginx "nginx -g 'daemon of…" 8 minutes ago Up 4 seconds 0.0.0.0:8000->80/tcp tmp_app_1
>docker-compose exec app bash
root@a3f3714f952e:/# cd
root@a3f3714f952e:~# ls
test
root@a3f3714f952e:~#

 ポートを8010に変更してみます。

version: '3'

services:
  app:
    image: nginx
    ports: 
      - "8010:80"

 変更してからupしてみると、ファイルは消えて、コンテナIDも変わっています。

p>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
72872c27cc58        nginx               "nginx -g 'daemon of…"   7 seconds ago       Up 6 seconds        0.0.0.0:8010->80/tcp   tmp_app_1

>docker-compose exec app bash
root@72872c27cc58:/# cd
root@72872c27cc58:~# ls
root@72872c27cc58:~#

 どうもコンテナを再作成しているようです。

 リファレンスにも次のようにありました。

もしサービス用のコンテナが存在している場合、かつ、コンテナを作成後にサービスの設定やイメージを変更している場合は、 docker-compose up -d を実行すると、 設定を反映するためにコンテナを停止・再作成します(マウントしているボリュームは、そのまま保持します)。Compose が設定を反映させないようにするには、 –no-recreate フラグを使います。

 コンテナは基本使い捨てで、消したくないファイルはちゃんとマウントしたところに作るのがよさそうです。

関連:ざっくりdocker-compose

スポンサーリンク
GoogleAdSence レクタングル(大)

コメント

  1. […] iptablesで設定する。 Dockerコンテナのポートを後から解放する方法 の記事を見て、早速iptablesで設定をしてみる。 […]