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
が定義されています。ここでのeth0
がhostname
で定義されているホスト名に対してのIPアドレスです。
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アドレスを引っ張り込んでくるコマンド(例)は次のとおりです。
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 構成するときに必須になります...。