Chapter 7. Running Services in a Container

We've reached so far, brick by brick, laying a strong and stimulating foundation on the fast-evolving Docker technology. We talked about the important building blocks of the highly usable and reusable Docker images. Further on, you can read the easy-to-employ techniques and tips on how to store and share Docker images through a well-designed storage framework. As usual, images will have to go through a series of verifications, validations, and refinements constantly in order to make them more right and relevant for the aspiring development community. In this chapter, we are going to take our learning to the next level by describing the steps towards creating a small web server, run the same inside a container, and connect to the web server from the external world.

In this chapter, we will cover the following topics:

  • Container networking
  • Container as a Service (CaaS)—building, running, exposing, and connecting to container services
  • Publishing and retrieving container ports
  • Binding a container to a specific IP address
  • Auto-generating the Docker host port
  • Port binding using the EXPOSE and -P options

A brief overview of container networking

Like any computing node, the Docker containers need to be networked, in order to be found and accessible by other containers and clients. In a network, generally, any node is being identified through its IP address. Besides, the IP address is a unique mechanism for any client to reach out to the services offered by any server node. Docker internally uses Linux capabilities to provide network connectivity to containers. In this section, we are going to learn about the container's IP address assignment and the procedure to retrieve the container's IP address.

The Docker engine seamlessly selects and assigns an IP address to a container with no intervention from the user, when it gets launched. Well, you might be puzzled on how Docker selects an IP address for a container, and this puzzle is answered in two parts, which is as follows:

  1. During the installation, Docker creates a virtual interface with the name docker0 on the Docker host. It also selects a private IP address range, and assigns an address from the selected range to the docker0 virtual interface. This selected IP address is always outside the range of the Docker host IP address in order to avoid an IP address conflict.
  2. Later, when we spin up a container, the Docker engine selects an unused IP address from the IP address range selected for the docker0 virtual interface. Then, the engine assigns this IP address to the freshly spun container.

Docker, by default, selects the IP address 172.17.42.1/16, or one of the IP addresses that is within the range 172.17.0.0 to 172.17.255.255. Docker will select a different private IP address range if there is a direct conflict with the 172.17.x.x addresses. Perhaps, the good old ifconfig (the command to display the details of the network interfaces) comes in handy here to find out the IP address assigned to the virtual interface. Let's just run ifconfig with docker0 as an argument, as follows:

$ ifconfig docker0

The second line of the output will show the assigned IP address and its netmask:

inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0

Apparently, from the preceding text, 172.17.42.1 is the IP address assigned to the docker0 virtual interface. The IP address 172.17.42.1 is one of the addresses in the private IP address range from 172.17.0.0 to 172.17.255.255.

It's now imperative that we learn how to find the IP address assigned to a container. The container should be launched in an interactive mode using the -i option. Of course, we can easily find the IP by running the ifconfig command within the container, as shown here:

$ sudo docker run -i -t ubuntu:14.04 /bin/bash
root@4b0b567b6019:/# ifconfig

The ifconfig command will display the details of all the interfaces in the Docker container, as follows:

eth0      Link encap:Ethernet  HWaddr e6:38:dd:23:aa:3f
          inet addr:172.17.0.12  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::e438:ddff:fe23:aa3f/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:2 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:488 (488.0 B)  TX bytes:578 (578.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Evidently, the preceding output of the ifconfig command shows that the Docker engine has virtualized two network interfaces for the container, which are as follows:

  • The first one is an eth0 (Ethernet) interface for which the Docker engine assigned the IP address 172.17.0.12. Obviously, this address also falls within the same IP address range of the docker0 virtual interface. Besides, the address assigned to the eth0 interface is used for intra-container communication and host-to-container communication.
  • The second interface is the lo (Loopback) interface for which the Docker engine assigned the loopback address 127.0.0.1. The loopback interface is used for local communication within a container.

Easy, isn't it? However, the retrieval of an IP address gets complicated when the container is launched in the detached mode, using the -d option in the docker run subcommand. The primary reason for this complication in the detached mode is that there is no shell prompt to run the ifconfig command. Fortunately, Docker provides a docker inspect subcommand, which is as handy as a Swiss army knife, and allow us to dive deep into the low-level details of the Docker container or image. The docker inspect subcommand generates the requested details in the JSON array format.

Here is a sample run of the docker inspect subcommand on the interactive container that we previously launched. The 4b0b567b6019 container ID is taken from the prompt of the container:

$ sudo docker inspect 4b0b567b6019

This command generates quite a lot of information about the container. Here, we show some excerpts of the container's network configuration from the output of the docker inspect subcommand:

"NetworkSettings": {
        "Bridge": "docker0",
        "Gateway": "172.17.42.1",
        "IPAddress": "172.17.0.12",
        "IPPrefixLen": 16,
        "PortMapping": null,
        "Ports": {}
    },

Here, the network configuration lists out the following details:

  • Bridge: This is the bridge interface to which the container is bound
  • Gateway: This is the gateway address of the container, which is the address of the bridge interface as well
  • IPAddress: This is the IP address assigned to the container
  • IPPrefixLen: This is the IP prefix length, another way of representing the subnet mask
  • PortMapping: This is the port mapping field, which is now being deprecated, and its value is always null
  • Ports: This is the ports field that will enumerate all the port binds, which is introduced later in this chapter

There is no doubt that the docker inspect subcommand is quite convenient for finding the minute details of a container or an image. However, it's a tiresome job to go through the intimidating details and to find the right information that we are keenly looking for. Perhaps, you can narrow it down to the right information, using the grep command. Or even better, the docker inspect subcommand, which helps you pick the right field from the JSON array using the --format option of the docker inspect subcommand.

Notably, in the following example, we use the --format option of the docker inspect subcommand to retrieve just the IP address of the container. The IP address is accessible through the .NetworkSettings.IPAddress field of the JSON array:

$ sudo docker inspect 
  --format='{{.NetworkSettings.IPAddress}}' 4b0b567b6019
172.17.0.12
..................Content has been hidden....................

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