Вопрос или проблема
С экземпляра 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
для мониторинга сетевого трафика:
- Установите tshark внутри контейнера.
- Запустите:
tshark -i any
- После этого сделайте запрос извне на ваш контейнер. Вы должны увидеть, приходят ли пакеты в контейнер и как на них отвечает ваше приложение.
Если вы видите пакет RST
, это означает, что пакет был отклонен, и вы вновь сталкиваетесь с проблемой настройки интерфейсов.
5. Окончательная проверка
После внесения всех изменений убедитесь, что вы перезапустили контейнер и проверили доступность сервиса:
docker restart b56fa0d76d5c
curl 'http://localhost/health'
Если все сделано правильно, вы должны получать корректный ответ от сервиса.
Заключение
Ошибка curl (56) Recv failure: Connection reset by peer
может быть исправлена с помощью проверки конфигурации приложения, состояния контейнера и настройки сетевых интерфейсов. Убедитесь в том, что приложение прослушивает нужные порты на подходящих интерфейсах и не блокируется настройками безопасности.