Ошибка получения Docker: превышено время ожидания при TLS рукопожатии

Вопрос или проблема

Я постоянно получаю это (Ubuntu 16.04 LTS):

$ docker pull nginx
Using default tag: latest
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout

Однако curl TLS работает нормально (кроме ошибки аутентификации):

$ curl https://registry-1.docker.io/v2/
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]}

И даже небольшая программа на Golang (для имитации docker) работает нормально:

package main
import (
    "fmt"
    "io/ioutil"
    "net/http"
)
func main() {
    resp, err := http.Get("https://registry-1.docker.io/v2/")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println("Got: ", string(body))
}

Pcap для запроса с тайм-аутом TLS docker:

reading from file docker-timeout.pcap, link-type LINUX_SLL (Linux cooked)
00:38:54.782452 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [S], seq 26945613, win 29200, options [mss 1460,sackOK,TS val 1609360 ecr 0,nop,wscale 7], length 0
00:38:54.878630 IP registry-1.docker.io.https > my-ubuntu.52036: Flags [S.], seq 2700732154, ack 26945614, win 26847, options [mss 1460,sackOK,TS val 947941366 ecr 1609360,nop,wscale 8], length 0
00:38:54.878691 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [.], ack 1, win 229, options [nop,nop,TS val 1609384 ecr 947941366], length 0
00:38:54.878892 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1609384 ecr 947941366], length 155
00:38:55.175931 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1609459 ecr 947941366], length 155
00:38:55.475954 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1609534 ecr 947941366], length 155
00:38:56.076327 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1609684 ecr 947941366], length 155
00:38:57.280103 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1609985 ecr 947941366], length 155
00:38:59.684095 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1610586 ecr 947941366], length 155
00:39:04.492102 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1611788 ecr 947941366], length 155
00:39:04.879468 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [F.], seq 156, ack 1, win 229, options [nop,nop,TS val 1611884 ecr 947941366], length 0
00:39:04.976015 IP registry-1.docker.io.https > my-ubuntu.52036: Flags [.], ack 1, win 105, options [nop,nop,TS val 947943890 ecr 1609384,nop,nop,sack 1 {156:157}], length 0
00:39:04.976073 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1611909 ecr 947943890], length 155
00:39:05.275922 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1611984 ecr 947943890], length 155
00:39:05.876104 IP my-ubuntu.52036 > registry-1.docker.io.https: Flags [P.], seq 1:156, ack 1, win 229, options [nop,nop,TS val 1612134 ecr 947943890], length 155

Что может быть не так?

net/http: TLS handshake timeout означает, что у вас медленное подключение к интернету. Значение по умолчанию для тайм-аута подключения слишком маленькое для вашей среды. К сожалению, в Docker нет настроек, которые позволяют изменить тайм-аут подключения. Вы можете попробовать создать собственное кеширование реестра в другом месте и потянуть образы оттуда.

У меня та же проблема. Ответ Азамата Хакимова дал мне правильное направление. Моя машина работает медленно, особенно при загрузке, когда я хочу запустить сервис. Поэтому короткий тайм-аут завершает мой запрос.

Вот мое решение:

docker pull $IMAGE || docker pull $IMAGE ||  docker pull $IMAGE || docker pull $IMAGE

Просто постоянно отправляйте запросы на сервер. Обычно вторая попытка удается.

Если вы используете частный реестр, вам нужно разместить сертификат для него в:

/etc/docker/certs.d/registryname/ca.crt

registryname будет изменено соответственно.

Также, измените размер MTU на 1300, это одна из вещей, которую я сделал для решения этой ошибки. Вероятно, вы уже сделали это для Reestr 1.

Команда для изменения MTU:

ip link set dev eth0 mtu 1300

Размер MTU важно проверить, чтобы избежать этой ошибки, если ваше интернет-соединение действительно хорошее.

У меня была аналогичная проблема при запуске docker run hello-world в первый раз, что привело к загрузке образа, используя https://registry-1.docker.io/v2/, что завершилось

docker: Error response from daemon: Get https://registry-1.docker.io/v2/: proxyconnect tcp: net/http: TLS handshake timeout.

