事象
alpine linuxを用いてdockerコンテナを作成しようとしたところ、突然下記のように出るようになってしまいCDNが死んでいるのかと思われました。
WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz: could not connect to server (check repositories file)
WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpindocにe/v3.9/community/x86_64/APKINDEX.tar.gz: could not connect to server (check repositories file)
ERROR: unsatisfiable constraints:
ところが早速検索でヒットしたこのあたりを見ると、CDNは死んでいない模様。
原因
どうやらdocker-alpineのissueでも昔から出ているようで、docker側のDNS解決の問題のようです。
Repository problem? #279
dl-cdn.alpinelinux.org errors #386
正確には、ホストOS側でデフォルトで有効になっているdnsmasqが原因であり、
dockerがデフォルト設定をコピーするとローカルにDNSがなくて困ってしまうので、パプリックなDNSを指定するようにしなければならないそう。
なので、docker buildしたイメージの中で、/etc/resolv.confが下記のようになる。
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
search xxx.jp
nameserver 8.8.8.8
nameserver 8.8.4.4
dockerのこちらのdocにそれっぽいことが書かれています。
解決策
手っ取り早くは、dockerを再起動する(ことによってデフォルトでパブリックなDNSを指定するようにdockerが設定されるたぶん)ようにissueには書かれていますが、私の環境では改善しなかったのでdockerを更新 + 端末ごと再起動 + イメージから作り直し をとりあえず試した段階で改善されました。
しかしそれでは気持ち悪いので下記の通り先人の知恵に乗っかりました。
「dockerのホストであるUbuntuでは、デフォルトでdnsmasq が有効になっていて、 /etc/resolv.confが下記のように自分を見る設定になっている。」
ならば /etc/resolv.conf に下記の通り書いてしまおうと。
nameserver 8.8.8.8
nameserver 8.8.4.4
を追記の上、Dockerを再起動すればDNS解決で失敗しなくなります。
参考にした記事
Repository problem? #279
dl-cdn.alpinelinux.org errors #386
alpine linuxのapk updateが失敗して動かなくなったときの解決法
Dockerコンテナ内から外部通信が向いたときにDNSが解決できない問題を解消する
systemd起動のDockerでdnsオプションを有効にする
Docker が使う DNS サーバの設定