TL;DR
~/.config/Code/User/settings.json
に
"remote.localPortHost": "allInterfaces"
を追加すると 172.17.0.1 でコンテナ間の通信ができる。
Remote Container だと 172.17.0.1 で他のコンテナに接続できない
普通に Docker を使っているときはコンテナの中から他のコンテナへのアクセスは 172.17.0.1
を使えばできました。
# コンテナ1 $ docker run --rm -p 9000:9000 python:3 python -m http.server 9000 172.17.0.1 - - [23/Feb/2022 06:59:03] "GET / HTTP/1.1" 200 - # コンテナ2 $ docker run --rm alpine/curl http://172.17.0.1:9000 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 987 100 987 0 0 647k 0 --:--:-- --:--:-- --:--:-- 963k <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".dockerenv">.dockerenv</a></li> <li><a href="bin/">bin/</a></li> <li><a href="boot/">boot/</a></li> <li><a href="dev/">dev/</a></li> <li><a href="etc/">etc/</a></li> <li><a href="home/">home/</a></li> <li><a href="lib/">lib/</a></li> <li><a href="lib64/">lib64/</a></li> <li><a href="media/">media/</a></li> <li><a href="mnt/">mnt/</a></li> <li><a href="opt/">opt/</a></li> <li><a href="proc/">proc/</a></li> <li><a href="root/">root/</a></li> <li><a href="run/">run/</a></li> <li><a href="sbin/">sbin/</a></li> <li><a href="srv/">srv/</a></li> <li><a href="sys/">sys/</a></li> <li><a href="tmp/">tmp/</a></li> <li><a href="usr/">usr/</a></li> <li><a href="var/">var/</a></li> </ul> <hr> </body> </html>
Remote Container を2つ立ち上げて同じようにすると Connection refused
になってしまいました。
172.17.0.1
だとつながりませんが、コンテナに割り振られた IP address である 172.17.0.2
だと接続できました。
# remote container 1 vscode ➜ /workspaces/exp $ python -m http.server 8000 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... # remote container 2 vscode ➜ /workspaces/exp_ubuntu $ curl http://172.17.0.1:8000 curl: (7) Failed to connect to 172.17.0.1 port 8000: Connection refused vscode ➜ /workspaces/exp_ubuntu $ curl http://172.17.0.2:8000 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".devcontainer/">.devcontainer/</a></li> </ul> <hr> </body> </html>
ちなみにローカルから Remote Container で動かしているコンテナにはアクセスできます。
これがアクセスできるなら 172.17.0.1
からも接続できそうなものですができません。
# remote container 1 vscode ➜ /workspaces/exp $ python -m http.server 8000 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 127.0.0.1 - - [23/Feb/2022 07:20:40] "GET / HTTP/1.1" 200 - # ローカル ~ $ curl http://localhost:8000 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".devcontainer/">.devcontainer/</a></li> </ul> <hr> </body> </html>
違い
ss
使って remote container の場合とそうでない場合を比較してみます。
# remote container で python -m http.server 8000 を動かした場合 $ ss -atn State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 511 127.0.0.1:8000 0.0.0.0:* ... # docker run --rm -p 8000:8000 python:3 python -m http.server 8000 で動かした場合 $ ss -atn | grep 8000 LISTEN 0 4096 0.0.0.0:8000 0.0.0.0:* LISTEN 0 4096 [::]:8000 [::]:*
remote container だと 127.0.0.1
になっていて 0.0.0.0
でない。どうやらここが原因のようです。
調べてみると VSCode 側の設定でデフォルトだと 0.0.0.0 でなく localhost で listen する設定になっているとのこと。
設定を変えると無事に remote container 間で 172.17.0.1 経由で通信することができました。
# remote container 1 vscode ➜ /workspaces/exp $ python -m http.server 8000 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 127.0.0.1 - - [23/Feb/2022 08:20:34] "GET / HTTP/1.1" 200 - # remote container 2 vscode ➜ /workspaces/exp_ubuntu $ curl http://172.17.0.1:8000 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".devcontainer/">.devcontainer/</a></li> </ul> <hr> </body> </html>