После долгих поисков в интернете я обнаружил, что это происходит у некоторых пользователей с Ubuntu 18.04 и текущей версией Docker за прокси. Одно из решений – удалить все https-прокси конфигурации, оставив только http-прокси, чтобы заставить загрузку по http (не https).

Не знаю, в чем реальная причина.

(Кстати: у меня была аналогичная проблема “TLS handshake” с Composer и Packagist. Это было из-за отсутствующей cacert.pem, которая по умолчанию не предоставляется Ubuntu. Возможно, эта проблема с Docker движется в том же направлении?)

В моем случае мой сервер находился за NAT и прокси и был установлен на автоматическое определение прокси, что я сделал в текущем терминале, я экспортировал настройки прокси

root@k8master:~/runner# export http_proxy="http://192.168.10.208:3128"
root@k8master:~/runner# docker pull gitlab/gitlab-runner:latest
latest: Pulling from gitlab/gitlab-runner
7b722c1070cd: Pull complete 
5fbf74db61f1: Pull complete 
ed41cb72e5c9: Pull complete 
7ea47a67709e: Pull complete 
ae336ceeca88: Pull complete 
f9f79780e6cf: Pull complete 
67e622273f37: Pull complete 
bc84c40af701: Pull complete 
69e36092e9de: Pull complete 
Digest: sha256:b1f5387942aaaf8c220f6613a1e96ba2cbcb6c58a5e47ca0df8ae3216720a15e
Status: Downloaded newer image for gitlab/gitlab-runner:latest

Вы можете получить ошибку TLS handshake timeout, если ваш прокси Docker Daemon неправильно настроен.

# проверьте конфигурацию прокси для Docker Daemon
/etc/systemd/system/docker.service.d/proxy.conf

# примените изменения
sudo systemctl daemon-reload

# перезапустите сервис Docker
sudo systemctl restart docker 

Дополнительные сведения см. на странице https://docs.docker.com/config/daemon/systemd/#httphttps-proxy

Ни один из вышеуказанных ответов не может решить мою проблему, однако я обнаружил, что следующий https://github.com/helm/helm/issues/5220 работает для меня!

После этого изменения IT-отдел моей компании нашел решение. Я использовал переменную окружения https_proxy с https:// URL для нашего прокси. Это работает для большинства инструментов, которые мы используем, но не для Helm или более нового Kube. Кажется, у них есть проблемы с TLS handshake. Мы переключились с https:// на http:// URL (например, https_proxy=http://myproxy) и теперь все работает нормально.

В моем случае это сработало:
Я просто изменил интернет-соединение на другое. Оказалось, что мой текущий интернет-провайдер немного медленный.

Когда я переключил сетевое соединение на более быстрое, проблема разрешилась.

Множество возможных причин и решений уже здесь, но в моем случае это был docker daemon и его сетевая конфигурация:

docker network inspect 26d443779693
[
    {
        "Name": "bridge",
...
        "Options": {
...
            "com.docker.network.driver.mtu": "1500"
        },
...
    }
]

Вы можете видеть, что сетевой мост, созданный демоном, имеет MTU 1500, что не очень хорошо с VPN-решением, которое я использую.

Поэтому добавление:

{
    "mtu":1300
}

в /etc/docker/daemon.json помогло мне.

Что помогло мне, так это использование другого сетевого интерфейса. Вместо подключения через Ethernet (проводное соединение) я переключился на Wi-Fi. Проблема решена.

Кстати, я был на свежей установке Raspbian Stretch.

В моем случае помогло следующее: перетянуть/переназначить/отправить образ в мой частный реестр. Дело в том, что я запускаю dnsmasq на двух Raspberry Pi 1, и они просто кажутся слишком медленными для зеркала Docker Hub в Cloudflare.

1. Измените конфигурацию Docker Daemon

Так как значение MTU для сетевого моста docker0 управляется конфигурацией Docker, вам нужно установить MTU в конфигурационном файле Docker daemon (/etc/docker/daemon.json).

Вот как это сделать:

Откройте конфигурационный файл Docker Daemon:

Если файла нет, создайте его.

sudo nano /etc/docker/daemon.json

