Сегодня для многих день начался с проблем загрузки образов из регистра docker hub. Причина написана на странице, которую отдает регистр при попытке открыть его или запросить какой-либо образ.

Что случилось

Докер хаб больше не обслуживает клиентов из России, судя по всему разбор “откуда пришел клиент” идет по GeoIP. При попытке открыть главную страницу получаем такое сообщение:

Главная страница hub.docker.com

Тот же самый ответ показывается при попытке стянуть како-нибудь образ через консольную утилиту:

1
2
3
❯ docker pull docker
Using default tag: latest
Error response from daemon: error parsing HTTP 403 response body: invalid character '<' looking for beginning of value: "<html><body><h1>403 Forbidden</h1>\nSince Docker is a US company, we must comply with US export control regulations. In an effort to comply with these, we now block all IP addresses that are located in Cuba, Iran, North Korea, Republic of Crimea, Sudan, and Syria. If you are not in one of these cities, countries, or regions and are blocked, please reach out to https://hub.docker.com/support/contact/\n</body></html>\n"

Решение через VPN

Так как дома у меня есть несколько виртуальных серверов, которым, как и основному компьютеру, нужен доступ к хабу (не считая еще и ноутбука), то проще завернуть все запросы к хабу в VPN с выходным ip страны не из списка. Есть два основных домена которые нужно проверить registry-1.docker.io для получения и загрузки образов. Так же hub.docker.com для работы интерфейсом регистра. Каждый из них сейчас ссылается на три адреса внутри облака amazon.

Решение через mirror

Так же можно получить доступ через зеркало хаба. Для этого нужно указать его в настройках докера. Файл настроек лежит по следующим путям (взято из документации):

Операционная система и типПуть до файла настроек
Linux (основной)/etc/docker/daemon.json
Linux (пользовательский)~/.config/docker/daemon.json
WindowsC:\ProgramData\docker\config\daemon.json

Указывая тут путь ~/.config подразумевается, что внутри $XDG_CONFIG_HOME лежит именно такой путь. К корневому объекту нужно добавить свойство registry-mirrors, значение для которого будет массив ссылок на зеркала. Например:

1
2
3
4
5
{
  "registry-mirrors": [
    "https://mirror.gcr.io"
  ]
}

Если же будет использоваться регистр без https, то обязательно нужно будет указать параметр insecure-registries, в котором перечислить регистры с доступом без https:

1
2
3
4
5
6
7
8
9
{
  "registry-mirrors": [
    "https://mirror.gcr.io",
    "http://registy.lab.home:5006"
  ],
  "insecure-registries": [
    "registy.lab.home:5006"
  ]
}

Так же после всех этих изменений нужно либо перезапустить docker, либо (что лучше) выполнить reload конфигурации.

Параметр registry-mirrors на работает

У меня после указания такого параметра и перезапуска зеркала не заработали. При поиске проблем обнаружил две причины:

  1. очень старый клиент, нужно обязательно указывать параметр запуска /usr/bin/dockerd --registry-mirror https://mirror.gcr.io;
  2. до установки параметров была выполнена авторизация, и теперь нужно разлогиниться из всех регистров (docker logout hub.docker.com) и заново авторизоваться.

У меня случилась именно вторая проблема, видимо это способ не позволить “утечь” токену (или паролю?) в сторону зеркала.

Список зеркал (актуален на момент публикации)

Url зеркалаДополнительная информация
https://mirror.gcr.ioЗеркало от Google Cloud
https://quay.ioЗеркало от Red Hat
https://dockerhub.timeweb.cloudЗеркало от Timeweb Cloud
https://daocloud.ioКакое-то зеркало из Китая
https://c.163.comКакое-то зеркало из Китая
https://registry.docker-cn.comКакое-то зеркало из Китая

Важный совет по зеркалам!

Так как зеркало ВСЕГДА контролируется третьими лицами (даже если это известная компания), нужно ВСЕГДА сравнивать sha256 слепки образов на hub.docker.com и тех, что скачаны от стороннего регистра.