WSL2環境でHelmがスタックする問題について調べた
要約
- WSL2環境でHelmを実行すると環境によってはスタックする現象はDNS周りのおま環
前回のあらすじ
こちらの記事です。
issue
scrape
- なんかterraform applyしたら固まる
- Providerをデバッグして何が起こってみるか調べる
- 調べてみたらterraform provider内部処理の、さらに内部で使われてるhelmの処理に入った時にとまる
というダイジェストとなります。
結論
WSL2環境固有の問題だった
何が起こっているのか
自分の環境だと
WSL2の/etc/resolv.confが自動設定モード時(デフォルトは自動設定モード)
helm内部処理でChartのindex.yamlをURL指定で取得しにいく際に、どうやらDNS名前解決の処理周りでスタックしているようでした。
なので、以下のようにhelmコマンドで直接chartのURLを指定してrepoを追加しようとしても同じようにスタックします。
helm repo add metallb https://metallb.github.io/metallb
helm repo add agones https://agones.dev/chart/stable
「😭先にコマンド叩いて確認シテクレー、過去の自分」
解決策
こちらで書いてくれている事がまんま答えなのですが
/etc/resolv.conf
を変更し、CloudflareやGoogle Public DNSのnameserverにDNS問い合わせをするように設定する事です。
# Cloudflare
nameserver 1.1.1.1
# Google
nameserver 8.8.8.8
nameserver 8.8.4.4
こちらの対応を行った後なら
当該のterraform applyで固まる現象
も、helmコマンドでURL指定でchart repoを追加すると固まる現象
も両方解消します。
ですが,基本的にデフォルトの設定だとWSL2上で動作しているLinuxディストリビューションは
/etc/resolv.conf
が自動で設定されるようになっており、/etc/wsl.conf
の設定を変更しない状態で手動でファイルを編集しても、変更は削除されファイル毎上書きされます。
ですので、まずはこの部分の対応を行う必要があります。
WSL2の/etc/resolv.confの変更や設定について
以下のリンクで言及されていたり、
WSLのドキュメント(ネットワーク設定) のとおり /etc/resolv.conf は自動生成されるため、WSL再起動後にも変更した設定を維持したい場合は /etc/wsl.conf を編集したうえで、/etc/resolv.conf を個別に編集する必要があります。
ただし、WSLでは /etc/resolv.conf はシンボリックリンクとなっており、generateResolvConf = false 設定後に /etc/resolv.conf を直接編集した上でWSLを再起動すると既存のファイルも削除され、/etc/resolv.conf は 編集の有無によらず破棄されてしまうようです。
以下、公式docにも記載のあるとおり
[network]
generateResolvConf = false
の設定を対象のLinuxディストリビューション内の/etc/wsl.conf
に記載した後、再起動します。
コマンド例:
wsl -t Ubuntu-20.04
再起動が完了したら、再度ログインしたあとに/etc/resolv.conf
を編集します。
# Cloudflare
nameserver 1.1.1.1
# Google
nameserver 8.8.8.8
nameserver 8.8.4.4
と編集した後に、確認の為にhelm repo add
コマンドを流すと
helm repo add metallb https://metallb.github.io/metallb
"metallb" has been added to your repositories
chartのrepoがURL指定で追加できる状態となり、以下の構成をapplyしてもスタックすることなくapplyが完了するようになります。
なぜこのような現象がおきるのか?
以下のissueに理由が詳細に書かれています。
Info from the AUTHORITY/ADDITIONAL sections are mixed in the ANSWER section: this behaviour currently creates issues to other programs that need to process the answer.
AUTHORITY/ADDITIONALセクションからの情報がANSWERセクションに混合されます。この動作は現在、回答を処理する必要のある他のプログラムに問題を引き起こしています。
For example, in this issue geth cannot unmarshal the DNS message because it's greater then 512 bytes.
Geth is written in go, and go DNS client follows the RFC 1035 specification. This specification states that via UDP the maximum allowed message size is 512 bytes.
例えば、この問題では geth は DNS メッセージが 512 バイトより大きいので、unmarshal することができません。
gethはgoで書かれており、goのDNSクライアントはRFC1035の仕様に準拠しています。この仕様では、UDP経由での最大許容メッセージサイズは512バイトであるとされています。
The program works fine with all other DNS servers because ANSWER configured in the DNS server is correctly less then 512 bytes, but it fails with WSL that - with the addition of other information - creates an ANSWER section too big.
このプログラムは、DNSサーバに設定されたANSWERが正しく512バイト未満であるため、他のすべてのDNSサーバで正常に動作しますが、他の情報を追加して、大きすぎるANSWERセクションを作成したWSLで失敗します。
This strange behavior potentially impacts every RFC 1035 compliant library, and at least it impatcs every program written in go-lang and that uses the native DNS client library.
この奇妙な動作は潜在的にすべてのRFC 1035準拠のライブラリに影響を与え、少なくともgo-langで書かれ、ネイティブDNSクライアントライブラリを使用するすべてのプログラムを危険にさらすことになります。
そして、issueを読み進めていくと
この現象は特定のISPのDNSを使用する + WSLを使用するというケースでのみ発生するという事が読み取れます。
で、前回記事で調べた通り、
の箇所でも、内部で名前解決を行う際に上記の現象が発生し、goのランタイム上でスタックしてしまい最終的にHelmの実行自体が止まるというのが、事の顛末のようです。
Helm側のissueではこちらも記載があります。
つまり「おま環」!!
こ、これはもし自分が対応する側の立場だと想像すると・・・🤮
所感
WSLでも結構走りながら問題解決してる感じなんかぁ~と感じた次第です。
まったく関係ないんですが、Dockerに関する以下の画像を思い出しました。
😢
「自分の環境だとコードちゃんと動いたんです~」
😶 🧔
「はい、ではあなたの環境で動くのを確認したいので、今動作させて見せて頂けますか?」
😶 🧔
「・・・あ、なんかちゃんと動かないなぁ~・・・、今日はコードちゃん気分が悪いのカナァ・・・?」
😶💦 🧔
「・・・」
Discussion