やったことだけ書く備忘録

/etc/hostsから名前解決するluaライブラリ書いた

これは何



READMEにも書いたけど、openrestyを使っているとちょくちょくhostnameからIPを引けないケースがある。



resty.redis



content_by_lua_blockなどのディレクティブではnginx側のresolver指定を引き継ぐ(のかな?)で例えばresolver 8.8.8.8とかしてるとローカルのアドレスが引けなかったりする。localhostもダメで、127.0.0.1を指定しないといけない。

参考: Resolv hostname problem

対策として、 REDIS_HOSTみたいな環境変数を作り、nginx.confの先頭でenv REDIS_HOSTでロードして、luaからos.getenv("REDIS_HOST")しろみたいな方法がある。



ngx.balancer.set_current_peer(host, port)



dynamic upstreamをやるときに使うディレクティブだけど、接続するピアを指定するのにhostnameは許可されていない。

参考: Problems when the hostname is not an ip but a name defined in /etc/hosts (Docker)

docker



上にも関連しているけどこれが一番困った問題で、openrestyのコンテナとアプリケーションのコンテナをlinkしてapp01, app02, app03,...とロードバランシングする時、app01とかでIPを引けないのはキツイ。



ということで、/etc/hostsに書かれているホスト設定を読み込んでhostname -> IPを解決するライブラリを書いた。

ysugimoto/lua-local-resolver



使い方



読み込んで、ホストファイル指定でインスタンス化してresolve(hostname)を呼ぶだけ。ipv6もサポートしている(はず)。




local Resolver 
= require "local-resolver"
local resolver Resolver.new("/etc/hosts")

-- 
resolve local host
local ip 
resolver:resolve("localhost") -- 127.0.0.1
local app 
resolver:resolve("app01") -- docker linkしたコンテナのIP

-- resolve ipv6 local host
local ipv6 
resolver:resolve_v6("localhost") -- ::1
 


lua-resty-coreのissueにも簡単だぜ!って書かれてるけど特に誰もやって無さそうだったのでやってみた。実際実装は簡単だった。

hostsファイルはそう頻繁に変更されないと思うので、使う時はinit_by_lua_blockとかでグローバルに初期化しておいて、各ディレクティブで参照するのが効率が良さそう。openrestyを使う時は入れておくと良いと思います。

ちなみにこれはあくまでローカルの名前解決なので、外向きの時はlua-resty-dnsを使いましょう。

現場からは以上です。

« 前の記事 次の記事 »

0件のコメント