Заставить докер использовать IPv4 для привязки порта

98

У меня есть докер-хост, а внутри - один контейнер.

Хост докера привязывает порт только к интерфейсу IPv6, а не к IPv4.

Это результат

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:55082           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::40280                :::*                    LISTEN      -
tcp6       0      0 :::5432                 :::*                    LISTEN      -
tcp6       0      0 :::40122                :::*                    LISTEN      -
tcp6       0      0 :::36378                :::*                    LISTEN      -
tcp6       0      0 :::40543                :::*                    LISTEN      -
tcp6       0      0 :::111                  :::*                    LISTEN      -

Теперь у меня есть порт 40122 на хосте для связи с портом 22 на контейнере.

Я хочу подключиться к этому контейнеру по SSH, но не могу, поскольку он привязан только к IPv6

Это моя версия докера Docker version 1.5.0, build a8a31ef

docker ps

201bde6c839a        myapp:latest   "supervisord -n"    3 weeks ago         Up 2 hours          0.0.0.0:40122->22/tcp, 0.0.0.0:40280->80/tcp, 0.0.0.0:40543->443/tcp   myapp

Я побежал, используя docker run -d -P -p 40122:22

netstat -tlna

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3031          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::6379                 :::*                    LISTEN

ps aux

root         1  0.0  0.8  52440 16668 ?        Ss   00:53   0:03 /usr/bin/python /usr/bin/supervisord -n
root        49  0.0  0.1  17980  3048 ?        S    01:32   0:00 bash
root        64  0.0  0.1  46632  2712 ?        S    01:32   0:00 su -l vagrant
vagrant     65  0.0  0.1  21308  3760 ?        S    01:32   0:00 -su
root       288  0.0  0.1  17980  3088 ?        S    02:01   0:00 bash
root       304  0.0  0.1  46632  2720 ?        S    02:01   0:00 su -l vagrant
vagrant    305  0.0  0.1  21304  3804 ?        S    02:01   0:00 -su
vagrant    308  0.0  3.7 429616 75840 ?        Sl+  02:01   0:05 python ./manage.py shell_plus
root       654  0.0  0.4  47596  9848 ?        S    03:12   0:01 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       655  0.0  0.3  90280  7732 ?        S    03:12   0:00 nginx: master process /usr/sbin/nginx
www-data   656  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   657  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   658  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   659  0.0  0.2  90940  4500 ?        S    03:12   0:00 nginx: worker process
root       660  0.0  0.2  61372  5332 ?        S    03:12   0:00 /usr/sbin/sshd -D
root       669  0.0  0.4  37004  8892 ?        Sl   03:12   0:01 redis-server *:6379
root       856  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       857  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       858  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       859  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
vagrant    889  0.0  0.1  18692  2508 ?        R+   04:11   0:00 ps aux
user3214546
источник
Какую команду вы использовали для запуска контейнера? Также опубликуйте вывод, docker psкогда контейнер работает.
Даниэль Т.
Можете ли вы подтвердить, что sshd действительно запущен в контейнере? Беги docker exec -ti 201bde6c839a /bin/bash, как только вы войдете, опубликуйте результат ps aux иnetstat -taln
Даниэль Т.
На моем хосте Docker все порты докеров прослушивают IPv6 и не имеют проблем с подключением к ssh в контейнерах.
Даниэль Т.
@ Дэниелт. я добавил информацию. Я могу использовать ssh с помощью exec, но я не могу подключать ssh к контейнеру напрямую извне, используя порт хоста 40122 с mac
user3214546
Вы можете столкнуться с этой проблемой github.com/docker/docker/issues/2174 , я не уверен, что она решена. Можете ли вы также рассказать, как вы пытаетесь подключиться через ssh и какую ошибку получаете?
Даниэль Т.

Ответы:

73

Как указывает @ daniel-t в комментарии: github.com/docker/docker/issues/2174 показывает привязку только к IPv6 netstat, но это не проблема. Как говорится в этой проблеме на github:

