The Runtime Specification
This specification governs the format of the file that is passed to container runtime. Every OCI-compliant runtime will accept this file format, including runc, crun, Kata, gVisor, Railcar, etc. Typically, this file is constructed by a container engine such as CRI-O, Podman, containerd or Docker. These files can be created manually, but it's a tedious process. Instead, we are going to do couple of experiments so that you can get a feel for this file without having to create one manually.
Before we begin our experiments, you need to have a basic understanding of the inputs that go into creating this spec file:
- The container image comes with a config.json which provides some input. We inspected this file in the last section on the image specification. These inputs are a combination of things provided by the image builder (example: CMD) as well as defaults specified by the build tool (example: Architecture). The inputs specified at build time can be thought of as a way for the image builder to communicate with the image consumer about how the image should be run.
- The container engine itself also provides some default inputs. Some of these can be configured in the configuration for the container engine (example: SECCOMP profiles), some are dynamically generated by the container engine (example: sVirt/SELinux contexts, or Bind Mounts - aka the copy on write layer which gets mounted in the container's namespace), while others are hardcoded into the container engine (example: the default namespaces to utilize).
- The command line options specified by the user of the container engine (or robot in Kubernetes' case) can override many of the defaults provided in the image or by the container engine. Some of these are simple things like bind mounts (example:
-v /data:/data) or more complex like security options (example:
--privilegedwhich disables a lot of technologies in the kernel).
Being the reference implementation for the runtime specification, runc has the ability to create a very simple spec file. Let's create one and take a quick look at the fairly simple set of directives:
runc spec cat config.json | jq
Now that we have a basic understanding of the runtime spec file, lets move on to starting a container.