пятница, 18 октября 2024 г.

Failed to establish a new connection: [Errno -2] Name does not resolve

Оптимизировал размер образа, который построен на базе Google Cloud SDK и столкнулся с ошибкой локальной сборки после переключения с google/cloud-sdk:497.0.0-slim на google/cloud-sdk:497.0.0-alpine:

Beginning update. This process may take several minutes.
ERROR: gcloud crashed (ConnectionError): HTTPSConnectionPool(host='dl.google.com', port=443): Max retries exceeded with url: /dl/cloudsdk/channels/rapid/components-2.json (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f2c42715950>: Failed to establish a new connection: [Errno -2] Name does not resolve'))

If you would like to report this issue, please run the following command:
  gcloud feedback

To check gcloud for common problems, please run the following command:
  gcloud info --run-diagnostics

Тестовый Dockerfile выглядит так:

FROM google/cloud-sdk:497.0.0-alpine

RUN gcloud components install gke-gcloud-auth-plugin && \
    gke-gcloud-auth-plugin --version

В самом контейнере dl.google.com прекрасно резолвится:

$ docker run --rm -it google/cloud-sdk:497.0.0-alpine nslookup dl.google.com
Server:         172.16.0.10
Address:        172.16.0.10:53

Non-authoritative answer:
Name:   dl.google.com
Address: 142.251.208.110

Non-authoritative answer:
Name:   dl.google.com
Address: 2a00:1450:400d:802::200e

Сначала грешил на проблемы с IPv6 - поскольку в ответе есть и IPv4 и IPv6, то приложение может пытаться соединяться на IPv6 адрес вместо IPv4. Это можно решить порядком сортировки ответов в резолвере, но Alpine Linux использует библиотеку Musl вместо Libc и не получится подкрутить приоритет в /etc/gai.conf.

В процессе гугления наткнулся на заметку в которой описывались проблемы с DNS в Alpine Linux:

For instance, musl performs parallel querying of name servers and can’t switch to sequential one like glibc. So if you start the Docker daemon with --dns=172.17.42.1 --dns=10.0.2.15, where the former is the local DNS server and the latter is used for external DNS resolving, there is no guarantee that 172.17.42.1 will be tried first, which will lead to unforeseen failures.

После этого я убрал все адреса DNS серверов кроме первого из /etc/resolv.conf и повторил сборку - всё прошло без ошибок. Перебирая по очереди сервера из списка я нашёл один который выдавал ошибку

$ awk '/^nameserver/ {print $2}' /etc/resolv.conf | xargs -I{} docker run --rm --dns {} google/cloud-sdk:497.0.0-alpine nslookup google.com

Server:         172.16.0.10
Address:        172.16.0.10:53

Non-authoritative answer:
Name:   google.com
Address: 142.251.39.14

Non-authoritative answer:
Name:   google.com
Address: 2a00:1450:400d:80c::200e

Server:         172.16.0.11
Address:        172.16.0.11:53

Non-authoritative answer:
Name:   google.com
Address: 142.251.39.14

Non-authoritative answer:
Name:   google.com
Address: 2a00:1450:400d:80c::200e

Server:         192.168.1.1
Address:        192.168.1.1:53

** server can't find google.com: NXDOMAIN

Non-authoritative answer:

Два первых DNS сервера выдаёт рабочий VPN. Если его отключить, то остаётся только третий и тогда всё начинает работать. При подключённом VPN блокируются запросы к DNS серверам, которые не являются частью рабочей инфраструктуры.

В общем это знание стоило мне пару часов времени и возможно кому-то оно их сэкономит.

Комментариев нет:

Отправить комментарий