LoginSignup
1

More than 3 years have passed since last update.

[Heroku] Private Space 内で自分自身の IPアドレスを特定する方法 [heroku-18 stack]

Last updated at Posted at 2019-04-16

2日間、起きている間の80%はHeroku用のbuildpack作ったり、負荷テストツールを動かすようにしてみたり、無理やりslugに入れて動かしてみたり無茶なことをしていたしょっさんです、こんばんわ。

今日、これからするお話はPrivate Space限定です。


2019/4/17(水) 追記

HEROKU_PRIVATE_IP 環境変数で定義されてるって教えてもらいました...。ああん、もう Devcenter 多くて困っちゃう。以下、元のネタです。こちらの紛糾ぶりも是非どうぞ。


自分自身のIPアドレスが知りたい!

タイトルからして、なにか悪いことをしようとしているのかと思ったらおおまちがいです。ひじょーに至極まっとうな理由があります。このコンテナ時代の世の中、自分自身に定義されている hostname と実際に外部からアクセスされるIPアドレスがまったく異なることは、よくあることです。

「それがどうした」「別にいいじゃないか」

そんなふうに考えていた時期が、俺にもありました(画像略)

Java RMIなどでは、自分自身のIPアドレスを指定して、待ち受けて起動するような仕様になっているものがあります。何も指定しないと、デフォルトではhostnameで解決されたIPアドレスを指定するようです。

実はHerokuではhostnameで設定されているホスト名が、コンテナ内部だけで利用されているホスト名のようで、コンテナの外からアクセスされるためのIPアドレスではない、内部用のIPアドレスが返ってきてしまいます。するとどうでしょう。別のDynoからそのアドレスで起動しているコンテナに対して接続する場合「ヒャッハーこのIPアドレスはnestしてやがるぜ!!」と言われて接続を拒否されます。切ないです。本人は受け入れる準備万端なのに、別のなにかに拒絶されてしまうんです。こんな悲しいことがあるでしょうか。

さて、じゃぁどうするかというと、ipコマンドで無理やり引っ張ってきます。HerokuのDyno(Heroku-18 Stackにおいて)では、IPアドレスが 3つ定義されています。例えば heroku run ip addr とでも実行すると、次のような結果(Private Spaceの場合)が返ってきます。lo,eth0,eth1が定義されています。ここでのeth0hostnameで定義されているホスト名に対してのIPアドレスです。

bash
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether b2:b5:e8:d2:fb:71 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.128.2/30 scope global eth0
       valid_lft forever preferred_lft forever
8: eth1@if4: <BROADCAST,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 06:94:0d:8c:48:2a brd ff:ff:ff:ff:ff:ff
    inet 10.0.134.102/20 scope global eth1
       valid_lft forever preferred_lft forever

したがって、われわれは、このeth1のIPアドレスを取得して、サーバーの Listen Address に設定してあげれば良さそうです。
ということで、Heroku上でeth1のIPアドレスを引っ張り込んでくるコマンド(例)は次のとおりです。

bash
ip -f inet -o addr show eth1 |awk '{print $4}' | cut -d '/' -f 1

Heroku Private Space DNS Service Discoveryを利用して、Private Space内部で特定の通信を行うとき、Private Space内のプライベート公開IPアドレスでLISTENしないとならない場合には、このような形でIPアドレスを引っ張ってみてください。幸せになれると思います。


例えば、Private Space内で JMeter で Master/Slave 構成するときに必須になります...。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1