環境
- CentOS 7.3.1611
- docker 17.05
概要
例えば以下のような感じで起動してしまった場合に
docker run -d --name test nginx
80/tcp で動作するのはコンテナ内のみになるので localhost に curl などできません
普通はこの場合コンテナを削除して再生成するのですが、データを永続している場合などはデータが来てしまうので削除したくありません (本当はちゃんと永続して削除できるようにしておくのが正解ですが、、、)
そんな場合は起動中のコンテナに対してホストのポートにコンテナのポートをバインドする方法を紹介します
docker commit を使う
一旦別のイメージを作成して、そこから別のコンテナを起動する方法です
- docker commit test new_nginx
docker run -d --name new_test -p 8080:80 new_nginx
で新しくコンテナを起動したら古いコンテナを削除します
- docker stop test
- docker rm test
一応動作していた状態のコンテナからホストにポートをバインドしたコンテナを新たに生成することができます
(失敗例) iptables を使う
失敗したんですが、載せておきます
docker run で -p オプションを指定すると iptables のルールにいろいろと追加されます
それと同じルールを追加できればアクセスできるのではと思いやってみました
動作中のコンテナの IP は 172.17.0.2 とします
まず iptables -nL
で表示される
Chain DOCKER (3 references)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 172.17.0.2 tcp dpt:80
を追加します
iptables -A DOCKER -p tcp -d 172.17.0.2 --dport 80 -j ACCEPT
次に iptables -t nat -nL
で表示される
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
MASQUERADE all -- 172.19.0.0/16 0.0.0.0/0
MASQUERADE all -- 172.18.0.0/16 0.0.0.0/0
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
iptables -t nat -A POSTROUTING -p tcp -d 172.17.0.2 --dport 80 -s 172.17.0.2 -j MASQUERADE
iptables -t nat -A DOCKER -p tcp -d 0.0.0.0/0 --dport 8080 -s 0.0.0.0/0 -j DNAT --to-destination 172.17.0.2:80
で追加はできます
これで 8080 ポートにアクセスしてみようとしたのですが、そもそも 8080 ポートが LISTEN していないのでダメでした (当然と言えば当然)
試しに -p ポートで正しく動作しているときに 8080 ポートが何のプロセスで動作しているか確認したところ docker-pr
というプロセスが 8080 で動作していました
なので、iptables を使う場合は同じようにプロセスもどうにかして起動させる必要があると思います
最後に
起動中のコンテナのポートをホストにバインドする方法を紹介しました
結果的には新しいコンテナを作ることで解決しましたが、本当は起動中のコンテナでやりたいところです
いろいろ調べてみたのですが、現状その方法はないかなと思います
確かにコンテナの概念的にも作り直せばいいだけなので、既存のコンテナの設定を変更できる必要はないのですがまぁできたら便利かなとも思います
0 件のコメント:
コメントを投稿