docker / for-win

Bug reports for Docker Desktop for Windows
https://www.docker.com/products/docker#/windows
1.85k stars 287 forks source link

How to access containers by internal IPs 172.x.x.x #221

Closed wclr closed 7 years ago

wclr commented 7 years ago

How to access containers by internal IP 172.x.x.x from dev machine (with docker for windows installed)? So by default you can not connect to containers.

I found out that it can be achived by adding route manually (you actually need to add routes for each sub-netwrok, I usually do for 17-25):

route /P add 172.17.0.0 MASK 255.255.0.0 10.0.75
route /P add 172.18.0.0 MASK 255.255.0.0 10.0.75
route /P add 172.19.0.0 MASK 255.255.0.0 10.0.75
...

Is is a valid method? Shouldn't it be made possible by default?

genjudev commented 6 years ago

I hope its written in the comments above but I didnt find it....

don't use:

route /P add 172.0.0.0 MASK 255.0.0.0 10.0.75.2

172.0.0.0/8 contains public ip's as well!

use the private subnet 172.16.0.0/12

route /P add 172.16.0.0 MASK 255.240.0.0 10.0.75.2

or even better the right subnet from your docker specific configuration

rizplate commented 6 years ago

docker networking is a clown show

lucnap commented 6 years ago

@mayaracsferreira please describe here all your configuration: host windows ip addr, guest linux ip addr, docker bridge network, docker container ip addr

mayaracsferreira commented 6 years ago

@lucnap, thanks for the reply

I changed my strategy and this solved my problem. I'll comment the steps I took here, perhaps this can be helpful to somebody

Now I'm using docker for windows 8.1

I innocently created a network for docker on the same subnet as the host's network with the command on Docker Toolbox

docker network create --driver=bridge --subnet=192.168.1.0/24 localnet

After that I pulled the Image of oracle I wanted and up the container with the network I created before:

docker run --net localnet -d -p 8080:8080 -p 1521:1521 --name oracle wnameless/docker-oracle-xe-11g

To access the database created at this container I needed to discover the external IP of the VM create by Kitematic to run docker

docker-machine ls

Now I can connect to the database running inside docker on the oracle client on the host machine with the ip of the VM and the port 1521

leandrocgsi commented 6 years ago

docker_toolbox If you using DockerToolbox for windows just use your IP 192.168.99.100

ekc commented 6 years ago

@leandrocgsi , many thanks for the tip. It works for me I use Oracle Virtualbox as a driver and I believe the container IP address is translated to that of the docker-machine upon publishing with docker run -p. The IP address of the docker-machine can be found by running docker-machine ip ...

\ $ docker-machine ip
192.168.99.100
\ $

Once I accessed the docker-machine and dumped the nat chain of the iptables, I found this

