ポートマッピングを使わずにDockerコンテナにアクセスする方法
この記事はDocker Advent Calendar 2018の16日目になります。
はじめに
記事書いといてアレなんですが
基本的にはポートマッピングを使ったほうがいいと思うので、あんまり使い所はないかもしれません。
自分の場合は、とあるライブラリでWebSocketのコネクションがどうしても上手くいかず
今回の方法に行き着いた感じです。
どこかで誰かの参考になれば幸いなので記事にしたいと思います。
Linuxの場合
コンテナ起動
例として、apacheコンテナを使用していきます。
以下のdocker-compose.ymlを用意して、コンテナを起動します。
$ vi docker-compose.yml version: '3' services: web: image: httpd:2.4-alpine expose: - "80" network_mode: host # ホストのネットワークでコンテナを実行 $ docker-compose up -d
network_mode: host
とすることで、ホストのネットワークに対してポート番号をexposeするため、マッピング無しでアクセス可能となります。
この設定はLinux環境限定のようです。
確認
$ docker ps --format "table {{.Image}}\t{{.Ports}}\t{{.Names}}" IMAGE PORTS NAMES httpd:2.4-alpine test_web_1 $ curl http://localhost <html><body><h1>It works!</h1></body></html>
ポートマッピングしていませんが、アクセスできました。
Docker for Windowsの場合
Hyper-VでDockerデーモンが動いている都合上、仕方ないのかもしれませんが、
network_mode: host
は使えないのでネットワークの設定が必要になります。
コンテナ起動
以下のdocker-compose.ymlを用意して、apacheコンテナを起動します。
$ vi docker-compose.yml version: '3' services: web: image: httpd:2.4-alpine expose: - "80" networks: my_network: ipv4_address: 172.99.0.2 # コンテナのIPを指定 networks: my_network: driver: bridge ipam: driver: default config: - subnet: 172.99.0.0/24 # ネットワークアドレスを指定 $ docker-compose up -d
ネットワークアドレスは172以外は自由に設定できます。
他のdocker networkで使われていないものを指定してください。
ルーティングテーブル設定
Docker for Windowsでは、デフォルトで以下の構成になっているようです。
- 仮想スイッチ:10.0.75.0/24
- DockerNAT:10.0.75.1
- MobyLinuxVM:10.0.75.2
この内のMobyLinuxVMに、先ほどのネットワークアドレスをルーティングします。
$ route -p add 172.99.0.0/24 10.0.75.2 ※管理者権限のコマンドプロンプトで実行
ルーティングテーブルを確認
$ route print
設定を削除する時はこちら
$ route delete 172.99.0.0
この設定については、以下の記事が大変参考になりました。 qiita.com
確認
$ docker ps --format "table {{.Image}}\t{{.Ports}}\t{{.Names}}" IMAGE PORTS NAMES httpd:2.4-alpine 80/tcp test_web_1 $ curl http://172.99.0.2 <html><body><h1>It works!</h1></body></html>
アクセスできました。
Docker for Macの場合
すいません。分かりませんでした。
ただ、Macの場合はWndowsと違ってDocker for MacとVirtualBoxが共存できるので
VirtualBox上のDockerで network_mode: host
を使えば良いかなと思います。
最後に
Macについては思いっきり手抜きとなってしまいましたが、
そもそも今回の記事はDocker for WindowsとVirtualBoxが共存できないことがきっかけになっています。
前述のWebSocketの件で最初は仕方なくVagrantで環境構築したんですが
DockerとVagrantを切り替えるために毎回PCを再起動する状況にノイローゼ寸前だったので、必死に調べた結果となります。
*1
何卒ご容赦ください。
以上、現場からでした。