Я управляю небольшой доской, предоставляющей некоторые услуги в нашей локальной сети. Когда я пытаюсь понять, что docker поддерживает ipv6, я не совсем понимаю результаты моих первых тестов.
Моя сеть управляется одним маршрутом с использованием dhcpv6, каждый клиент имеет 2 действительных глобальных адреса ipv6 (также 1 локальный ipv4) и защищен брандмауэром маршрутизатора (не разрешая запросы из Интернета к клиентам).
Arm Board работает под управлением Ubuntu 16.04, имеет действующий адрес ipv6 с включенными расширениями конфиденциальности.
Все контейнеры докеров используют мостовую сеть по умолчанию без каких-либо настроек.
На хосте докера
netstat -tulpen|grep docker
показывает
tcp6 0 0 :::8080 :::* LISTEN 0 22490 1559/docker-proxy
Ни одна служба ipv4 не слушает.
Внутри этого контейнера докеров тот же запрос netstat дает
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 23955 8/nginx
tcp6 0 0 :::80 :::* LISTEN 0 23956 8/nginx
Nginx прослушивает ipv6, а также ipv4 - порт 80 доступен для порта 8080 с
docker run (...) -p 8080:80 (...)
Осмотр мостовой сети
docker network inspect bridge
показывает локальный мост по умолчанию
(...)
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
(...)
"b10cf3750252daf0ba11a59cfcd64c72194adcaacd4b9b5df17fae0f53fc4f00": {
"Name": "ng",
"EndpointID": "f42de3590072dec2b0d3fae61fc89aeffcb8e6e716b27f5736272fcc8f94f643",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
(...)
Теперь к моему вопросу:
Насколько я понимаю, конфигурация docker bridge ipv6 отключена, docker-контейнер не имеет ipv6 - только ipv4. Nginx слушает как ipv4, так и ipv6 - игнорируя тот факт, что ipv6 недоступен.
Почему служба nginx на хосте, доступном через порт 8080, указана как доступная только через ipv6?
Проверка этого с помощью другого сетевого клиента с
curl -g -6 http://[DOCKER_HOST_IPV6]:8080
curl http://[DOCKER_HOST_IPV4]:8080
показывает, что служба доступна как с ipv6, так и с ipv4 - почему netstat не показывает службу как службу ipv4?
Если ipv6 отключен в конфигурации сети моста, как вообще доступна эта служба?
У меня есть другой контейнер, в котором запущен openvpn на udp 1194. Я настроил сервер на использование udp6, проверенный с помощью netstat внутри контейнера. Этот контейнер отображается таким же образом с помощью флага -p, но вообще недоступен на хосте. Как правильно связать эту службу?
Это не контейнер nginx, который прослушивает ipv6 (кстати, сокет tcp6, который вы видите в контейнере, привязан к его fe80 :: и :: 1, и он недоступен извне мира контейнеров). Это процесс docker-proxy, который управляет портом хоста. Когда вы используете "-p 8080: 80", docker-proxy связывает сокет tcp6 на хосте :: 0, прослушивая порт 8080 (и сокеты tcp6 также принимают tcp4).
Таким образом, отключенная поддержка ipv6 на докере (по умолчанию) означает, что вашим контейнерам назначен только ipv4, но docker-proxy «переводит» v6 на v4:
(мир ipv6) -> хост докера ipv6: 8080 -> [докер-прокси] -> контейнер nginx ipv4: 80