Using a Dockerfile to modify a container

In the previous post I modified a CentOS Docker container image to include the man application as a simple example. But it was not obvious looking at the container what modifications, if any, had been made. I wanted instead to specify the installation of man via a Dockerfile so that the modifications to the base OS would be more clear to another user.

First, I create a new empty directory and create a Dockerfile within the directory:

$ mkdir man-centos
$ cd man-centos
$ vi Dockerfile

In the Dockerfile, I specify that I want to use the publicly-available CentOS 7 base image, and then install the man package via yum:

# Start with CentOS 7
FROM centos:7

# Install the man yum module
RUN yum -y install man

Then build and run the container:

$ docker build -t man-centos .
$ docker run -i -t man-centos
[root@6f597c97d72d /]# man man
No manual entry for man

It works!

Running CentOS in a Docker container

I’m just getting started with Docker. I’ve thought for years that containerization is a great idea, but I haven’t actually done anything with containers yet. Time to get started.

I ran through a couple tutorials on the Docker docs site and created a cloud.docker.com account to get some basic familiarity.

I found the CentOS container repository on Docker Hub: https://hub.docker.com/_/centos/

Let’s try running it!

$ docker pull centos
$ docker run centos

Did it do anything? It looks like it did something. At least, it didn’t give me an error. What did it do? How do I access it?

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Nothing is actively running. That makes sense, because we’re not telling the containerized OS to do anything — it starts, it doesn’t have anything to do, and so it shuts down immediately. Instead we can tell it to run interactively and with a terminal by specifying a couple options:

-i, --interactive
-t, --tty
(“allocate a pseudo-TTY”, i.e. a terminal)
(see docker run --help for details)

$ docker run -i -t centos
[root@4f0b435cdbd7 /]#

I’m in!

What if I want to modify the container? Right now it is pretty bare-bones. For example, this doesn’t even have man installed:

[root@4f0b435cdbd7 /]# man man
bash: man: command not found

[root@4f0b435cdbd7 /]# yum install man
...
[root@4f0b435cdbd7 /]# man man
No manual entry for man

Quite the improvement! Now we need to save our change:

[root@4f0b435cdbd7 /]# exit

$ docker commit 4f0b435cdbd7 man-centos
$ docker run -i -t man-centos

[root@953c512d6707 /]# man man
No manual entry for man

Progress! Now we have a CentOS container where man is already installed. Exciting.

I can’t (that I know of) inspect the container and know whether or not man is installed without running it. That’s fine for many cases, but next I will attempt to figure out how specify via a Dockerfile that man is installed.

Error: Cannot contact any KDC for realm while getting initial credentials

I’ve been testing FreeIPA on a small network of CentOS 7 hosts (all virtual machines running in VirtualBox on a host-only network). After installing the IPA server on one host and creating the realm (IPA.OSRIC.NET), I installed the IPA client on one of the other hosts and tried running kinit:

# kinit admin
kinit: Cannot contact any KDC for realm 'IPA.OSRIC.NET' while getting initial credentials

Searching for that error brought me to Kinit won’t connect to a domain server. Although that did not describe the same issue, it did point me to the /etc/krb5.conf file. The realms section looked like it was missing something:

[realms]
  IPA.OSRIC.NET = {
    pkinit_anchors = FILE:/etc/ipa/ca.crt

  }

I added a kdc attribute:

[realms]
  IPA.OSRIC.NET = {
    kdc = prospero.osric.net:88
    pkinit_anchors = FILE:/etc/ipa/ca.crt
 
  }

No restart of any service was necessary. I ran kinit again and it worked:

# kinit admin
Password for admin@IPA.OSRIC.NET:

According to the krb5.conf documentation on realms:

kdc
The name or address of a host running a KDC for that realm. An optional port number, separated from the hostname by a colon, may be included.

I’m a Kerberos novice, but that seems like a necessary property. I’m not sure why the IPA client setup did not include it. I have a few more virtual machines to install the client on, so I’ll soon find if that behavior is consistent on subsequent installations.

Missing Nagios plugins in CentOS 7

I set up a Nagios server on a CentOS 7 VM (Virtual Machine):

sudo yum install epel-release
sudo yum install nrpe
sudo yum install nagios

By default it sets up some basic checks for localhost. When I checked the Nagios site at http://127.0.0.1/nagios/, I found that even PING was critical:

(No output on stdout) stderr: execvp(/usr/lib64/nagios/plugins/check_ping, ...) failed. errno is 2: No such file or directory

I checked the contents of the plugins directory:

# ls /usr/lib64/nagios/plugins
eventhandlers negate urlize utils.sh

Sure enough, the usual suspects are not there. E.g.:

  • check_load
  • check_ping
  • check_disk
  • check_http
  • check_procs

Eventually I stumbled onto the following document, /usr/share/doc/nagios-plugins-2.0.3/README.Fedora:

Fedora users

Nagios plugins for Fedora have all been packaged separately. For
example, to isntall the check_http just install nagios-plugins-http.

All plugins are installed in the architecture dependent directory
/usr/lib{,64}/nagios/plugins/.

I installed some of the plugins following that convention:

sudo yum install nagios-plugins-load
sudo yum install nagios-plugins-ping
sudo yum install nagios-plugins-disk
sudo yum install nagios-plugins-http
sudo yum install nagios-plugins-procs

Now the the corresponding plugins exist in /usr/lib64/nagios/plugins, and Nagios reports OK for those checks on localhost.