curl (56) Ошибка приема: соединение сброшено соперником – при обращении к контейнеру docker [закрыто]

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

С экземпляра AWS EC2 (который запускает docker) я пытаюсь curl мой веб-сервис, размещенный в контейнере docker.

Учитывая:

[ec2-user]$ docker ps
ID КОНТЕЙНЕРА        ИЗОБРАЖЕНИЕ                                                                КОМАНДА                  СОЗДАНО             СТАТУС              ПОРТЫ                                        ИМЯ
b56fa0d76d5c        $REGISTRY/$WORK/metrics:v0.1.0   "/bin/sh -c 'sh /root"   3 минуты назад       Запущен 3 минуты        0.0.0.0:80->80/tcp, 0.0.0.0:9000->9000/tcp   insane_leakey

Я могу обратиться к веб-сервису изнутри контейнера:

[ec2-user]$ docker exec -it b56fa0d76d5c bash
root@b56fa0d76d5c:/# curl 'http://localhost/health'
Запрос не содержит обязательного параметра запроса 'apiName' 

Но я не могу обратиться к нему с хоста:

[ec2-user]$ curl 'http://localhost/health'
curl: (56) Ошибка получения: Соединение сброшено удаленной стороной

Я посмотрел на этот подробный ответ на эту ошибку curl, но я не уверён, как диагностировать эту проблему.

Сброс соединения с контейнером Docker обычно указывает на то, что вы определили сопоставление портов для контейнера, которое не указывает на приложение.

Итак, если вы определили сопоставление 80:80, проверьте, что ваш процесс внутри экземпляра docker действительно работает на порту 80:

netstat -an|grep LISTEN

Вы получаете сброс, так как ‘прокси’ Docker перехватывает соединение, пытается подключиться к процессу внутри контейнера, терпит неудачу и сбрасывает соединение.

Вы можете исследовать это, установив tshark в контейнер и затем выполнив tshark -i any:

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

root@618910b515f0:/code# tshark -i any
Запуск от имени пользователя "root" и группы "root". Это может быть опасно.
Перехват на 'any'
tshark: cap_set_proc() не удалось вернуть: Операция не разрешена

tshark: cap_set_proc() не удалось вернуть: Операция не разрешена

    1 0.000000000   172.18.0.1 → 172.18.0.3   TCP 76 45844 → 8001 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=820044004 TSecr=0 WS=128
    2 0.000019457   172.18.0.3 → 172.18.0.1   TCP 56 8001 → 45844 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0

Сетевой пакет поступил, но он ответил RST, что означает, что он был отклонён.


Скорее всего, вы прослушиваете на 127.0.0.1, а не на 0.0.0.0 – всех IP-адресах. Вы можете проверить это, запустив netstat -tulpn

.

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

Ошибка curl (56) Recv failure: Connection reset by peer, возникающая при попытке обратиться к веб-сервису, размещенному в контейнере Docker, может быть вызвана несколькими причинами. Давайте разберем проблему детально и предложим возможные пути решения.

1. Причина ошибки

Суть ошибки заключается в том, что при попытке подключения к сервису в контейнере, Docker прокси не может установить соединение с внутренним процессом, что приводит к сбросу соединения. Это может произойти по следующим причинам:

  • Приложение внутри контейнера не слушает на ожидаемом порте.
  • Приложение настроено на прослушивание только по локальному интерфейсу (например, 127.0.0.1), в то время как Docker ожидает подключения по 0.0.0.0.

2. Проверка состояния контейнера

Для начала необходимо убедиться, что приложение внутри контейнера действительно запущено и слушает на ожидаемом порте. Для этого выполните следующие шаги:

a. Проверка запущенных контейнеров

docker ps

Убедитесь, что ваш контейнер запущен и правильно отображает состояние.

b. Подключение к контейнеру

Подключитесь к вашему контейнеру для проверки состояния приложения:

docker exec -it b56fa0d76d5c bash

c. Проверка активных соединений

После подключения к контейнеру выполните команду:

netstat -tulpn | grep LISTEN

Эта команда покажет, какие порты находятся в состоянии прослушивания. Убедитесь, что ваше приложение слушает на интерфейсе 0.0.0.0 (или на нужном порту).

3. Изменение конфигурации приложения

Если ваше приложение действительно слушает только на 127.0.0.1, это может быть источником ошибки. Вам нужно изменить конфигурацию приложения, чтобы оно перенаправляло соединения на 0.0.0.0. Это позволит внешним запросам проходить через Docker.

4. Проверка маршрутизации сетевого трафика

Вы можете использовать tshark для мониторинга сетевого трафика:

  1. Установите tshark внутри контейнера.
  2. Запустите:
tshark -i any
  1. После этого сделайте запрос извне на ваш контейнер. Вы должны увидеть, приходят ли пакеты в контейнер и как на них отвечает ваше приложение.

Если вы видите пакет RST, это означает, что пакет был отклонен, и вы вновь сталкиваетесь с проблемой настройки интерфейсов.

5. Окончательная проверка

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

docker restart b56fa0d76d5c
curl 'http://localhost/health'

Если все сделано правильно, вы должны получать корректный ответ от сервиса.

Заключение

Ошибка curl (56) Recv failure: Connection reset by peer может быть исправлена с помощью проверки конфигурации приложения, состояния контейнера и настройки сетевых интерфейсов. Убедитесь в том, что приложение прослушивает нужные порты на подходящих интерфейсах и не блокируется настройками безопасности.

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

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