IPv6 не работает в Docker Swarm?
У меня есть сервер Ubuntu 16.04 LTS, работающий на IPv4 и IPv6 (двойной стек). На этом сервере также работает Docker. Однако у меня возникают проблемы, когда я пытаюсь получить доступ к контейнерам в рое, но только через IPv6. Вот мои шаги:
Я создал простое приложение под управлением веб-сервера gnuicron:
def app(environ, start_response):
"""Simplest possible application object"""
data = b'Hello, World!\n'
status = '200 OK'
response_headers = [
('Content-type', 'text/plain'),
('Content-Length', str(len(data)))
]
start_response(status, response_headers)
return iter([data])
Я запускаю это с gunicorn -w 4 -b [::]:5678 myapp:app
на моем сервере и убедитесь, что он работает, запустив это на клиенте с двумя стеками в моей сети:
$ curl --connect-timeout 15 http://[2001:db8:db0::5]:5678
Hello, World!
$ curl --connect-timeout 15 http://192.168.10.5:5678
Hello, World!
Я пишу Dockerfile и запускаю его:
docker build -t docker_ipv6_test .
docker run --rm --init -p 5678:5678 docker_ipv6_test
Я запускаю ту же проверку, что и примерно, и она работает, как ожидалось. Затем я пишу docker-compose.yml:
version: '3'
services:
ipv6_test:
image: docker_ipv6_test:latest
deploy:
replicas: 1
restart_policy:
condition: on-failure
ports:
- '5678:5678/tcp'
и запустить его:
docker stack deploy -c docker-compose.yml ipv6_test
Тогда это происходит:
$ curl --connect-timeout 15 http://[2001:db8:db0::5]:5678
curl: (28) Operation timed out after 0 milliseconds with 0 out of 0 bytes received
$ curl --connect-timeout 15 http://192.168.10.5:5678
Hello, World!
Но мне было интересно, если я делаю что-то не так, или я ошибся?
Весь мой код и файлы доступны здесь: https://github.com/SitronNO/docker_ipv6_test
0 ответов
Режим Swarm, похоже, не поддерживает IPv6 с входящей / служебной сетью. По этому поводу есть открытая проблема, на которую я бы порекомендовал подписаться и поставить отметку "Нравится", чтобы привлечь больше внимания.
В качестве обходного пути службы в кластере могут взаимодействовать по IPv4, и вы можете публиковать порты в режиме хоста через прокси, работающий в глобальном режиме. Например, вот частичный файл компоновки:
version: '3.8'
services:
proxy:
deploy:
mode: global
ports:
- target: 80
published: 80
protocol: "tcp"
mode: "host"
# ...
Вы нажали на ошибку и сделали что-то не так. Из многих проблем github и комментария на https://docs.docker.com/compose/compose-file/ узнать, что ipv6 в настоящий момент не работает в роях:
Если требуется адресация IPv6, необходимо установить параметр enable_ipv6 и использовать файл составления версии 2.x. Опции IPv6 в настоящее время не работают в режиме роя.
вы можете попробовать IPv6 NAT https://github.com/robbertkl/docker-ipv6nat но это тоже сложно настроить, особенно если у вас нет ipv6tables и т. д.
То, что вы сделали неправильно, не настроили сеть моста роя роя с поддержкой ipv6, ИЛИ не запустите докер с включенным ipv6 - но, учитывая текущую документацию, это не удивительно.
-Я бы сказал, что никто не ответил на этот вопрос, потому что пока нет хорошего ответа.
НО один из ответов - пусть docker сделает то, что умеет лучше всего, а остальная часть linux сделает все остальное. Оставьте Docker Swarm в качестве чисто сети ipv4 и просто перенаправьте трафик ipv6 в эту сеть. Это невозможно с ip-таблицами пересылки с ipv4 на ipv6, но это возможно при использовании socat
например:
sudo socat TCP6-LISTEN:80,,su=nobody,fork,reuseaddr TCP4:127.0.0.1:81
Заметьте, что я перенес докер порта, который прослушивает порт 81, потому что, хотя в docker_gwbridge для роя может быть не включен ipv6, он все равно будет связываться с портом ipv6:80 (вздох). Обратите внимание, что socat теперь будет пересылать ОБА ipv4 и ipv6 трафик на порт ipv4 80.
Вы можете sudo nohup socat ... &
эта команда, чтобы получить его в фоновом режиме.
см. Как прозрачно туннелировать порт от IPv4 к удаленному устройству IPv6? и другие.