dockerコンテナの中でホストマシンのIPアドレスを取り出す


結論
cat /etc/hosts | awk 'END{print $1}' | sed -r -e 's/[0-9]+$/1/g'

docker-composeでとりあえず普通にコンテナどうしの通信

  • Dockerfileの中でEXPOSE 80みたいな感じでポートを指定
  • docker-compose.ymlにhostname: hogeでホスト名をつける
  • hoge以外のコンテナからcurl http://hoge/

みたいな感じでしょう

コンテナではなくホストマシンと通信

ホストマシンのホスト名を指定すればよいですね
curl http://hostmachine/

でも特に開発環境などにおいては、いつもホストマシンにホスト名を設定しているわけではありません。
それなら開発環境におけるホストマシンのIPアドレスを指定すれば解決できそうですが、
そもそもいつもホストマシンのIPアドレスが同じとは限りません。
ルーターの設定次第で会社では10.XX.YY.ZZだったり家では192.168.XX.YYだったりします。
DHCPならなおさらですね。

どこでも同じ環境が構築できることがウリのコンテナですから、なるべく環境に固有の値はファイルに書いたりしたくないです。

そもそも別に外のネットワークにおけるホストマシンのIPアドレスが必要なわけではありません。
dockerの内部ネットワークにおけるホストマシンのIPアドレスが知りたいのです。

コンテナからホストのIPアドレスを調べる

やっと本題です。
dockerの内部ネットワークについてはいろいろ深い話があるので興味がある人はぜひ公式ドキュメントを読むことをおすすめします。

今回はコンテナ内で余計なもの(iputilsとか)をインストールすることなく、さくっとホストのIPアドレスを知る方法を紹介します。

/etc/hosts

コンテナの中でipアドレスとかホスト名の情報が書いてあるファイルといえばこいつでしょう

# cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  0c50f3b8bcb9

この一番下のやつがコンテナ自身の内部IPです。
dockerの内部ネットワークではデフォルト(特に設定しなかった場合)は172.XX.YY.ZZみたいなアドレスが振られます。
こいつが厄介でいつもいつも同じサブネットであるとは限りません。
おそらくデフォルトではホストマシンはゲートウェイなので172.XX.YY.1でホストマシンにアクセスできそうです。

ホストのIPアドレスを取り出す

シェル芸の出番です

# cat /etc/hosts | awk 'END{print $1}' | sed -r -e 's/[0-9]+$/1/g'
172.17.0.1

解説

awk 'END{print $1}'
最後の行の1列目を取り出す

sed -r -e 's/[0-9]+$/1/g'
末尾の数値を1に書き換え

もっと良い方法(正しい方法)がありましたらぜひコメントでもよいので教えてください。

追記

sed -e 's/[0-9]\+$/1/g' でもいけるっぽい

使用例

ホストの80番にHTTPのGETを投げる

curl http://`cat /etc/hosts | awk 'END{print $1}' | sed -r -e 's/[0-9]+$/1/g'`:80