Добавьте или измените конфигурацию MTU:

Добавьте следующую настройку в файл (если она еще не там):

{
  "mtu": 1000
}

Если файл уже содержит другие настройки, просто добавьте строку “mtu”: 1000 внутри существующего объекта JSON. Убедитесь, что формат JSON является допустимым.

2. Перезапустите Docker
После сохранения изменений в daemon.json перезапустите Docker, чтобы применить новое значение MTU:

sudo systemctl restart docker

3. Проверьте изменения

Теперь проверьте, обновлено ли значение MTU для интерфейса docker0 до 1300:

ip a | grep docker0

Или вы можете проверить сетевой мост Docker, чтобы подтвердить:

docker network inspect bridge

Теперь вы должны увидеть, что “com.docker.network.driver.mtu” установлено на 1000 вместо 1500 в выводе.

В моем случае это сработало:
В Docker измените версию на 3.7, так как docker python 3.7 уже установлен в Docker

.

Ответ или решение

Теория

Ошибка docker pull: TLS handshake timeout чаще всего возникает в случае, когда ваше соединение с Docker Registry не завершилось за отведённое время. TLS (Transport Layer Security) обеспечивает безопасную передачу данных по сети, и если TLS-соединение не может быть установлено вовремя, происходит тайм-аут. Возможные причины этого могут быть связаны с несколькими факторами, такими как сетевая задержка, неправильная настройка прокси-сервера или проблемы с конфигурацией MTU в сетевых интерфейсах. Чтобы устранить эту проблему, необходимо рассмотреть все возможные причины и внести соответствующие изменения.

Пример

Вы столкнулись с ошибкой при попытке выполнить команду docker pull nginx на Ubuntu 16.04 LTS. К сожалению, команда завершилась ошибкой Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout. В то же время, попытка отправить запрос через curl завершилась успешно, что указывает на то, что проблема связана именно со взаимодействием Docker.

После анализа данных отладки, таких как pcap и тестовые программы на Go, становится понятно, что основная причина заключается в тайм-ауте при установлении TLS-соединения. Кроме того, вы отметили, что другие программы, такие как curl, справляются с аналогичным запросом, что указывает на проблему конфигурации или среду выполнения Docker.

Применение

Изменение MTU

Одной из часто встречающихся проблем является неправильная настройка MTU (Maximum Transmission Unit). На некоторых сетевых интерфейсах значение MTU по умолчанию (обычно 1500) может быть слишком большим, особенно в средах, где используется VPN. Изменение MTU может значительно повлиять на запуск Docker. Для изменения MTU выполните следующую команду:

ip link set dev eth0 mtu 1300

Можно также установить это значение в конфигурации Docker, добавив его в файл /etc/docker/daemon.json:

{
  "mtu": 1300
}

После внесения изменений перезапустите Docker:

sudo systemctl restart docker

Настройка Прокси

Если ваша система находится за прокси-сервером, убедитесь, что у вас правильно настроены переменные окружения http_proxy и https_proxy. Необходимо проверить, что конфигурации systemd для процесса Docker правильно определяют эти прокси:

/etc/systemd/system/docker.service.d/proxy.conf

После внесения изменений обязательно перезагрузите демона Docker для применения конфигураций:

sudo systemctl daemon-reload
sudo systemctl restart docker

Локальный зеркальный репозиторий Docker

Создание локального зеркального репозитория Docker может быть полезным решением в случае, если у вас низкая скорость соединения с Docker Hub. Локальное зеркало позволит вам загружать образы быстрее:

Документация по созданию зеркального репозитория Docker

Пробное Накачивание

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

docker pull $IMAGE || docker pull $IMAGE || docker pull $IMAGE || docker pull $IMAGE

Заключение

Ошибки, связанные с тайм-аутом TLS-соединения, требуют комплексного подхода для решения, включая изменения в конфигурации сети, настройке прокси и потенциал создания локальных зеркальных репозиториев Docker. Каждое из упомянутых решений может значительно улучшить производительность и стабильность системы, особенно в сложных сетевых конфигурациях или средах с ограниченной доступностью сетевых ресурсов.

Оцените материал
Добавить комментарий

Капча загружается...