docker port bind docker0 failed on macos - docker

custom interface
docker0
172.17.0.1
code
docker run -it --rm \
-p 172.17.0.1:53:53/udp \
--cap-add=NET_ADMIN --cap-add=NET_RAW \
ubuntu echo "hello word"
docker0 IPAddress
docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge
172.17.0.1
on linux
hello word
on mac
docker: Error response from daemon: Ports are not available: exposing port UDP 172.17.0.1:53 -> 0.0.0.0:0: listen udp 172.17.0.1:53: bind: can't assign requested address.
ERRO[0000] error waiting for container: context canceled

Related

Is it possible to bind on another IP than 127.0.0.1 on MacOS?

On MacOS 12, using Docker 20.10, I'm not able to start a container on another IP:
% docker run -p 127.123.2.13:80:80 -d nginx
a9216ae29940f7357b9b4826ecddf041f1805c9ee48ba1336361277fc0dcb524
docker: Error response from daemon: Ports are not available: listen tcp 127.0.17.1:80: bind: can't assign requested address.
Is there any other way?
In order to bind to the ip, other than 0.0.0.0, you need to have an interface in your system with the desired ip. For example, watch docker failing to bind to a non-existent ip of 127.0.0.2:
docker run -p 127.0.0.2:80:80 -d nginx
cc79b1b60c9f5e245b326bbfcc17d4a1f1abe6fad6fd12f9677b66bbee972a12
docker: Error response from daemon: Ports are not available: listen tcp 127.0.0.2:80: bind: can't assign requested address.
Now I create an alias for my existing interface lo0:
sudo ifconfig lo0 alias 127.0.0.2 netmask 0xff000000
and try again:
docker run -p 127.0.0.2:80:80 -d nginx
05223ecb6ae99a25b7423f014b9b95422c621717705ce1c255bea04072c45263
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc79b1b60c9f nginx "/docker-entrypoint.…" 2 minutes ago Created hardcore_haslett
05223ecb6ae9 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 127.0.0.2:80->80/tcp pensive_bardeen

Can connect to docker container when it runs apache, but not when it runs netcat on port 80

