varnishのresolves to too many addressesを解決する
TLDR
- libvmod-dynamicを追加でインストールする
- ホワイトリスト設定を忘れない
varnishの仕様
varnishでは基本的にバックエンドとの対応付けは1対1が基本であり、複数IPなどには対応することができない。
(注:ドメインなどを記載した場合はコンパイル(起動)時にDNSを引いた際のIPアドレスを利用しているっぽい)
つまりbackendに"s3-ap-northeast-1.amazonaws.com"のような複数のAレコードを持つようなものを指定しようとすると、resolves to too many addresses
と怒られる1。
varnishのドキュメントやggってみるとgoto
というライブラリが出てくるが、これはシェアウェアのバンドルなので利用できない。
調べてみるとgotoとは別にlibvmod-dynamicというモジュールがあったのでこちらを利用する。 libvmod-dynamicはバックエンドに接続する際にDNSを引くという動作をする。つまりDNSレコードが変わるような環境でも利用できる。 また、複数のレコードがある場合にも問題なく利用できる。
環境
varnish: 6.0.10(yumからインストール)
構成としてはALBでSSL終端しVarnishが受けて各種バックエンドやS3などに振り分けるといったもの(画像書くのが面倒だった)。 varnishはリバースプロキシとして利用しており読み替えでs3を呼び出す。 s3は静的ファイルが主においてありcssなどを要求する際に利用される。
s3のDNSのAレコードは8つあり、しかもおよそ5秒ごとに変更されるためTTLを長めにしてしまうとアクセスできなくなるので注意(2022/10/28現在)。
構築
- 必要なライブラリを追加する
sudo yum install getdns-devel varnish-libs-devel
- リポジトリにアクセスし、varnishのバージョンと同じブランチを選択する。今回は6.0。
- CodeをクリックしDownload ZIPのリンクをコピー
- wget する。今回は
wget https://github.com/nigoroll/libvmod-dynamic/archive/refs/heads/6.0.zip
- unzip
unzip 6.0.zip
- ディレクトリに入りmake&install
./autogen.sh ./confugure make
- 問題なく
make
できたらsudo make install
- 完了を確認したらvclの設定へ
varnish vmod-dynamicの使い方
基本的にはsrc/vmod_dynamic.vcc
に書いてあるのでそれを見て設定する。
今回は以下のように設定した。
s3.vcl
import dynamic; probe www_probe { .window = 5; .initial = 7; .threshold = 3; .interval = 5s; } acl www_acl { "0.0.0.0/0"; } sub vcl_init { new s3 = dynamic.director( port = "80", probe = www_probe, whitelist = www_acl, ttl = 1s); }
default.vcl
set req.backend_hint = s3.backend("s3-ap-northeast-1.amazonaws.com");
ここで重要なのは、whitelist
の設定である。
vmod_dynamic.vcc
には「ACLに一致する名前解決結果のみが使用される」と記載があるので、これを記載しないと動作しないようである。
今回はAWSがAWSIPからランダムに(実際はラウンドロビンか何か)IPを変更しているため設定値を0.0.0.0/0
としている2が、利用IPの範囲が決まっていれば192.168.0.0/31
のように範囲指定すべきである。
設定例では"192.168"/24;
となっているのだがこの場合は"192.168.0.0/24"となるんだろうか…?この書き方なら/16
が適切な気がするんだけども。
また、TTLは基本的にはDNSの設定値と同様か少し小さい値を設定しておけば良い。
今回はAWSの設定に振り回されないように1sec
にしてあるが、普通は5m
でも1h
でもいいと思う。
反映
sudo systemctl restart varnish
で反映させる
再起動してもいいかも。
気になること
- ドキュメント記載の
"192.168"/24;
を設定したときの許可範囲 - www_probeの各パラメータの適切さがそもそもわかっていない
- varnishのドキュメントとlibvmod-dynamicのドキュメントではinitialの定義が違うんだけどlibvmod-dynamicが間違ってる?
varnishわからないことだらけなので誰か教えて下さい。。。