Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Docker Container IP when using WSL + Ubuntu 20.04 LTS

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?

like image 419
gbieul Avatar asked Sep 04 '20 11:09

gbieul


1 Answers

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:

  1. Setup the communication routes in your Windows Host for your cluster in the VM, as the WSL2 VM does not use a static IP: route add <your-cluster-subnet>/<mask> <your-vm-ip>
  2. Enable forwarding from Docker iptables rules for external routing: iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
  3. Profit?

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

  • https://docs.docker.com/network/iptables/
  • https://www.howtogeek.com/howto/windows/adding-a-tcpip-route-to-the-windows-routing-table/
like image 88
Gustavo Kawamoto Avatar answered Sep 29 '22 06:09

Gustavo Kawamoto