25

I am running this on ubuntu 14.04 and have set docker0 to a static ip which is then routed to from the public ip through the firewall. I am trying to set up my backend API to run in a docker container and am confused by a couple things.

1.) How would I map docker0's ip to the container's ip such that docker0 would know to send the incoming packets to the container (dynamically if possible).

2.) If not already done in such a way, how could I make it so that I don't have to set this up every time I do a fresh run of that docker container?

Thanks in advance!

robert
  • 819
  • 1
  • 10
  • 24
  • 1
    Have you considered the --net=host option? see: https://docs.docker.com/articles/networking/#container-networking – Mark O'Connor Oct 25 '14 at 00:13
  • What do you mean by sending the incoming packets dynamically? Supposing that the backend API responds to HTTP, what about setting up an HTTP proxy that can also handle other stuff, e.g. SSL offloading etc. – andi5 Nov 02 '14 at 18:32

2 Answers2

40

I assume you want to have an IP assigned to your docker container outside of docker.

First, create a new IP and assign it to your host's interface (we assume your interface is called eth0.

$> ip addr add 10.0.0.99/8 dev eth0

Now, when you fire up the container, specify that address and link it to your docker container:

$> docker run -i -t --rm -p 10.0.0.99:80:8080 base

The -p argument will make docker create an iptables NAT rule which will nat all the traffic matching the destination 10.0.0.99:80 to your docker container on port 8080.

If you need to automate the process and scale it out, consult this resource: https://github.com/jpetazzo/pipework

The docker documentation is a good start: https://docker.github.io/engine/userguide/networking/

WoJ
  • 27,165
  • 48
  • 180
  • 345
nucatus
  • 2,196
  • 2
  • 21
  • 18
  • 2
    Yes but how do you map a containers outgoing ports to a host IP? – Duncan Calvert Jan 06 '15 at 17:23
  • 1
    I don't think you need to do that. In most situations, when the communication is initiated by an application residing in the container, the source port is dynamic, so you don't need a mapping. What would be the application where you need to map the source port? Moreover, having fix ports for client application poses a security risk, therefor, source ports have to be randomized. More details here [RFC6056](https://tools.ietf.org/html/rfc6056) – nucatus Jan 08 '15 at 21:47
  • 1
    > What would be the application where you need to map the source port? -- an MRCP (RFC 6787) server, for example. Is there any way to really assign public IP address to a container? – Alexey Naidyonov Dec 08 '15 at 15:36
  • I am not sure about the requirements of the MRCP, but I doubt it requires a fix source port. Can you please link here the paragraph in the documentation where that is specified? – nucatus Dec 13 '15 at 00:38
  • Yes, you can assign a public IP to the container. You create IP alias on the NIC for the public IP and that link that IP to the container as I stated in the answer above. – nucatus Dec 13 '15 at 00:40
9

Recently I had the same problem and solved it using Network Containers:

  • Start my 'service' container that I want to be available on the public IP
  • Create a new 'network' container that is linked with the service container and does routing to the ports exposed by the service container. This container will have an extra network interface bridged with the host so it can acquire an IP from DHCP.
  • Create a network bridge from the Docker host to the container using jpetazzo's Pipework (https://github.com/jpetazzo/pipework)
  • The network container acquires an address from DHCP.

From this point on the network container is available on the network and routes the ports to the service container. The main advantage is that the 'service' container does not have to know about the public IP, DHCP, etc. This way every running container can be made public on the network.

For convenience, I created a script that does all of this at once. Making a running container available on a public IP is as simple as:

create-network-container.sh webserver ens32

In this case you would need to have a running container called 'webserver', and a network interface on the host 'ens32'. The interface is needed in order to create the bridge into the network container.

The script, more detailed info and examples are available on: https://github.com/jeroenpeeters/docker-network-containers

Jeroen Peeters
  • 1,974
  • 1
  • 20
  • 24