Autogenerating the Docker host port

The Docker containers are innately lightweight and due to their lightweight nature, you can run multiple containers with the same or different service on a single Docker host. Particularly, autoscaling of the same service across several containers based on the demand is the need of the IT infrastructure today. Here, in this section, you will be informed about the challenge in spinning up multiple containers with the same service and also the Docker's way of addressing this challenge.

Earlier in this chapter, we launched a container using Apache2 HTTP server by binding it to port 80 of the Docker host. Now, if we attempt to launch one more container with the same port 80 binding, the container would fail to start with an error message, as you can see in the following example:

$ sudo docker run -d -p 80:80 apache2
6f01f485ab3ce81d45dc6369316659aed17eb341e9ad0229f66060a8ba4a2d0e
2014/11/03 23:28:07 Error response from daemon: Cannot start container
6f01f485ab3ce81d45dc6369316659aed17eb341e9ad0229f66060a8ba4a2d0e:
Bind for 0.0.0.0:80 failed: port is already allocated

Obviously, in the preceding example, the container failed to start because the previous container is already mapped to 0.0.0.0 (all the IP addresses of the Docker host) and port 80. In the TCP/IP communication model, the combination of the IP address, port, and the transport protocols (TCP, UDP, and so on) has to be unique.

We could have overcome this issue by manually choosing the Docker host port number (for instance, -p 81:80 or -p 8081:80). Though this is an excellent solution, it does not scale well for autoscaling scenarios. Instead, if we give the control to Docker, it would autogenerate the port number on the Docker host. This port number generation is achieved by underspecifying the Docker host port number, using the -p <containerPort> option of the docker run subcommand, as shown in the following example:

$ sudo docker run -d -p 80 apache2
ea3e0d1b18cff40ffcddd2bf077647dc94bceffad967b86c1a343bd33187d7a8

Having successfully started the new container with the autogenerated port, let's review the port mapping as well the NAT entry for the preceding example:

  • The following text is an excerpt from the output of the docker ps subcommand that shows the details of this container:
      ea3e0d1b18cf        apache2:latest      "/usr/sbin/apache2ct          
5 minutes ago Up 5 minutes 0.0.0.0:49158->80/tcp
nostalgic_morse
  • The following text is an excerpt from the output of the iptables -n nat -L -n command that shows the DNAT entry created for this container:
      DNAT    tcp -- 0.0.0.0/0      0.0.0.0/0      tcp dpt:49158 
to:172.17.0.18:80

After reviewing both the output of the docker run subcommand and the DNAT entry of iptables, what stands out is the 49158 port number. The 49158 port number is niftily autogenerated by the Docker Engine on the Docker host, with the help of the underlying operating system. Besides, the 0.0.0.0 meta IP address implies that the service offered by the container is accessible from outside, through any of the valid IP addresses configured on the Docker host.

You may have a use case where you want to autogenerate the port number. However, if you still want to restrict the service to a particular IP address of the Docker host, you can use the -p <IP>::<containerPort> option of the docker run subcommand, as shown in the following example:

$ sudo docker run -d -p 198.51.100.73::80 apache2
6b5de258b3b82da0290f29946436d7ae307c8b72f22239956e453356532ec2a7

In the preceding two scenarios, the Docker Engine autogenerated the port number on the Docker host and exposed it to the outside world. The general norm of network communication is to expose any service through a predefined port number so that anybody knows the IP address, and the port number can easily access the offered service. Whereas, here the port numbers are autogenerated and as a result, the outside world cannot directly reach the offered service. So, the primary purpose of this method of container creation is to achieve autoscaling, and the container created in this fashion would be interfaced with a proxy or load balance service on a predefined port.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset