Today, we are going to show how Anchore technology fits into a Docker-based container workflow to provide trust, insight, and validation to your container ecosystem without inhibiting the flexibility, agility, and speed of development that makes container-based deployment platforms so valuable. This post will walk through using Anchore in a deployment scenario for a container-based application.

And we’ll also discuss the container registry, curation, and management capabilities of Anchore as well as analysis, control, inspection, and review of containers.

The rest of this document is organized around a container-based application deployment workflow composed of the following basic phases:

  1. Creation of trusted well-known base containers
  2. Creation and validation of application containers built by developers or a CI/CD system
  3. Analysis of containers to determine acceptance for production use prior to deployment

This post will present both an operations and a developer perspective on each phase, and describes how Anchore operates in each one.

Setup and Creating Anchore Curated Containers

Starting with the operations perspective, the first step is to create a registry that hosts trusted containers, and exposes them to development teams for use as the base containers from which application containers are built. This is the job of the Anchore registry management tool. The tool creates a local registry and orchestrates the images pulled fromDocker Hub (or another public-facing registry) with the image analysis metadata provided by the Anchore service.

So, let’s first create a local registry and sync it to Anchore. Starting with an installed registry tool, run the initcommand to initialize the registry and do an initial sync:

[root@tele ~]# anchore-registry init
Creating new anchore anchore-reg at /root/.local/
[root@tele ~]#

After the command is run, the registry is now initialized and contains some metadata about the base subscribed images as well as vulnerability data. You can view the set of subscribed containers by running the subscriptions command

[root@tele ~]# anchore-registry subscriptions
[]
[root@tele ~]#

To subscribe to a few more containers, for example mongo and redis, run the subscribe command. This command will not pull any data, only change the subscription values:

[root@tele ~][root@tele ~]# anchore-registry subscribe centos ubuntu mysql redis
Subscribing to containers [u’centos’, u’ubuntu’, u’mysql’, u’redis’]
Checking sources: [u’ubuntu’, u’centos’, u’busybox’, u’postgres’, u’mysql’,
u’registry’, u’redis’, u’mongo’, u’couchbase’, u’couchdb’]
[root@tele ~]#
[root@tele ~]# anchore-registry subscriptions
[u’centos’, u’ubuntu’, u’mysql’, u’redis’]
[root@tele ~]# 

To pull those containers and metadata from Anchore, run the sync command:

[root@tele ~]# anchore-registry sync
Synchronizing anchore registry with remote
[root@tele ~]#

By synchronizing with Anchore, we now have the ability to inspect the container to see what kind of analysis and information you get from a curated Anchore container. Let’s search those containers for specific packages.

We now have the ability to “navigate” the information that Anchore gathers about the subscribed containers. For example, you can find all of the containers that have a particular package installed:

[root@tele ~]# anchore --allanchore navigate --search --has-package ‘ssl*’
+--------------+--------------------+----------------------+-------------------+---------------------+
| ImageId | Current Repo/Tags | Past Repo/Tags | Package | Version |
+--------------+--------------------+----------------------+-------------------+---------------------+
| 778a53015523 | centos:latest | centos:latest | openssl-libs | 1.0.1e-51.el7_2.4 |
| f48f462dde2f | devone:apr15 | devone:latest | openssl-libs | 1.0.1e-51.el7_2.4 |
| | devone:latest | devone:apr15 | | |
| 0f0e96f1f267 | redis:latest | redis:latest | libssl1.0.0:amd64 | 1.0.1k-3+deb8u4 |
| b72889fa879c | | ubuntu:latest | libssl1.0.0:amd64 | 1.0.1f-1ubuntu2.18 |
| b72889fa879c | | ubuntu:latest | libgnutls- | 2.12.23-12ubuntu2.5 |
| | | | openssl27:amd64 | |
+--------------+--------------------+----------------------+-------------------+---------------------+
[root@tele ~]#

That output shows us which images in the local docker repo contain the ssl* package.

Analyzing Changed Containers

