Validating Docker containers
Container Inspection
If a customs officer wants to know whether a freighter from, say, Brazil really has bananas on board, they simply look inside the containers. Google's test tool with the somewhat unwieldy name Container Structure Test (CST) [1] basically follows the same principle.
The tool walks into a predefined Docker container, performs various user-defined tests, and logs the results of the individual checks in detail at the command line. Automatically, you can ensure, among other things, that a container actually contains MySQL and not bananas.
Compact Friend
CST currently supports four different test types. First, developers can use it to inspect the filesystem to find out whether the configuration file for the database is in the right place and has the appropriate access privileges. Additionally, the tool takes a look at text files and searches for given strings.
For example, the user-generated tests check whether the database configuration file reserves enough cache space. If required, CST can call any command in the Docker container and examine its output. In this way, you could ask the package manager whether a specific package is installed.
Finally, the tool also checks the configuration and metadata of the container on request, which makes it possible, for example, to ensure that the operator has set all the required environment variables correctly in the container.
With the appropriate tests, the test suite ensures that a new Docker container complies with the required or prescribed specification, even before it is put into operation. For example, if a prepackaged MySQL container from Docker Hub suddenly comes with a new version of the database, the CST tool immediately notices this. In this way, you don't have to wait for the web application to deliver mysterious error messages during live operation to know the API has changed.
CST also ensures more robust operation of the complete infrastructure. The tool can also be integrated easily into an existing workflow and launched automatically (e.g., whenever a container is updated).
However, the tool does not take a close look at running Docker containers. Moreover, the quality of the test results depends to a large extent on the stored tests. For example, if a developer forgets to check the MySQL version, the test tool will not complain about an outdated database.
Command Set
Although Google refers to CST as a test framework, it actually only consists of a command-line tool written in Go. CST carries out all the intended tests and returns a test report when done. The source code is licensed under the Apache 2.0 license and is available from GitHub [1].
For 64-bit systems, the prebuilt tool is available on the Google servers [2]. You only have to download the program and make it executable, thus removing the need to install. If you want to use the tool globally on a system, the Google developers recommend installing with the one-liner:
curl -LO https://storage.googleapis.com/container-structure-test/latest/container-structure-test-linux-amd64 && chmod +x container-structure-test-linux-amd64 && sudo mv container-structure-test-linux-amd64 /usr/local/bin/container-structure-test
All following examples assume that the test tool file name is container-structure-test
and is accessible in the search path.
Delivery Notes
Developers add the tests to be performed to a text file with either YAML or JSON notation, which means that the tests can even be generated or modified by other tools or scripts. A simple test example in YAML notation is shown in Listing 1, which first checks whether the MySQL server is installed in the container. It then inspects the associated configuration file, which must be found at the specified location and must contain a special setting. CST ignores all lines starting with a hash (#
).
Listing 1
Sample MySQL Container Config
01 schemaVersion: "2.0.0" 02 03 globalEnvVars: 04 - key: "MYSQL_USER" 05 value: "dev" 06 - key: "MYSQL_PASSWORD" 07 value: "123456" 08 09 commandTests: 10 11 # Is the MySQL package installed? 12 - name: "MySQL package installed" 13 command: "rpm" 14 args: ["-q", "mysql-community-server-minimal"] 15 expectedOutput: "["mysql-community-server-minimal*"] 16 17 fileExistenceTests: 18 19 # Does the MySQL client exist in the container? 20 - name: "mysql client exists" 21 path: '/usr/bin/mysql' 22 shouldExist: true 23 24 # Does the MySQL configuration file exist at the right place? 25 - name: "my.cnf exists and has appropriate permissions" 26 path: '/etc/my.cnf' 27 shouldExist: true 28 permissions: '-rw-r--r--' 29 30 fileContentTests: 31 32 # Does the configuration file my.conf have the correct content? 33 - name: 'Content of my.cnf' 34 path: '/etc/my.cnf' 35 expectedContents: "["datadir=/var/lib/mysql\n"] 36 37 metadataTest: 38 env: 39 - key: "PATH" 40 value: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 41 exposedPorts: ["3306", "33060"] 42 volumes: "["/test"] 43 entrypoint: [/entrypoint.sh] 44 cmd: ["mysqld"]
How developers need to define each test is specified in a matching schema. At the beginning of Listing 1, schemaVersion: "2.0.0"
reveals that the test descriptions that follow use the 2.0.0 schema. Without this information, the tool immediately denies service.
Under globalEnvVars
(lines 3-7; note that the colon is left out in the text explanation throughout to avoid punctuation confusion) you set environment variables in the container before starting the tests; key
is followed by the environment variable itself, and the variable's content follows the value
keyword. Listing 1 uses this to pass the logon credentials for the database into the container. The container then has a MYSQL_USER
environment variable containing dev
, and MYSQL_PASSWORD
has the password 123456
. These environment variables can now be used for the tests.
The commandTests
section (lines 9-15) lets you list the checks for which the tool must execute a command in the Docker container. The single test in Listing 1 asks the RPM package manager whether the mysql-community-server-minimal
package is installed in the container.
Like all other tests, it has a short description after name
. In Listing 1 this is MySQL package installed
. The test framework will use this in the log later, so you should choose intuitive and unambiguous names.
Buy this article as PDF
(incl. VAT)