При настройке прокси Docker запрашивает адрес обратной связи «127.0.0.1», Linux понимает, что это адрес, который существует в IPv6 (как :: 0), и открывается на обоих (но формально это сокет IPv6). Когда вы запускаете netstat, он видит это и сообщает вам, что это IPv6, но он все еще прослушивает IPv4. Если вы немного поигрались со своими настройками, возможно, вы отключили этот трюк, который делает Linux, установив net.ipv6.bindv6only = 1.

Другими словами, только потому, что вы видите его только как IPv6, он все еще может взаимодействовать по IPv4, если только у вас не настроен IPv6 для привязки только к IPv6 с параметром net.ipv6.bindv6only. Чтобы было ясно, net.ipv6.bindv6only должен быть 0 - вы можете запустить sysctl net.ipv6.bindv6onlyдля проверки.

Майкл
источник
4
На самом деле это большая проблема. Общедоступное облако, такое как Azure, не очень хорошо поддерживает IPV6, например, общедоступный балансировщик нагрузки Azure пытается использовать IPV4 в качестве серверной части.
Thomas Decaux
1
Кажется, вам может потребоваться установить «Docker VM Extension» в Azure и использовать Ubuntu 14.04 LTS. Однако я не думаю, что есть проблема с ipv6, поскольку он работает только на локальном хосте, а не в сети.
Майкл
Вы правы, проблема была в моей конфигурации (отключение IPV6 - не лучшая идея ^^)
Thomas Decaux
1
@bigdong, вы хотите включить ipv6.
Майкл
1
@Michael Ты экономишь мое время. :)
lv0gun9
6

Настройка net.ipv6.conf.all.forwarding=1устранит проблему.

Это можно сделать в живой системе, используя sudo sysctl -w net.ipv6.conf.all.forwarding=1

Люцифер Джек
источник
Этот ответ имеет одно преимущество: он позволяет вам «исправить» проблему без перезапуска демона докера (ответ с изменением конфигурации докера ниже). Относительно верхнего выбранного ответа: у меня действительно было sysctl net.ipv6.bindv6only=0так, что изменение этой конфигурации не помогло.
pkoperek
2

По умолчанию docker использует сокеты AF_INET6, которые можно использовать как для соединений IPv4, так и для IPv6. Это заставляет netstat сообщать IPv6-адрес для адреса прослушивания.

Из RedHat https://access.redhat.com/solutions/3114021

Герасимос Митропулос
источник
0

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

  • найдите файл настроек
    • / etc / sysconfig / docker-network как в RedHat
    • / etc / default / docker-network в Debian и аналогично
  • редактировать настройки сети
    • добавить DOCKER_NETWORK_OPTIONS = -ip = xx.xx.xx.xx
    • xx.xx.xx.xx - ваш реальный ipv4 (а не 0.0.0.0)
  • перезапустить докер демон

у меня работает на докере 1.9.1

Сильвен
источник
1
это работает на debian? Разве это не должно быть / etc / default / docker?
Dimitri Kopriwa
1
@BigDong спасибо за комментарий, я использую RedHat, как ОС, поэтому путь немного отличается от одной ОС к другой. Я попытался отразить ваш комментарий в ответе
Сильвен
0

РЕШЕНИЕ ВОПРОСА :

ИСПОЛЬЗОВАТЬ docker run -it -p 80:80 --name nginx --net=host -d nginx

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

tcp     0    0 0.0.0.0:80            0.0.0.0:*             LISTEN      - 
tcp6    0    0 :::80                 :::*                  LISTEN      -  
Хариш Чандер Далал
источник
-1

Я смог получить доступ к контейнеру докеров после отключения SELinux

Чтобы временно отключить SELinux #sudo setenforce 0

Мои докер-контейнеры работали на Centos-7

Манджунатх N
источник