Now, assume that a developer has built an application container using one of the curated Anchore images and has pushed that container back into the local docker repo. In order to determine if this developer container is okay to push into production, it’s helpful to see how the container changed from its parent image (in the FROM clause of the dockerfile).

Anchore provides a specific report for this that gives insight into exactly what has changed at a file, package, and checksum level. If, for example, the developer built the container with the following steps:

[root@tele ~]# cat Dockerfile
FROM centos:latest
RUN yum -y install wget
CMD ["/bin/echo", "HELLO WORLD FROM DEVONE"]
[root@tele ~]#

[root@tele ~]# docker build --no-cache=True -t devone .
...
...
Successfully built f48f462dde2f
[root@tele ~]#

First, we need to run the analysis tools on the image. For convenience we can just specify all local images (those already processed are skipped). The result of this command is locally stored analysis data for the images that have not been analyzed yet:

[root@tele ~]# anchore --image devone analyze --dockerfile
./DockerfileRunning analyzers: 2791834d4281 ...SUCCESS
Running analyzers: f48f462dde2f ...SUCCESS
Running analyzers: 778a53015523 ...SUCCESS
Running differs: f48f462dde2f to 778a53015523...SUCCESS
Running differs: 778a53015523 to f48f462dde2f...SUCCESS
[root@tele ~]#

Now, we can view the reports and metadata that resulted from the analysis pass:

[root@tele ~]# anchore --image devone analyze --dockerfile
./DockerfileRunning analyzers: 2791834d4281 ...SUCCESS
Running analyzers: f48f462dde2f ...SUCCESS
Running analyzers: 778a53015523 ...SUCCESS
Running differs: f48f462dde2f to 778a53015523...SUCCESS
Running differs: 778a53015523 to f48f462dde2f...SUCCESS
[root@tele ~]#

With this report, we can see exactly the delta between an image and its parent:

