I'm currently using docker on Windows 10 through the WSL. I've developed an application in Linux natively, and there I was able to access the container through the browser with something like http://10.5.0.2:8088
. It happens that when I to do the same using the WSL + Ubuntu, the only thing that I manage to do is http://localhost:8088
.
For now, this doesn't appear to be a problem, but since I'm working simulating a cluster, it would be better to avoid this kind of thing to not have port conficts in the future.
To illustrate: I'm defining a stack with something like
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
So, it would be possible to map this to the Windows host, or Docker Desktop with WSL backend doesn't support acessing containers by IP at all?
Short answer
Yes, but it's usually too complex to maintain (involving network knowledge, as well as iptables and Windows and Linux routing) and defeats the purpose of using docker in the first place. You should probably handle your WSL2 virtual machine as a single, external node from which you access remotely.
Long answer
Docker in WSL2 runs in a VM inside Hyper-V, doing a few tricks to forward communication from exposed ports in the VM to the Windows Host and vice-versa (that's why you can run docker run --rm -it -p 80:80 containous/whoami
and access your container data through http://localhost).
That's why you cannot access your container directly by using the container IP: the network which your containers are bridged are from the VM (not the Windows Host), so the Windows Host has no clue where to point to communicate in that network.
However, if you ever messed around with networking, you know that you can always hop from host to host if everything is set properly. You just need to know your way into the network tangles. But (and there's always a but) docker also uses it's own iptables
scheme to NAT container communications over external networks and container security. That's why simply adding a route from your Windows Host to the WSL2 VM won't work: the request will be able to reach the VM, but not the containers, as the iptables rule will disable it's forwarding (for security reasons, as seem here).
So, to summarize it, in order for you to communicate to your containers as you would in Ubuntu:
route add <your-cluster-subnet>/<mask> <your-vm-ip>
iptables
rules for external routing: iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
Note that if you're using the default setup from WSL2, you'll need to perform step 1 multiple times, as the WSL2 virtual machine does not use a static IP by default.
Personally I think it's easier to just expose ports :)
References
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With