Container Runtimes - OCI and LXC
Overview
OCI and LXC provide similar features for describing and constructing a container runtime.
In each case, a container is represented as a configuration file and a rootfs directory (usually together in the same directory).
Both configuration specifications are comprehensive in their support for fine grained linux container configuration.
OCI:
json configuration file format
default name is
config.jsonspecified in https://github.com/opencontainers/runtime-spec/blob/main/config.md
container launched with runc, crun, or similar runtime agent
LXC:
lxc configuration file format
default name is
config.specified in
Linux Containers - LXC - Manpages - lxc.container.conf.5
container launched with lxc-start or lxc-execute
OCI
Runtime spec release: https://github.com/opencontainers/runtime-spec/releases/tag/v1.2.1
An “OCI bundle” is a directory with a config.json file and a rootfs directory containing a root filesystem.
From a bundle, the container can be started with one of the runtime agent commands like crun or runc. The runc command is particularly lightweight while being essentially identical to crun (runc is written in C instead of Go).
config.json property overview
root: defines path to rootfs, and whether its read-only
mounts: array of mount points, with options
uidMappings, gidMappings options, implemented with mount_setattr(MOUNT_ATTR_IDMAP)
process:
terminal: true to attach a pseudo terminal to the container process’s standard streams
consoleSize: if terminal is set, specified width and height
cwd: working directory for the executable
env: environment variables
args: argv-like array of strings
process (posix):
rlimits: resource limits on the process
type: see getrlimit(2)
soft: rlim.rlim_cur
hard: rlim.rlim_max
process (linux):
apparmorProfile: name of the AppArmor profile for the process https://wiki.ubuntu.com/AppArmor
capabilities: object containing arrays that specify sets of capabilities
valid values defined in https://man7.org/linux/man-pages/man7/capabilities.7.html
properties of capabilities (capability sets): effective, bounding, inheritable, permitted, ambient
noNewPrivileges: prevents the process from gaining additional privileges
The no_new_privs article in the kernel documentation has information on
how this is achieved using a prctl system call on LinuxoomScoreAdj: adjusts the oom-killer score in [pid]/oom_score_adj
scheduler: object, describing the scheduler properties for the process
policy, nice, priority, runtime, deadline, period
selinuxLabel: specifies the SELinux label for the process
ioPriority: object. configures the I/O priority settings for the container’s processes within the process group
class, priority
execCPUAffinity: object. specifies CPU affinity used to execute the process.
user: user the process runs as
uid: user ID in container namespace
gid: group ID in container namespace
umask: umask of user
additionalGids: array of ints specifying additional group IDs
hostname, domainname: hostname and domainname in uts namespace
linux (platform-specific configuration) - many configurable properties
namespaces, cgroups, devices, network devices, sysctl, seccomp, etc.
https://github.com/opencontainers/runtime-spec/blob/main/config-linux.md
hooks: custom actions related to lifecycle
LXC
Documentation:
Introduction:
Linux Containers - LXC - Introduction
Getting Started:
Linux Containers - LXC - Getting started
Manpages:
Linux Containers - LXC - Manpages
Container configuration file format: lxc.container.conf.5
Security:
Linux Containers - LXC - Security
LXC provides templates as an option for creating a container. The “download” template is commonly used for downloading and creating a container from a set of common linux distributions. There are also some interesting templates for trying out simple container environments:
lxc-busybox: a minimal busybox environment, with busybox init for /sbin/init
lxc-oci: Create application containers from OCI images
lxc-sshd: a container that just runs sshd, no OS
lxc-local: create a container from a tarball
A container can also be created manually by populating a rootfs tree and a config file (much like an OCI bundle). The host rootfs, or portions thereof, can also be used as the container’s rootfs.
The container is started with the lxc-start or lxc-execute command.
config property overview
Some lxc example configuration settings (documented in lxc.container.conf(5)):
lxc.hook.*: hooks allow for actions to be performed at different stages of the container lifecycle
lxc.rootfs.path: a directory to use as the container's rootfs
If not specified, the host's rootfs is used.
lxc.environment: Specify an environment variable to pass into the container
lxc.idmap: for privilege separation (unprivileged containers with user namepaces)
lxc.init.cmd: default command to run when using lxc-start. defaults to /sbin/init
lxc.execute.cmd: default command to run when using lxc-execute
lxc.init.cwd: Absolute path inside the container to use as the working directory
lxc.init.uid: User ID (inside container) to use for init
lxc.init.gid: Group ID (inside container) to use for init
lxc.net: specify network interfaces (implies network namespace)
lxc.uts.name: hostname
lxc.cap.drop: drop capabilities
lxc.mount.entry: add mount points
lxc.mount.auto: specify which standard kernel file systems should be automatically mounted. Provides convenient options for specifying how to automatically mount proc, sys, and cgroup filesystems.
lxc.cgroup2.*: cgroup configuration
lxc.prlimit.[name]: Specify the resource limit to be set
lxc.proc.[proc file name]: Specify the proc file name to be set. E.g.
lxc.proc.oom_score_adj = 10lxc.sysctl.[kernel parameters name]: Specify the kernel parameters to be set
lxc.apparmor.profile: Specify the apparmor profile
lxc.selinux.context: Specify the SELinux context
lxc.seccomp.profile: Specify a file containing the seccomp configuration
lxc.no_new_privs: Specify whether the PR_SET_NO_NEW_PRIVS flag should be set for the container