Building a test container

One of the tenants of building Docker containers is to keep them small and lean. In some cases, this can limit your troubleshooting options as the containers won't have many of the common Linux networking tools as part of their image. While not ideal, it is sometimes nice to have a container image that has these tools installed so that you can troubleshoot the network from the container perspective. In this chapter, we'll review how to build a Docker image specifically for this purpose.

Getting ready

In this recipe, we'll be using a single Docker network host. It is assumed that Docker is installed and in its default configuration. You'll also need root-level access in order to inspect and change the hosts networking and firewall configuration.

How to do it…

A Docker image is built by defining a Dockerfile. The Dockerfile defines what base image to use as well as commands to run inside of the container. In my example, I'll define the Dockerfile as follows:

FROM ubuntu:16.04
MAINTAINER Jon Langemak [email protected]
RUN apt-get update && apt-get install -y apache2 net-tools 
inetutils-ping curl dnsutils vim ethtool tcpdump
ADD index.html /var/www/html/index.html
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_PID_FILE /var/run/apache2/apache2.pid
ENV APACHE_LOCK_DIR /var/run/apache2
RUN mkdir -p /var/run/apache2
RUN chown www-data:www-data /var/run/apache2
EXPOSE 80
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]

The goal of this image is twofold. First, I wanted to be able to run the container in detached mode and have it offer a service. This would allow me to define the container and verify that things such as port publishing were working off the host. This container image provides me with a known good container that will publish a service on port 80. For this purpose, we're using Apache to host a simple index page.

The index file is pulled into the image at build time and can be customized by you. I use a simple HTML page, index.html, that shows big red font such as this:

<body>
  <html>
    <h1><span style="color:#FF0000;font-size:72px;">Test Web Server - Running on port 80</span>
    </h1>
</body>
  </html>

Second, the image has a lot of network tools installed as part of the image. You'll notice that I'm installing the following packages:

  • net-tools: This provides network utilities to view and configure interfaces
  • inetutils-ping: This provides ping functionality
  • curl: This is to pull files from other network endpoints
  • dnsutils: This is to resolve DNS names and other DNS tracing
  • ethtool: This is to get information and stats from interfaces
  • tcpdump: This is to do packet capture from within the container

If you define this Dockerfile, as well as it's required supporting files (an index page), you can build the image as follows:

sudo docker build -t <tag name for image> <path files ('.' If local)>

Note

There are a lot of options you can define when building an image. Take a look at docker build --help for more information.

Docker will then process the Dockerfile and, if successful, it will generate a docker image file, which you can then push to your container registry of choice for consumption on other hosts with docker pull.

Once built, you can run it and verify that the tools are working as expected. Having ethtool within the container means that we can easily determine the host-side VETH end of the VETH pair:

user@docker1:~$ docker run -dP --name nettest jonlangemak/net_tools
user@docker1:~$ docker exec -it nettest /bin/bash
root@2ef59fcc0f60:/# ethtool -S eth0
NIC statistics:
     peer_ifindex: 5
root@2ef59fcc0f60:/#

We can also perform local tcpdump actions to verify traffic reaching the container:

root@2ef59fcc0f60:/# tcpdump -qnn -i eth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:17:43.442243 IP 10.20.30.41.54974 > 172.17.0.3.80: tcp 0
15:17:43.442286 IP 172.17.0.3.80 > 10.20.30.41.54974: tcp 0

As your use cases change, you can modify the Dockerfile to make it more specific to your own use cases. Being able to troubleshoot from within the container can be a big help when diagnosing connectivity issues.

Note

This image is just an example. There are many ways that this can be made more lightweight. I decided to use Ubuntu as the base image just for the sake of familiarity. The image described earlier is fairly heavy because of this.

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

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