[[root@tele ~]# anchore --image devone navigate -- report

CI/CD Gates

The next step is to determine if the image is acceptable to put into production. Anchore provides mechanisms to describe gating policies that are run against each image and can be used to gate an image’s entry into production (e.g., as a step in a continuous integration pipeline).

Gate policies can include things like file content changes, properties of Dockerfiles, and presence of known vulnerabilities. To check an image against the gates, run the control —gate command. The output will show all of the gate evaluations against the image:

[root@tele ~]# anchore --image devone control --gate
+--------------+-----------------+-------------+
| f48f462dde2f | ANCHORECHECK | GO |
| f48f462dde2f | PKGDIFF | GO |
| f48f462dde2f | DOCKERFILECHECK | GO |
| f48f462dde2f | SUIDDIFF | GO |
| f48f462dde2f | USERIMAGECHECK | GO |
| f48f462dde2f | NETPORTS | GO |
| f48f462dde2f | FINALACTION | GO |
+--------------+-----------------+-------------+
[root@tele ~]#

If these statuses are all GO, then that container has passed all gates and is ready for production or further functional testing in a CI/CD system.

Aggregate Container Introspection and Search

After some time has passed and your Docker environment has accrued more developer container images, Anchore tools can be used to perform a variety of exploration, introspection and search actions over the entire set of analyzed container images.

We can search the container image space for packages, files, common packages that have been added, and various types of differences between the application containers and their Anchore curated base images. Some example queries are illustrated below.

This query shows us all images that have an installed /etc/passwd file that is different from its base image (i.e., has been modified either directly or indirectly):

[root@tele ~]# anchore --alldocker navigate --search --show-file-diffs /etc/
passwd
+--------------+-------------------+----------------+--------------+--------------+----------------------+----------------------+
| ImageId | Current Repo/Tags | Past Repo/Tags | BaseId | File | Image MD5 | Base MD5 |
+--------------+-------------------+----------------+--------------+--------------+----------------------+----------------------+
| 3ceace5b73b0 | devfive:latest | devfive:latest | 778a53015523 | ./etc/passwd | 7073ff817bcd08c9b9c8 | 60c2b408a06eda681ced |
| | | | | | cee4b0dc7dea | a05b0cad8f8a |
| c67409e321d6 | devfive:apr15 | devfive:apr15 | 778a53015523 | ./etc/passwd | 7073ff817bcd08c9b9c8 | 60c2b408a06eda681ced |
| | | devfive:latest | | | cee4b0dc7dea | a05b0cad8f8a |
+--------------+-------------------+----------------+--------------+--------------+----------------------+----------------------+
[root@tele ~]#

The next query shows all images that are currently in a STOP Anchore gate state:


[root@tele ~]# anchore --alldocker navigate --search --has-gateaction STOP
+--------------+--------------------+--------------------+-------------+
| ImageId | Current Repo/Tags | Past Repo/Tags | Gate Action |
+--------------+--------------------+--------------------+-------------+
| 3ceace5b73b0 | devfive:latest | devfive:latest | STOP |
| 55c843b5c7a3 | devthirteen:apr15 | devthirteen:apr15 | STOP |
| | devthirteen:latest | devthirteen:latest | |
| 2785fa3ab761 | devfifteen:apr15 | devfifteen:apr15 | STOP |
| | devfifteen:latest | devfifteen:latest | |
| 4e02de1e5ca5 | devtwelve:apr15 | devtwelve:apr15 | STOP |
| | devtwelve:latest | devtwelve:latest | |
| dd490a4ef2b3 | devsix:apr15 | devsix:apr15 | STOP |
| | devsix:latest | devsix:latest | |
| a7f1bb64c477 | develeven:apr15 | develeven:apr15 | STOP |
| | develeven:latest | develeven:latest | |
| b33f58798470 | devseven:apr15 | devseven:apr15 | STOP |
| | devseven:latest | devseven:latest | |
| c67409e321d6 | devfive:apr15 | devfive:apr15 | STOP |
| | | devfive:latest | |
| f48f462dde2f | devone:apr15 | devone:latest | STOP |
| | devone:latest | devone:apr15 | |
| 0f0e96f1f267 | redis:latest | redis:latest | STOP |
| 63a92d0c131d | mysql:latest | mysql:latest | STOP |
+--------------+--------------------+--------------------+-------------+
[root@tele ~]#

This last query shows us a count of common packages that have been installed in applications containers, which can be used to determine how popular certain package installations are amongst those building containers from base images:

[root@tele ~]# anchore --alldocker navigate --search --common-packages
+--------------+-------------------+----------------+-------------------+--------------------+
| BaseId | Current Repo/Tags | Past Repo/Tags | Package | Child Images w Pkg |
+--------------+-------------------+----------------+-------------------+--------------------+
| 778a53015523 | centos:latest | centos:latest | wget | 2 |
| 778a53015523 | centos:latest | centos:latest | sudo | 2 |
| 778a53015523 | centos:latest | centos:latest | gpg-pubkey | 4 |
| 44776f55294a | ubuntu:latest | ubuntu:latest | wget | 9 |
| 44776f55294a | ubuntu:latest | ubuntu:latest | ca-certificates | 9 |
| 44776f55294a | ubuntu:latest | ubuntu:latest | libssl1.0.0:amd64 | 9 |
| 44776f55294a | ubuntu:latest | ubuntu:latest | libidn11:amd64 | 9 |
| 44776f55294a | ubuntu:latest | ubuntu:latest | openssl | 9 |
+--------------+-------------------+----------------+-------------------+--------------------+
[root@tele ~]#

Container Image Visualizations

Anchore CLI tools can be used to view, inspect, search, and perform specific queries in individual container images and sets, but it is also often helpful to be able to view a container image collection graphically and to also apply coloring to indicate certain qualities of images in the visual representation. Anchore has a number of visualizations that can be generated from analysis data.

As an example, we have a visual representation of container images in a system with just 15 total application containers, with each node being colored either green, yellow or red (indicating the level of severity of a present CVE vulnerability within the container image).

This visualization can be performed at any time against the list of static container images, or against a list of images that has been derived from the set of deployed containers.