I am running a Debian server (stable), with the docker.io Debian package.This is the one distributed by Debian, not the one from the Docker developers. Since docker.io is only available in sid, I have installed from there (apt install -t unstable docker.io).
My firewall does allow connections to/from docker containers:
$ sudo ufw status
(...)
Anywhere ALLOW 172.17.0.0/16
172.17.0.0/16 ALLOW Anywhere
I also have this in /etc/ufw/before.rules :
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 172.17.0.0/16 -o eth0 -j MASQUERADE
So -- I have created an image with
$ sudo debootstrap stable ./stable-chroot http://deb.debian.org/debian > /dev/null
$ sudo tar -C stable-chroot -c . | docker import - debian-stable
Then started a container and installed apache2 and netcat. Port 1111 on the host machine will be redirected to port 80 on the container:
$ docker run -ti -p 1111:80 debian-stable bash
root#dc4996de9fe6:/# apt update
(... usual output from apt update ...)
root#dc4996de9fe6:/# apt install apache2 netcat
(... expected output, installation successful ...)
root#dc4996de9fe6:/# service apache2 start
root#dc4996de9fe6:/# service apache2 status
[ ok ] apache2 is running.
And from the host machine I can connect to the apache server:
$ curl 127.0.0.1:1111
(... HTML from the Debian apache placeholder page ...)
$ telnet 127.0.0.1 1111
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
And it waits for me to type (if I type GET / I get the Debian apache placeholder page). Ok. And if I stop apache inside the container,
root#06da401a5724:/# service apache2 stop
[ ok ] Stopping Apache httpd web server: apache2.
root#06da401a5724:/# service apache2 status
[FAIL] apache2 is not running ... failed!
Then connections to port 1111 on the host will be rejected (as expected):
$ telnet 127.0.0.1 1111
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.
Now, if I start netcat on the container, listening on port 80:
root#06da401a5724:/# nc -l 172.17.0.2 80
Then I cannot connect from the host!
$ telnet localhost 1111
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.
The same happens if I try nc -l 127.0.0.1 80 in the container.
What could be happening? Both apache and netcat were listening on port 80. What have I missed?
I'd appreciate any hints...
update: if I try this:
root#12b8fd142e00:/# nc -vv -l -p 80
listening on [any] 80 ...
172.17.0.1: inverse host lookup failed: Unknown host
invalid connection to [172.17.0.2] from (UNKNOWN) [172.17.0.1] 54876
Then it works!
Now it's weird... ifconfig inside the container tells me it has IP 172.17.0.2, but I can only use netcat binding to 172.17.0.1:
root#12b8fd142e00:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe11:2 prefixlen 64 scopeid 0x20<link>
And Apache seems to want to 172.17.0.2 instead:
2AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
but it actually uses 172.17.0.1:
root#12b8fd142e00:/# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 12b8fd142e00:http 172.17.0.1:54942 TIME_WAIT
tcp 0 0 12b8fd142e00:39528 151.101.48.204:http TIME_WAIT
Apache is not listening on 172.17.0.1, that's the address of the host (in the docker bridge).
In the netstat output, the local address has been resolved to 12b8fd142e00. Use the -n option with netstat to see unresolved (numeric) addresses (for example netstat -plnet to see listening sockets). 172.17.0.1 is the foreign address that connected to Apache (an it's indeed the host).
The last line in the netstat output shows that some process made a connection to 151.101.48.204:80, probably to make an HTTP request. You can see the PID/name of the process with netstat -p.

Hit a service running on localhost from inside a docker image

I'm on mac os, I have a service running on my machine on localhost:8000
now I want to launch a docker image and hit this service from here.
I did a docker bridge and I use it from inside, but it is not working.
Here are my steps:
My host ip:
ifconfig
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 98:01:a7:b0:2b:41
inet 192.168.0.70 netmask 0xffffff00 broadcast 192.168.0.255
media: autoselect
status: active
I hit my service from host:
curl localhost:8000 #this is working!
I create a bridge and I use it:
docker network create -d bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 dockernet
docker run --rm -it -v "$(pwd):/src" --network=dockernet qatests /bin/bash
from inside docker, I do a curl but it is not working:
curl 192.168.0.1:8000 #it's not working :-(
any ideas?
You dont need to create a new network. You can use the default one (bridge).
Just check which ip is associated to the docker0 interface in your host with ip or ifconfig (in my case is 172.17.42.1), and use that ip from inside the container:
$ curl 172.17.42.1:8000
In the end, I've discovered that if I ping my pc ip, I can see it even from the docker image.
For convenience, I did a lounch script witch get my current IP and launch the docker image making my ip accessible under "mymac" address
So what i did is lunching
MY_IP=$(ifconfig en0 | grep inet | grep -v inet6 | awk '{print $2}')
docker run --rm -it -v "$(pwd):/src" --add-host=mymac:$MY_IP qatests
/bin/bash
inside docker I can now lunch:
curl mymac:8000 #it works! now mymac is my pc outside docker

Open docker daemon container to outside

The docker daemon container is isolated from outside when we run it below,
$ docker run -d --name test_container ubuntu/ping \
/bin/sh -c "while true do echo hello world; sleep 1; done"
$ docker inspect test_container | grep IPAddress
[ip of test_container]
$ ping [ip of test_container]
[timeout]
$ ifconfig docker0 | grep "inet addr"
[ip of docker bridge]
$ ping [ip of docker bridge]
[ok]
$ docker exec -it test_container /bin/bash
# ping [ip of test_container]
[ok]
# ping [ip of docker bridge]
[timeout]
How to open the ip address of the docker daemon container inside out?
By default docker daemon is running on a unix socket
You can enable to listen on tcp socket by doing :
docker daemon -H tcp://validIpOnYourHost:port
By default port is 2375 if you do not provide some.
cf this page for more explanation : https://docs.docker.com/v1.11/engine/reference/commandline/daemon/
Be careful, if you expose docker throught TCP, this is not security enabled.
Probably I replied to something else, after reading your question :
could you do a :
docker network inspect bridge
and paste the json output.
I had similar issues when the attribute :
"com.docker.network.bridge.enable_ip_masquerade"
was set to false

Remote debugging JVM in docker on AWS EB

I have a docker image in which I start jstatd -p 1099 and then my Java app. I also expose port 1099 in the dockerfile.
I have deployed this docker image to AWS ElasticBeanstalk and I can see from the EB logs that the port is exposed.
/var/log/docker-ps.log
-------------------------------------
'docker ps' ran at Fri Jun 17 04:23:02 UTC 2016:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3199a65e216 8b9c53bb10b6 "/app/run.sh" 5 minutes ago Up 5 minutes 1099/tcp, 8080/tcp jolly_carson
I would now like to profile the app using VisualVM. How can I find the correct ip to connect to? Attempts to telnet to the app's domain name on port 1099 time out.
The container's port is not bound to the instance's port, which is good because you don't want to expose your debugging interface publicly. The IP address of the container can be found with:
$ sudo docker ps
$ sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container_id>
Start an SSH tunnel that tunnels from port 5005 locally to that IP address and port 5005 on the box.
$ ssh ec2-user#ec2-54-204-111-222.compute-1.amazonaws.com -L 5005:<ip>:5005 -N
or you can configure port forwarding over iptables
$ sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' stupefied_swartz
172.17.0.2
$ sudo iptables -t nat -A PREROUTING -p tcp --dport 5005 -j REDIRECT --to-destination 172.17.0.2:5005

Resources