Goodbye Docker, hello Containers

3 minute read

This year, the DockerConEU took place in Copenhagen, this event was a great opportunity to learn more about containers evolution. Through a lot of very interesting talks and two keynotes (described here), we noted the following main events in the container ecosystem:

  • Kubernetes integration into Docker-Enterprise defines it as the main actor in the container orchestration domain.
  • The three big players (Google, Microsoft, Docker) work together to improve the container environment.
  • The Cloud Native Computing Foundation (CNCF) is the main actor in the OpenSource communities around containers with projects like Kubernetes, Prometheus, Fluentd, …

DockerCon2017

All these changes encourage us to focus on CNCF container standardization.

The first container standard was published by the Open Container Initiative, and the implementation reference called runc is used everywhere.

runc is a great product, unfortunately, some features are missing to become a full-featured alternative to Docker:

  • pulling images
  • images storage & container layers
  • troubleshooting containers with a docker exec equivalent
  • logs storing
  • networks creation
  • port forwarding
  • ….

Based on this situation, people from the CNCF started working on a new standard that will include the features listed above. The standard is called Container Runtime Interface (CRI) and several implementations are available:

  • dockershim: to support the old Docker solution
  • cri-containerd: to support Docker Containerd
  • cri-o: a new container solution created by RedHat
  • rkt: to support CoreOS Rocket
  • frakti: to run containers inside Virtual Machines

CRI comparison

A standard is only successful if the implementations are interchangeable. It’s a good news, switching between CRI-O and CRI-Containerd seems possible.

In the example below, we are going to use crictl, the command line interface for CRI, to pull an image and start a container on two different CRI implementations without requiring any change.

The full installation steps are not described in this article, but you can find them in this gist.

VM 1 - Start Containerd and CRI-Containerd

$ containerd &
$ cri-containerd &
$ echo "runtime-endpoint: /var/run/cri-containerd.sock" > /etc/crictl.yaml

VM 2 - Start CRI-O

$ crio &
$ echo "runtime-endpoint: /var/run/crio/crio.sock" > /etc/crictl.yaml

Both VM - Pull the redis images

$ crictl pull redis:alpine
Image is update to date for sha256:ba3df185d5ea4cae3b5da690301605ac96199732bab4edf46f7bafec43dbcb1f

$ crictl images
IMAGE                     TAG                 IMAGE ID            SIZE
docker.io/library/redis   alpine              ba3df185d5ea4       10.1MB

Both VM - Start container

CRI needs two configuration files, one for the pod and one for the container. We are going to use the following test examples:

These configurations are coming from the CRI-O repository but also work with CRI-Containerd

$ POD_ID=$(crictl runs test/testdata/sandbox_config.json)

$ CONTAINER_ID=(crictl create POD_ID test/testdata/container_redis.json test/testdata/sandbox_config.json)

$ crictl start $CONTAINER_ID
d94bf519cf7ffcacf6c689250592d0718b98d7a030d73329349d29dc560e4998

$ crictl ps $CONTAINER_ID
CONTAINER ID        IMAGE               CREATED             STATE               NAME                ATTEMPT
d94bf519cf7ff       redis:alpine        5 seconds ago       CONTAINER_RUNNING   podsandbox1-redis   0

It’s not a 100% proof that interoperability between implementations will work but it’s a good sign that it’s coming.

Standardized features

CRI provides the basic features available in Docker:

NAME:
   crictl - client for CRI

USAGE:
   crictl [global options] command [command options] [arguments...]

VERSION:
   0.2.0

COMMANDS:
     attach        Attach to a running container
     create        Create a new container
     exec          Run a command in a running container
     version       Display runtime version information
     images        List images
     inspect       Display the status of a container
     inspecti      Return the status of an image
     inspects      Display the status of a sandbox
     logs          Fetch the logs of a container
     port-forward  Forward local port to a sandbox
     ps            List containers
     pull          Pull an image from a registry
     runs          Run a new sandbox
     rm            Remove a container
     rmi           Remove an image
     rms           Remove a sandbox
     sandboxes     List sandboxes
     start         Start a created container
     info          Display information of the container runtime
     stop          Stop a running container
     stops         Stop a running sandbox
     update        Update a running container
     config        Get and set crictl options
     stats         List container(s) resource usage statistics
     help, h       Shows a list of commands or help for one command

Great solution to be continued

Container standardization progressed substantially, nevertheless additional work is still needed to reach vendor independence particularly from Docker:

  • the Dockerfile and the docker build process was part of the success of Docker. Unfortunately, the Dockerfile is not standardized, alternative implementations RedHat buildah and Docker buildkit are not 100% interchangeable.
  • the image signature is currently a nightmare: Docker signatures based on the Notary project are not recognized by RedHat CRI-O and RedHat Registry signatures are not recognized by Containerd and Docker. Recently, Docker moved the Notary project to the CNCF, we hope it will build the path to a Container Image Signature Interface that would allow to largely improve the current situation.

Written by

Romain Philibert

Container, Test and NodeJS lover

Loïc Rodier

DevOps Blacksmith

Thomas Langlois

Ops, container lover, ansible/puppet/automation addict