概要
WSL で terraform の実行が著しく遅かったため、/etc/resolv.conf に記載されているネームサーバを変更して解決しました。解決に至る経緯、対処方法についてご紹介します。
環境
- Windows 11
- WSL2
- Ubuntu-20.04
原因究明へのヒント
terraform plan を実行したところ、以下のようなエラーが出ました。これが terraform が遅い問題の本質的原因でした。
Error: retrieving Subscription (Subscription: "abcde012-1234-5678-abcd-0123456789ab"): subscriptions.Client#Get: Failure sending request: StatusCode=0 -- Original Error: Get "https://management.azure.com/subscriptions/abcde012-1234-5678-abcd-0123456789ab?api-version=2021-01-01": dial tcp: lookup management.azure.com on 172.17.64.1:53: cannot unmarshal DNS message
IPアドレス 172.17.64.1 は /etc/resolv.conf に記載されているネームサーバのものですが、ここからの返答が適切に処理できない感じです。ちなみに Ubuntu からインターネットへの接続に問題はなく、たとえば www.google.com に対して ping の応答は返ってきていました。
とはいえ、ネームサーバを 8.8.8.8 に変更してみたところ、上記エラーは出なくなり、また terraform plan も想定通りの速度で実行完了するようになりました。
WSL で /etc/resolv.conf の永続化
WSL の起動設定を何もしていなければ、イーサネット アダプター vEthernet (WSL) のIPv4アドレスの値になるはずです。起動時に自動生成してくれます。これは、上記のように手動でネームサーバを変更したとしても、WSL を再起動したら変更されてしまうということを意味します。そこで自動生成を止めます。
sudo vi /etc/wsl.conf
[network]
generateResolvConf = false
これで自動生成しなくなったので万事めでたしかと思い WSL を再起動してみます。
wsl --shutdown
wsl
cat /etc/resolv.conf
cat: /etc/resolv.conf: そのようなファイルやディレクトリはありません
おや?ファイルが消されてしまいました。おそらく内部的には
- イーサネット アダプター vEthernet (WSL) の IPv4アドレスを取得
- /run/resolvconf/resolv.conf に上記アドレスを nameserver の値として設定
- /run/resolvconf/resolv.conf /etc/resolv.conf にシンボリックリンクを張る
を起動時に行い、終了時に
- /etc/resolv.conf を unlink する
- /run/resolvconf/resolv.conf を削除
を行っているのではないかと思います。そして、generateResolvConf を false に設定したことで起動時の処理は行われなくなったけど、終了時の処理は実施されてるのではないかと推察されます。そこで起動時に /etc/resolv.conf を欲しい状態で作成するように設定します。
sudo vi /etc/resolv.conf.dist
nameserver 8.8.8.8
※ 8.8.8.8 の値はお好きなものにしてください。
sudo vi /etc/wsl.conf
[boot]
command = "cp -rup /etc/resolv.conf.dist /etc/resolv.conf"
[network]
generateResolvConf = false
起動時の処理は [boot] ブロックの command の値に実行したいコマンドを記載することで実現できます (複数のコマンドを実行したい場合には ; (セミコロン) 区切りで記載します)。これで /etc/resolv.conf を固定化することに成功しました。
おわりに
ちなみに Google 先生に "wsl terraform slow" で問い合わせると、Very slow on Ubuntu/WSL2 due to PATH containing entries from Windows という Github issue に辿り着きます。WSL では何も設定していないと、Windows コマンドも実行できるように環境変数 PATH が長大になります。これに起因しているということでしたが、PATH の値を手動で設定し直して文字数を小さくしても、事態はなにも改善しませんでした。