#docker #docker-compose #windows-subsystem-for-linux
#docker #docker-compose #windows-subsystem-for-linux
Вопрос:
В настоящее время я использую docker в Windows 10 через WSL. Я разработал приложение в Linux изначально, и там я смог получить доступ к контейнеру через браузер с помощью чего-то вроде http://10.5.0.2:8088
. Случается, что когда я делаю то же самое, используя WSL Ubuntu, единственное, что мне удается сделать, это http://localhost:8088
.
На данный момент это не кажется проблемой, но поскольку я работаю над имитацией кластера, было бы лучше избегать такого рода вещей, чтобы не иметь конфликтов портов в будущем.
Для иллюстрации: я определяю стек чем-то вроде
version: "3.7"
services:
spark-master:
image: master
container_name: spark-master
hostname: spark-master
tty: true
depends_on:
- spark-worker-1
- [...]
ports:
- "8088:8088"
- "50070:50070"
- "50030:50030"
- "8080:8080"
- "8042:8042"
- "8888:8888"
- "4040:4040"
networks:
spark-network:
ipv4_address: 10.5.0.2
spark-worker-1:
image: worker
container_name: spark-worker-1
hostname: spark-worker-1
tty: true
ports:
- "8081:8081"
- "6042:8042"
networks:
spark-network:
ipv4_address: 10.5.0.3
networks:
spark-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.5.0.0/16
Итак, можно было бы сопоставить это с хостом Windows, или рабочий стол Docker с серверной частью WSL вообще не поддерживает доступ к контейнерам по IP?
Ответ №1:
Короткий ответ
Да, но обычно это слишком сложно для обслуживания (с использованием сетевых знаний, а также iptables и маршрутизации Windows и Linux) и, в первую очередь, противоречит цели использования docker. Вероятно, вам следует обрабатывать свою виртуальную машину WSL2 как единый внешний узел, с которого вы получаете удаленный доступ.
Длинный ответ
Docker в WSL2 запускается на виртуальной машине внутри Hyper-V, выполняя несколько трюков для пересылки сообщений с открытых портов виртуальной машины на хост Windows и наоборот (вот почему вы можете запускать docker run --rm -it -p 80:80 containous/whoami
и получать доступ к данным вашего контейнера через http://localhost ).
Вот почему вы не можете получить доступ к своему контейнеру напрямую, используя IP-адрес контейнера: сеть, к которой подключены ваши контейнеры, подключена к виртуальной машине (не к хосту Windows), поэтому хост Windows понятия не имеет, куда указывать для связи в этой сети.
Однако, если вы когда-либо сталкивались с сетевыми сетями, вы знаете, что всегда можете переходить с хоста на хост, если все настроено правильно. Вам просто нужно знать свой путь в сетевых хитросплетениях. Но (и всегда есть «но») docker также использует свою собственную iptables
схему для обмена данными с контейнерами по внешним сетям и обеспечения безопасности контейнера. Вот почему простое добавление маршрута от вашего хоста Windows к виртуальной машине WSL2 не сработает: запрос сможет достичь виртуальной машины, но не контейнеров, поскольку правило iptables отключит его пересылку (по соображениям безопасности, как показано здесь).
Итак, подводя итог, чтобы вы могли взаимодействовать со своими контейнерами так, как вы бы это делали в Ubuntu:
- Настройте маршруты связи на вашем хосте Windows для вашего кластера в виртуальной машине, поскольку виртуальная машина WSL2 не использует статический IP:
route add <your-cluster-subnet>/<mask> <your-vm-ip>
- Включить пересылку из правил Docker
iptables
для внешней маршрутизации:iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
- Прибыль?
Обратите внимание, что если вы используете настройку по умолчанию из WSL2, вам нужно будет выполнить шаг 1 несколько раз, поскольку виртуальная машина WSL2 по умолчанию не использует статический IP.
Лично я думаю, что проще просто выставить порты 🙂
Ссылки
Комментарии:
1. Это действительно полезно знать! Большое спасибо!
Ответ №2:
Вы также можете попробовать запустить браузер внутри wsl2, это не решение проблемы!
https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps