Port forwarding in docker-machine?

2020-01-27 11:53发布

问题:

Since boot2docker is deprecated I've switched to docker-machine but I don't know how to open a port from docker-machine. In boot2docker I could do like this:

boot2docker ssh -L 27017:localhost:27017

This would forward port 27017 from VirtualBox to localhost 27017 as long as the SSH connection is open. Note that I'm not looking for a way to open the port permanently in VirtualBox. How can I achieve this with docker-machine?

回答1:

You can still access the VBoxmanage.exe command from the VirtualBox used by docker machine:

VBoxManage controlvm "boot2docker-vm" natpf1 "tcp-port27017,tcp,,27017,,27017";
  • Use docker-machine info to get the name of your vm.
  • use modifyvm if the vm isn't started yet.

See a practical example in this answer.


That is the current workaround, pending the possibility to pass argument to docker-machine ssh: see issue 691.

The other workaround is to not forward port, and use directly the IP of the VM:

 $(docker-machine ip default)

As commented by sdc:

You can confirm that port forwarding is set up correctly with

 VBoxManage showvminfo boot2docker-vm | grep "NIC.* Rule" 


回答2:

With recent versions of machine, you can simply do (where default is the name of the machine):

docker-machine ssh default -L 27017:localhost:27017

This is a more temporary solution than the VM configuration change.

Use the following variation to only forward ports in a background process:

docker-machine ssh default -f -N -L 27017:localhost:27017
  • -f Requests ssh to go to background just before command execution.
  • -N Allow empty command (useful here to forward ports only)


回答3:

You can ssh into the machine and pass on the regular port forwarding arguments:

ssh docker@$(docker-machine ip default) -L 27017:localhost:27017

The password of the docker user is tcuser. (see https://github.com/boot2docker/boot2docker)



回答4:

Since I have hard time remembering how to do this I've created a small bash script called pf (which stands for "port forward") that allows you to do:

$ pf 8080

This will forward the docker port 8080 to host port 8080 in the background (append -f to make it run in the foreground). To use a different host port just do:

$ pf 8090:8080

which maps the host port 8090 to 8080.

To stop the port forwarding add -s:

$ pf 8090:8080 -s

(actually host port is enough as well: pf 8090 -s). There are other options available as well so checkout the github page.



回答5:

If you don't want the need to use passwords, I would add that you should just point to the private key.

ssh -L 8080:localhost:8080 -i ~/.docker/machine/machines/default/id_rsa docker@$(docker-machine ip default)


回答6:

Just to enhance in script the answer of @VonC - currently if using Docker Toolbox on MacOS X, the default VM machine is "default". So a script to map all the exposed from container should look like:

for port in `docker port cassandra | cut -d'-' -f1`; 
do 
    port_num=`echo ${port} | cut -d'/' -f1`
    port_type=`echo ${port} | cut -d'/' -f2`
    echo "Create rule natpf1 for ${port_type} port ${port_num}"
    VBoxManage controlvm "default" natpf1 "${port_type}-port${port_num},${port_type},,${port_num},,${port_num}"
done

if you try to execute several times, a statement before creation should be added for deleting the existing rule:

VBoxManage controlvm "default" natpf1 delete "${port_type}-port${port_num}"

In the script it assumes that you have already port forward the ports from container to VM.

docker port cassandra

gives output like:

7000/tcp -> 0.0.0.0:7000