Convert Figma logo to code with AI

containers logocrun

A fast and lightweight fully featured OCI runtime and C library for running containers

3,109
317
3,109
33

Top Related Projects

11,985

CLI tool for spawning and running containers according to the OCI specification

An open and reliable container runtime

69,038

The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

Kata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/

Quick Overview

crun is a lightweight and fast OCI-compliant runtime for running containers. It is designed to be a drop-in replacement for the runc runtime, providing improved performance and additional features.

Pros

  • Performance: crun is designed to be faster than runc, with benchmarks showing significant performance improvements in container startup and shutdown times.
  • Compatibility: crun is fully compatible with the OCI runtime specification, allowing it to be used as a drop-in replacement for runc in most container environments.
  • Extensibility: crun is designed to be extensible, with support for additional features and functionality that can be added through plugins.
  • Security: crun includes a number of security features, such as support for seccomp and SELinux, to help protect against potential vulnerabilities.

Cons

  • Limited Documentation: The project's documentation is relatively sparse, which may make it more difficult for new users to get started with crun.
  • Lack of Widespread Adoption: While crun is gaining traction, it is not yet as widely used as runc, which may make it more difficult to find support and resources.
  • Potential Compatibility Issues: While crun is designed to be compatible with the OCI runtime specification, there may be some edge cases or specific container configurations where it may not work as expected.
  • Dependency on Libseccomp: crun relies on the libseccomp library for seccomp support, which may not be available on all systems.

Getting Started

To get started with crun, you can follow these steps:

  1. Install the necessary dependencies:
sudo apt-get install -y libseccomp-dev libapparmor-dev
  1. Clone the crun repository:
git clone https://github.com/containers/crun.git
  1. Build and install crun:
cd crun
./autogen.sh
./configure
make
sudo make install
  1. Configure your container runtime to use crun instead of runc:
# For Docker
sudo mkdir -p /etc/docker
echo '{"runtimes": {"crun": {"path": "/usr/local/bin/crun"}}}' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker

# For Podman
sudo mkdir -p /etc/containers
echo 'runtime = "/usr/local/bin/crun"' | sudo tee /etc/containers/containers.conf
  1. Verify that crun is being used:
# For Docker
docker info | grep Runtime
# For Podman
podman info | grep Runtime

You should see crun listed as the active runtime.

Competitor Comparisons

11,985

CLI tool for spawning and running containers according to the OCI specification

Pros of runc

  • Widely adopted and battle-tested in production environments
  • Extensive documentation and community support
  • Compliant with OCI (Open Container Initiative) specifications

Cons of runc

  • Written in Go, which may have higher memory usage compared to C
  • Slower startup times for containers compared to crun
  • Less flexible for embedded systems or resource-constrained environments

Code Comparison

runc (Go):

func (r *Runner) Run(config *specs.Spec, id string) (int, error) {
    container, err := r.Create(id, config)
    if err != nil {
        return -1, err
    }
    return container.Run()
}

crun (C):

int crun_run (struct crun_run_options *opts)
{
    int ret;
    libcrun_container_t *container = NULL;
    ret = libcrun_container_run (&container, opts);
    return ret;
}

Both runc and crun are low-level container runtimes, but crun is written in C, offering potentially better performance and lower resource usage. runc, being the reference implementation of the OCI runtime specification, has broader adoption and more extensive tooling support. crun aims to be a faster and more lightweight alternative, particularly suitable for systems with limited resources or requiring quick container startup times.

An open and reliable container runtime

Pros of containerd

  • More comprehensive container runtime with broader ecosystem support
  • Better suited for large-scale container orchestration (e.g., Kubernetes)
  • Extensive features including image management and networking

Cons of containerd

  • Higher complexity and resource overhead
  • Steeper learning curve for beginners
  • May be overkill for simple containerization needs

Code comparison

containerd (Go):

import (
    "github.com/containerd/containerd"
    "github.com/containerd/containerd/cio"
)

client, err := containerd.New("/run/containerd/containerd.sock")
container, err := client.NewContainer(ctx, "example")
task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))

crun (C):

#include <libcrun.h>

crun_container *container;
int ret = libcrun_container_load (&container, "config.json", NULL, 0);
ret = libcrun_container_run (container);

Key differences

  • containerd is written in Go, while crun is written in C
  • containerd offers a more extensive API and feature set
  • crun focuses on being a lightweight OCI runtime
  • containerd is better suited for complex container management scenarios
  • crun excels in simplicity and low resource usage
69,038

The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems

Pros of Moby

  • More comprehensive container ecosystem with broader functionality
  • Larger community and extensive documentation
  • Better integration with Docker-specific tools and services

Cons of Moby

  • Heavier resource footprint
  • More complex architecture, potentially harder to customize
  • Slower startup times for containers

Code Comparison

Moby (Docker) container run command:

docker run -d --name my_container -p 8080:80 nginx

crun container run command:

crun run -d --name my_container -p 8080:80 nginx

Key Differences

  • crun is a lightweight OCI runtime focused on performance and low resource usage
  • Moby (Docker) provides a full container management platform with additional features
  • crun is often used as a drop-in replacement for runc in container ecosystems
  • Moby has a more extensive CLI with numerous subcommands and options
  • crun is written in C, while Moby is primarily written in Go

Use Cases

  • crun: Ideal for embedded systems, IoT devices, or environments with limited resources
  • Moby: Better suited for complex container orchestration and management in enterprise environments

