Назад | Перейти на главную страницу

Перенаправить запросы localhost в контейнер Linux

Я запускаю несколько контейнеров Linux, каждый из которых запускает веб-приложение, на моем хосте Ubuntu. Для доступа к веб-приложениям я использую iptables переадресовать порт:

sudo iptables -t nat -A PREROUTING -p tcp --dport <port> -j DNAT --to-destination #<container_ip>:<port>

Это хорошо работает, если трафик идет из вне моего хозяина. Если запрос выполняется локальным хостом, он не работает:

 curl <host_ip>:<port>       #works (from outside the host)
 curl <container_ip>:<port>  #works (from inside the host)
 curl 127.0.0.1:<port>       #doesn't work (from inside the host)

Я понимаю, что пакет, приходящий с localhost, не проходит через правило DNAT iptables, и поэтому он не работает. Есть ли способ заставить это работать?

@ Бриго: Это неверно. Таблица nat может содержать цепочку OUTPUT. Проблема в том, что цепочка PREROUTING таблицы nat не применяется к интерфейсу обратной связи.

@rmonjo, используйте цепочку OUTPUT в дополнение к цепочке PREROUTING:

iptables -t nat -A OUTPUT -o lo -p tcp --dport <port> -j DNAT \
--to-destination #<container_ip>:<port>

Изменить: это не работает. Я думал о цели REDIRECT, которая не решит эту проблему.

Я потратил много времени, пытаясь заставить iptables сделать этот трюк, но каким-то образом, если вы добавите цель dnat в выходную цепочку таблицы nat, дальнейшая обработка пакета, похоже, остановится.

Отладку iptables можно выполнить с помощью такого трюка: http://backreference.org/2010/06/11/iptables-debugging/

Графический обзор потока пакетов в Linux также помогает: http://inai.de/images/nf-packet-flow.png

я обратился к xinetd для решения своей проблемы, см. Перенаправление конечной точки (на локальном хосте) туннеля SSH -L на другую машину

Если вы открыты для решений, не связанных iptables, вы можете просто запустить простой прокси-сервер (например, баланс или haproxy или ручка или что-то в этом роде) для перехвата трафика на localhost и передайте в свои контейнеры.