\ $ docker-machine ssh                                                                        
                        ##         .                                                          
                  ## ## ##        ==                                                          
               ## ## ## ## ##    ===                                                          
           /"""""""""""""""""\___/ ===                                                        
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~                                                 
           \______ o           __/                                                            
             \    \         __/                                                               
              \____\_______/                                                                  
 _                 _   ____     _            _                                                
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __                                    
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|                                   
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |                                      
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|                                      
Boot2Docker version 18.05.0-ce, build HEAD : b5d6989 - Thu May 10 16:35:28 UTC 2018           
Docker version 18.05.0-ce, build f150324                                                      
docker@default:~$ sudo iptables -t nat -L                                                     
Chain PREROUTING (policy ACCEPT)                                                              
target     prot opt source               destination                                          
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL   

Chain INPUT (policy ACCEPT)                                                                   
target     prot opt source               destination                                          

Chain OUTPUT (policy ACCEPT)                                                                  
target     prot opt source               destination                                          
DOCKER     all  --  anywhere            !127.0.0.0/8          ADDRTYPE match dst-type LOCAL   

Chain POSTROUTING (policy ACCEPT)                                                             
target     prot opt source               destination                                          
MASQUERADE  all  --  172.17.0.0/16        anywhere                                            
MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:www                    

Chain DOCKER (2 references)                                                                   
target     prot opt source               destination                                          
RETURN     all  --  anywhere             anywhere                                             
DNAT       tcp  --  anywhere             anywhere             tcp dpt:www to:172.17.0.2:80    
docker@default:~$                                                                             

On my Windows host, I can access port 80 of the container via the docker-machine ip

\ $ curl http://192.168.99.100/demo.php
<html>
<body>
<h1>My first PHP page</h1>

Hello World!</body>
</html>
\ $
felipemarques commented 6 years ago

Iam using a Windows 10 PRO. Iam not using Docker Toolbox, only docker engine installed on windows and using a virtualbox provider.

For me , the only way for work, is:

route /P add 172.17.0.0/8 192.168.99.100

Is that a correct way?

ghost commented 6 years ago

I don't think this problem is going to be solve because, overall docker for windows is is using some kind of vm and you won't be able to access the docker's IP address. you are looking at different IPs using the same box.

I have spend time finding a solution and is it one of things that is not going to take. The only way for you to use the internal IP for docker is by using Ubuntu because docker is install natively not virtualizing. So when it is install natively, you can set different IP for 172.x.x.x.x and it will work fine.

rizplate commented 6 years ago

ya'all need to move to linux or mac.

no sane person can develop on windows unless you are working on Microsoft tech

wclr commented 5 years ago

BTW in the late versions the problem of access (again) is just solved by adding persistent routes:

route /P add 172.0.17. MASK 255.255.0.0 10.0.75.2

no need to update routing tables in in the docker vm or something.

nocrobson commented 5 years ago

Try this https://stackoverflow.com/a/36458215/8405418

midacts commented 5 years ago

I ran into the same thing today. I am running Docker for Windows and was unable to ping my docker containers by their IP.

Adding the suggested route worked.

route /P add 172.16.0.0 MASK 255.240.0.0 10.0.75.2

jesuslpm commented 5 years ago

I'm using Docker Desktop Version 2.0.0.3 (31259) on Windows and this works:

route /P add 172.17.0.0 MASK 255.255.0.0 10.0.75.2

silkfire commented 5 years ago

@Midacts Thanks for the solution. The one by whitecolor actually made me unable to reach Google.com so I had to revert that procedure entirely.

wclr commented 5 years ago

@Midacts Thanks for the solution. The one by whitecolor actually made me unable to reach Google.com so I had to revert that procedure entirely.

Yeah, I updated OP.

uosjead commented 5 years ago

I was using Hyper-V on Windows, I got this to work without the using of route P /add

I used the the IPV4 address for Hyper-V vEthernet device from ipconfig /all which worked in a web browser with same port specified in the docker run -p flag while running the container on 0.0.0.0

docker inspect --format "{{.NetworkSettings.IPAddress}}" gave me the wrong IP addreess

f5oto commented 5 years ago

In windows this worked for me: Add route to Docker virtual machine on default IP 10.0.75.2

route -p add 172.17.0.0 mask 255.255.255.0 10.0.75.2

songpr commented 5 years ago

In windows this worked for me: Add route to Docker virtual machine on default IP 10.0.75.2

route -p add 172.17.0.0 mask 255.255.255.0 10.0.75.2

This work for me as well no need to map port which is unstable on windows Docker.

wclr commented 5 years ago

This work for me as well no need to map port which is unstable on windows Docker.

But it seems that using such routes causes Docker.Service to consume a lot of CPU/memory

siochs commented 5 years ago

In windows this worked for me: Add route to Docker virtual machine on default IP 10.0.75.2 route -p add 172.17.0.0 mask 255.255.255.0 10.0.75.2

This work for me as well no need to map port which is unstable on windows Docker.

Works for me too, but only when I apply the purposed command before I start any container. So apply first, then start working with docker. Why has this been closed? This is a workaround, right?

vinchauhan commented 4 years ago

This has stopped working again with the latest release of docker (19.03.5)

beckermarc commented 4 years ago

This seems to be the case because DockerNAT has been removed, see https://github.com/docker/for-win/issues/5538

vinchauhan commented 4 years ago

Yes upgrade is removing DockerNAT, Uninstall and Install should fix the issue.

Koc commented 4 years ago

Indeed, it stops work after one of the lasy updates. So I've switched to the docker-toolbox instead.

vinchauhan commented 4 years ago

@Koc - If you uninstall and Install Docker desktop for windows everything should start working. DockerNAT network interface will be restored

siochs commented 4 years ago

@Koc - If you uninstall and Install Docker desktop for windows everything should start working. DockerNAT network interface will be restored

I cannot confirm this. I tried uninstall and reinstall and DockerNAT did not restore. I did reboots in between. I tried manually add the adapter but no luck so far - my windows networking skills are limited and it was a shot in the dark. Maybe anyone can change the following to a working setup?

New-VMSwitch -SwitchName "DockerNAT" -SwitchType Internal -Verbose
Get-NetAdapter 
# --> ifIndex = 60
New-NetIPAddress -IPAddress 10.0.75.0 -PrefixLength 24 -InterfaceIndex 60 -Verbose
New-NetNat -Name NATNetwork -InternalIPInterfaceAddressPrefix 10.0.75.0/24 -Verbose
route -p add 172.17.0.0 mask 255.255.255.0 10.0.75.2
siochs commented 4 years ago

Just took a look into the Hyper-V VM Manager. This DockerDesktopVM has no network interface configured thus it is not attached to any NAT. Attaching it after boot has no effect.

vision57 commented 4 years ago

For those who use toolbox, if still can't access container ip directly from host after add route, but container gateway like 172.x.0.1 is accessable. Try login VM and check iptables, make sure FORWARD chain is ACCEPT.

Full instructions reference:


# add route if absent, doing this only if VM is running
# 172.x.0.0/16 is subnet of your container bridge network
# $(docker-machine ip default) retrieve ip of VM in one of host network
# command syntax varies with host OS
sudo route -n add -net 172.x.0.0/16  $(docker-machine ip default)

# login VM, the real linux running docker engine
docker-machine ssh default

sudo iptables -L

# add ACCEPT if absent, default rules may vary with releases of docker
# may lose after VM reboot
sudo iptables -I DOCKER-USER  -j ACCEPT

See Docker and iptables for more.

nibtime commented 4 years ago

I am on Win10 and had to access a host service from within a container recently, so I tried to connecting to the container with its IP, which did not work and so I landed here. The idea of system modifications with Windows + Docker networking for that purpose made me uncomfortable. For my situation, I found a little trick to avoid this entirely, and maybe it turns out to be useful for someone else too. It goes like that:

  1. Start an SSH server inside the container that needs the host service
  2. Forward the container port of the SSH server to your Windows host system (localhost)
  3. Use PuTTY to connect to the SSH server with a tunnel from 127.0.0.1:<port of host service> to a target port in the Container. The host system can access the container SSH server locally from its point of view since the port has been forwarded by the container earlier

After that, you can consume the host service locally from the container's point of view. My concrete scenario was Chrome Co-Debugging with VS Code Remote Containers. I described it with more detailed instructions over here.

datdinhquoc commented 4 years ago

@kallie-b ok what should I do after I got IP? I want to ping it by IP. But it won't work from dev machine. I'm asking how to do this.

for me, the ips 172.17.0.x work with Docker on linux, but not on windows. any ideas why?

vinchauhan commented 4 years ago

@datdinhquoc it won't work with the latest version of docker for windows as they changed networking and now there is no DockerNAT and there is no option to make it work other than installing and older version. I rolled back to 19.x and it works again with the persistent route workaround

datdinhquoc commented 4 years ago

@datdinhquoc it won't work with the latest version of docker for windows as they changed networking and now there is no DockerNAT and there is no option to make it work other than installing and older version. I rolled back to 19.x and it works again with the persistent route workaround

yes, i see it now, even on official docker website: can't ping linux containers from windows https://docs.docker.com/docker-for-windows/networking/#i-cannot-ping-my-containers

ghost commented 4 years ago

all u gotta do is use wls2 and docker, that solves every thing.

felipecrs commented 4 years ago

all u gotta do is use wls2 and docker, that solves every thing.

Do you mean installing docker daemon in the WSL distro instead of Docker Desktop? Because for me, this doesn't work even using Docker Desktop with WSL2 as backend.

datdinhquoc commented 4 years ago

all u gotta do is use wls2 and docker, that solves every thing.

docker container inside wsl2, ok, should work, tks

datdinhquoc commented 4 years ago

all u gotta do is use wls2 and docker, that solves every thing.

Do you mean installing docker daemon in the WSL distro instead of Docker Desktop? Because for me, this doesn't work even using Docker Desktop with WSL2 as backend.

yes, docker inside wsl2, not docker desktop (windows)

ghost commented 4 years ago

Let's say that you cannot use WSL2 on Windows 10 Pro. WSL2 is only for those who are using Windows 10 Home. The new Docker for Windows has built-in support for WSL2 for those who are using Windows 10 Home. The software detect if you are using home or pro.

felipecrs commented 4 years ago

Let's say that you cannot use WSL2 on Windows 10 Pro. WSL2 is only for those who are using Windows 10 Home. The new Docker for Windows has built-in support for WSL2 for those who are using Windows 10 Home. The software detect if you are using home or pro.

How does this help? The problem still happens in Docker Desktop, no matter what backend.

ghost commented 4 years ago

So if you are using WSL2 with Ubuntu and you have docker for Windows. you don't even need to install docker on WSL2, the docker for WIndows have an option as see below. image

ghost commented 4 years ago

honestly, I'm not sure how you guys are setting up your environment. my simple setup is just to use the localhost at 127.0.0.1 and it just does whatever it needs to do. maybe I'm not doing complicated things, as long as I get my setup environment the way I need it. then improve it.

ghost commented 4 years ago

I feel there is no need to grab the external IP address or the network that comes with the HyperV or WSL2 network because it changes every time you restart. WSL2 allows you to ping the 172.0.0.1 automatically without doing route IP or whatever. WSL2 is integrated into Windows so why not use the localhost for everything. If you're a web dev u can always update the hosts automatically with some bash script

macOS uses their own apple hypervisor you can't even access the dockerNAT. that's why using the localhost makes sense. I just build project that works for all different types of OS using HyperV, wsl2, macOS, and Linux because I use the localhost for everything.

127.0.0.1 dev.environtment.test
127.0.0.1 dev2.enviornment.test
felipecrs commented 4 years ago

The point of this Issue isn't to discuss if using localhost is good or not. We are talking about being able to ping a container. Are you able to do that with your environment? Mine looks just like yours, and I'm not able to.

docker run -d --name alpine alpine sleep infinity
container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' alpine)
ping $container_ip
docker rm -f alpine
felipecrs commented 4 years ago

Maybe this works if you install the docker daemon in WSL2, without Docker Desktop, but didn't test it.

ghost commented 4 years ago

u don't insall the daemon in wsl2, the docker desktop for windows enables that for u when u select wsl integration. i don't need to install docker on my wsl2 machine. the wsl integration in docker desktop does thatt for u.

felipecrs commented 4 years ago

u don't insall the daemon in wsl2, the docker desktop for windows enables that for u when u select wsl integration. i don't need to install docker on my wsl2 machine. the wsl integration in docker desktop does thatt for u.

I know. And does the ping work for you? As I said my environment is just like what you described, and it does not work.

docker run -d --name alpine alpine sleep infinity
container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' alpine)
ping $container_ip
docker rm -f alpine
ghost commented 4 years ago

is not going to work. u can just use dnsmasq to give container access. See this answer for your to use the docker internal DNS and you can just use service names directly

https://stackoverflow.com/a/52242360

felipecrs commented 4 years ago

is not going to work. u can just use dnsmasq to give container access. See this answer for your to use the docker internal DNS and you can just use service names directly

https://stackoverflow.com/a/52242360

Thanks for the suggestion. However, I believe this is a different matter. The fact is that the Issue reported here still persists even using Docker Desktop with WSL2.

ghost commented 4 years ago

is not gonna work as we hope in Windows and the fact that windows, like to change major updates every twice a year, seems stupid. . I have seen it work before that you have to do more setup than you realized. using dnsmaq and resolver may help. its just an suggestion. i've done it before but i realize its just too much an hassle.

well i hope you and the rest of people here can find a solution. but i think this is not gonna solve on its own.

vinchauhan commented 4 years ago

ting up your environment. my simple setup is just to use the localhost at 127.0.0.1 and it just does whatever it needs to do. maybe I'm not doing complicated things, as long as I get my setup environment the way I need it. then improve it.

I don't think every setup/project/requirement is drop dead simple like a webapp running of localhost. There is a challenge where you would need to ping or connect to the container ip 172.X, which is why people are asking for help

ghost commented 4 years ago

yah I understand, but then you know how windows like there UAC and security. you wouldn't have this issue if you were to use Linux because docker runs truly 100% natively so you can ping, create a network, and all that neat stuff. The majority I think Docker is made for Linux.

plus, there are solutions probably that no one has found a better one I guess.