Community and Support

  • crun: Smaller but growing community, focused on performance optimization
  • Moby: Large, established community with extensive third-party integrations and support

Kata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/

Pros of kata-containers

  • Enhanced security through hardware-assisted isolation
  • Better compatibility with legacy applications
  • Support for multiple architectures and hypervisors

Cons of kata-containers

  • Higher resource overhead compared to lightweight runtimes
  • Increased complexity in setup and management
  • Potentially slower startup times for containers

Code comparison

kata-containers:

devices:
  - path: /dev/vfio/vfio
    type: c
    major: 10
    minor: 196
    fileMode: 0600
    uid: 0
    gid: 0

crun:

int libcrun_container_run (libcrun_context_t *context,
                           libcrun_container_t *container,
                           unsigned int options,
                           libcrun_error_t *err)
{
  return libcrun_container_run_internal (context, container, -1, NULL, NULL, options, err);
}

The code snippets showcase different aspects of the projects. kata-containers example demonstrates device configuration in YAML, while crun shows a C function for container execution.

kata-containers offers stronger isolation and broader compatibility at the cost of increased resource usage and complexity. crun, being a lightweight runtime, provides faster performance but with less isolation between containers and the host system.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Coverity Status CodeQL

A fast and low-memory footprint OCI Container Runtime fully written in C.

crun conforms to the OCI Container Runtime specifications (https://github.com/opencontainers/runtime-spec).

Documentation

The user documentation is available here.

Why another implementation?

While most of the tools used in the Linux containers ecosystem are written in Go, I believe C is a better fit for a lower level tool like a container runtime. runc, the most used implementation of the OCI runtime specs written in Go, re-execs itself and use a module written in C for setting up the environment before the container process starts.

crun aims to be also usable as a library that can be easily included in programs without requiring an external process for managing OCI containers.

Performance

crun is faster than runc and has a much lower memory footprint.

This is the elapsed time on my machine for running sequentially 100 containers, the containers run /bin/true:

crunrunc%
100 /bin/true0:01.690:3.34-49.4%

crun requires fewer resources, so it is also possible to set stricter limits on the memory allowed in the container:

# podman --runtime /usr/bin/runc run --rm --memory 4M fedora echo it works
Error: container_linux.go:346: starting container process caused "process_linux.go:327: getting pipe fds for pid 13859 caused \"readlink /proc/13859/fd/0: no such file or directory\"": OCI runtime command not found error

# podman --runtime /usr/bin/crun run --rm --memory 512k fedora echo it works
it works

Dependencies

These dependencies are required for the build:

Fedora

$ sudo dnf install -y make python git gcc automake autoconf libcap-devel \
    systemd-devel yajl-devel libseccomp-devel pkg-config \
    go-md2man glibc-static python3-libmount libtool

RHEL/CentOS 8

$ sudo yum --enablerepo='*' --disablerepo='media-*' install -y make automake \
    autoconf gettext \
    libtool gcc libcap-devel systemd-devel yajl-devel \
    glibc-static libseccomp-devel python36 git

go-md2man is not available on RHEL/CentOS 8, so if you'd like to build the man page, you also need to manually install go-md2man. It can be installed with:

$ sudo yum --enablerepo='*' install -y golang
$ export GOPATH=$HOME/go
$ go get github.com/cpuguy83/go-md2man
$ export PATH=$PATH:$GOPATH/bin

Ubuntu

$ sudo apt-get install -y make git gcc build-essential pkgconf libtool \
   libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev \
   go-md2man autoconf python3 automake

Alpine

# apk add gcc automake autoconf libtool gettext pkgconf git make musl-dev \
    python3 libcap-dev libseccomp-dev yajl-dev argp-standalone go-md2man

Tumbleweed

# zypper install make automake autoconf gettext libtool gcc libcap-devel \
systemd-devel libyajl-devel libseccomp-devel python3 go-md2man \
glibc-static;

Note that Tumbleweed requires you to specify libseccomp's header file location as a compiler flag.

# ./autogen.sh
# ./configure CFLAGS='-I/usr/include/libseccomp'
# make

Build

Unless you are also building the Python bindings, Python is needed only by libocispec to generate the C parser at build time, it won't be used afterwards.

Once all the dependencies are installed:

$ ./autogen.sh
$ ./configure
$ make

To install into default PREFIX (/usr/local):

$ sudo make install

Shared Libraries

The previous build instructions do not enable shared libraries, therefore you will be unable to use libcrun. If you wish to build the shared libraries you can change the previous ./configure statement to ./configure --enable-shared.

Static build

It is possible to build a statically linked binary of crun by using the officially provided nix package and the derivation of it within this repository. The builds are completely reproducible and will create a x86_64/amd64 stripped ELF binary for glibc.

Nix

To build the binaries by locally installing the nix package manager:

$ curl -L https://nixos.org/nix/install | sh
$ git clone --recursive https://github.com/containers/crun.git && cd crun
$ nix build -f nix/
$ ./result/bin/crun --version

Ansible

An Ansible Role is also available to automate the installation of the above statically linked binary on its supported OS:

$ sudo su -
# mkdir -p ~/.ansible/roles
# cd ~/.ansible/roles
# git clone https://github.com/alvistack/ansible-role-crun.git crun
# cd ~/.ansible/roles/crun
# pip3 install --upgrade --ignore-installed --requirement requirements.txt
# molecule converge
# molecule verify

Lua bindings

A Lua binding is available. See the README for more information.