Docker上のruby:alpineにて、bundlerがrails-assets.orgに繋がらなくなっていた
タイトルどおりではあるが、急にbundlerが外部と疎通できなくなっていた(´・ω・`)
ほんの数日前までは特に問題なく動いていたんですが、さて個人の仕事をやらねばなと腰をあげたところ食らってしまい、起きているのがシンドい時間まで突入してしまいました。
環境はWSL2 Ubuntu上の、ruby:2.6.2-alpine
docker-compose run --rm {service} bundle install
で動かすと発生しました。
Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from https://rails-assets.org/
うーむ。まあエラーの内容通り外部と疎通できないのが要因だろうけれども。curlなりpingなり、存在しているところに飛ばしてもbad accessが発生してる。
調査のためにdigいれようと、apkでbind-toolsを引っ張ろうとしてもコケるので、コンテナ内部でなにか名前解決に問題が発生しているような気がしている。あ、IPアドレスで疎通できるかの確認してなかった(´・ω・`)
どちらにせよ、bundleの問題ではないと判断。まあこういうときは一度コンテナをビルドし直すと解消することがこれまで多かったので、今回もザクッとつくりなおしてみることにした。
docker-compose build --no-cache {service}
実行するとすくなくともapkは正常に走っていることがわかる。コンテナ内部の問題ではなさそう
doker-compose run --rm {service} bundle install
どうやら正常に名前解決できるようになった模様。
Bundle complete! 63 Gemfile dependencies, 150 gems now installed. Bundled gems are installed into `/usr/local/bundle`
原因が不明だとちょっと気持ち悪い(´・ω・`)
いろいろと調べてみると、resolve.confにnameserver 8.8.8.8
すると解決するという話がちらほらとあるわけで。名前解決になにか問題があることは理解したんですが、なぜ急に動かなくなったかは不明でした。
ちょっと深堀りしてみたら、ひとつ気になるものを見つけたんですが。
https://qiita.com/frost-tb-voo/items/fcc0c0fe7561b9101bf4
何も設定していない状態の dockerd では,ホストの /etc/resolv.conf をマスク(上書き)したファイルがコンテナ内部の /etc/resolv.conf として mount される.
WSL2では、resolve.confにはWSLホストであるWindowsIPアドレスが入ってるんですよね。確か。WSLでX Window試してみたことある人はわかると思うんですが、WSL起動ごとにこのresolve.confのIPアドレスが変わるわけですよ。
https://qiita.com/SoraKumo/items/388a1315a6bdc16b4d2e
つまり、dockerのコンテナ生成したタイミングでは、その時のWSL側のresolve.confがコピーされて使われる。しかし、WSLを起動し直すなどしてWSLのIPが変わってしまうと、その場合でもDockerのコンテナ側のresolve.confには古いIPが記録されており、ここに名前解決をしにこうとする。当然そのIPで応答するやつはいないので、解決できずに死ぬ。という動きが考えられるかもしれない。
普段再現しないのは、そもそもWindowsPCを終了することがほとんどなく、スリープ運用しているからで説明はつく。
まあ、状況から考えた仮説でしかないので、実際に何が問題としてあったかはわからずじまい(´・ω・`)
先にnameserver 8.8.8.8追加を試すべきだった。
まあ仮説どおりだとするとまた再現しそうな気はしているので、その時調べればいいかなというお気持ちです。