Rocket (rkt)

From Bauman National Library
This page was last modified on 16 February 2019, at 17:54.
</td></tr>
rkt
Rkt logo.png
Developer(s) CoreOS
Initial release December 2014; 7 years ago (2014-12)
Stable release
1.30.0 / April 16, 2018; 4 years ago (2018-04-16)
Repository github.com/rkt/rkt
Operating system Linux, Windows, macOS
Website coreos.com/rkt

Rocket(rkt) is an application container engine developed for modern production cloud-native environments. It features a pod-native approach, a pluggable execution environment, and a well-defined surface area that makes it ideal for integration with other systems[1].

Rocket vs Docker

rkt docker
Runs Docker images Yes Yes
Image Signing Verifies signatures by default Client based; signature validation not enforced in Docker daemon
Privilege Separation Fetch, verify, validate signatures as unprivileged user All operations conducted by Docker daemon running as root
Composability Proper unix process model, manage processes with systemd, standard sysv init, runit, etc. Requires custom in-container init systems to manage child processes
Pluggable Isolation Multiple stage1 isolation environments, from chroot to cgroups to KVM - or roll your own Isolation only in terms of docker daemon options for network bridge or full privileged mode
Image Creation Container build tool based on shell scripting, leveraging familiar unix tools Build defined in Dockerfile, built by Docker daemon (as root)
Container Distribution Container images are plain tarballs, served over common HTTPS. DNS discovery of custom namespaces & signatures Docker registry. Restrictive default namespace (docker.com)

The Docker Engine, or simply Docker, is an application container runtime system that runs as a centralized API daemon. Docker can take a "Docker Image" name, such as quay.io/coreos/etcd, and download, execute, and monitor the application. Functionally, this is all similar to rkt; however, along with "Docker Images", rkt can also download and run "App Container Images" (ACIs) specified by the App Container Specification (appc).

Besides also supporting ACIs, rkt has a substantially different architecture that is designed with composability and security in mind[2].

Process model

At the time of writing, the Docker Engine daemon downloads container images, launches container processes, exposes a remote API, and acts as a log collection daemon, all in a centralized process running as root. While such a centralized architecture is convenient for deployment, it does not follow best practices for Unix process and privilege separation; further, it makes Docker difficult to properly integrate with Linux init systems such as upstart and systemd. Since running a Docker container from the command line (i.e. using docker run) just talks to the Docker daemon API, which is in turn responsible for creating the container, init systems are unable to directly track the life of the actual container process. Rocket has no centralized "init" daemon, instead launching containers directly from client commands, making it compatible with init systems such as systemd, upstart, and others.

Also you can see Container Engine Process models on picture 1.

Picture 1 – Container Engine Process Models

Privilege Separation

rkt uses standard Unix group permissions to allow privilege separation between different operations. Once the rkt data directory is correctly set up (for example, by rkt install), the container image downloads and signature verification can run as a non-privileged user.

Also you can see Privilege Separation on picture 2.

Picture 2 – Privilege Separation

rkt vs runC

runC is a low-level container runtime and an implementation of the Open Container Initiative specification. runC exposes and expects a user to understand low-level details of the host operating system and configuration. It requires the user to separately download or cryptographically verify container images, and for "higher level tools" to prepare the container filesystem. runC does not have a centralized daemon, and, given a properly configured "OCI bundle", can be integrated with init systems such as upstart and systemd.

rkt includes the same functionality as runC but does not expect a user to understand low-level details of the operating system to use, and can be invoked as simply as rkt run coreos.com/etcd,version=v2.2.0. It can download both "Docker Images" and "App Container Images". As rkt does not have a centralized daemon it can also be easily integrated with init systems such as upstart and systemd[3].

rkt vs LXC/LXD

LXC is a system container runtime designed to execute "full system containers", which generally consist of a full operating system image. An LXC process, in most common use cases, will boot a full Linux distribution such as Debian, Fedora, Arch, etc, and a user will interact with it similarly to how they would with a Virtual Machine image.

LXC may also be used to run (but not download) application containers, but this use requires more understanding of low-level operating system details and is a less common practice. LXC can download "full system container" images from various public mirrors and cryptographically verify them. LXC does not have a central daemon and can integrate with init systems such as upstart and systemd.

LXD is similar to LXC but is a REST API on top of liblxc which forks a monitor and container process. This ensures the LXD daemon is not a central point of failure and containers continue running in case of LXD daemon failure. All other details are nearly identical to LXC.

rkt can download, cryptographically verify, and run application container images. It is not designed to run "full system containers" but instead individual applications such as web apps, databases, or caches. As rkt does not have a centralized daemon it can be integrated with init systems such as upstart and systemd[4].

rkt vs OpenVZ

OpenVZ is a system container runtime designed to execute "full system containers" which are generally a full system image. An OpenVZ process, in most common use cases, will boot a full Linux Distro such as Debian, Fedora, Arch, etc and a user will interact with it similarly to a Virtual Machine image. OpenVZ can download "full system container" images from various public mirrors and cryptographically verify them. OpenVZ does not have a central daemon and can integrate with init systems such as upstart and systemd.

rkt can download, cryptographically verify, and run application container images. It is not designed to run "full system containers" but instead individual applications such as web apps, databases, or caches. As rkt does not have a centralized daemon it can be integrated with init systems such as upstart and systemd[5].

rkt vs systemd-nspawn

systemd-nspawn is a container runtime designed to execute a process inside of a Linux container. systemd-nspawn gets its name from "namespace spawn", which means it only handles process isolation and does not do resource isolation like memory, CPU, etc. systemd-nspawn can run an application container or system container but does not, by itself, download or verify images. systemd-nspawn does not have a centralized daemon and can be integrated with init systems such as upstart and systemd.

rkt can download, cryptographically verify, and run application container images. It is not designed to run "full system containers", but instead individual applications such as web apps, databases, or caches. As rkt does not have a centralized daemon it can be integrated with init systems such as upstart and systemd. By default rkt uses systemd-nspawn to configure the namespaces for an application container[6].

rkt vs machinectl

machinectl is a system manager that can be used to query and control the state of registered systems on a systemd host. These systems may be registered Virtual Machines, systemd-nspawn containers, or other runtimes that register with the systemd registration manager, systemd-machined. Among many other things, machinectl can download, cryptographically verify, extract and trigger to run a systemd-nspawn container off the extracted image content. By default these images are expected to be "full system containers", as systemd-nspawn is passed the “--boot” argument.

On systemd hosts, rkt will integrate with systemd-machined in much the same way that machinectl containers will: any pods created by rkt will be registered as machines on the host and can be interacted with using machinectl commands. However, in being more oriented towards applications, rkt abstracts the pod lifecycle away from the user. rkt also provides a more configurable and advanced workflow around discovering, downloading and verifying images, as well as supporting more image types. Unlike machinectl, rkt execs systemd-nspawn directly instead of creating a systemd service, allowing it to integrate cleanly with any supervisor system. Furthermore, in addition to namespace isolation, rkt can set up various other kinds of isolation (e.g. resources) defined in the appc specification[7].

rkt vs qemu-kvm, lkvm

qemu-kvm and lkvm are userspace tools that execute a full system image inside of a Virtual Machine using the Linux KVM infrastructure. A system image will commonly include a boot loader, kernel, root filesystem and be pre-installed with applications to run on boot. Most commonly qemu-kvm is used for IaaS systems such as OpenStack, Eucalyptus, etc. The Linux KVM infrastructure is trusted for running multi-tenanted virtual machine infrastructures and is generally accepted as being secure enough to run untrusted system images. qemu-kvm and lkvm do not have a centralized daemon and can be integrated with init systems such as upstart and systemd.

rkt can download, cryptographically verify, and run application container images. It is not designed to run "full system images" but instead individual applications such as web apps, databases, or caches. As rkt does not have a centralized daemon it can be integrated with init systems such as upstart and systemd. rkt can optionally use lkvm as an additional security measure over a Linux container, at a slight cost to performance and flexibility; this feature can be configured using the kvm (aka Clear Containers) stage1[8].

Example

Create a hello go application

package main

import (
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		log.Printf("request from %v\n", r.RemoteAddr)
		w.Write([]byte("hello\n"))
	})
	log.Fatal(http.ListenAndServe(":5000", nil))
}

Build a statically linked Go binary

Next we need to build our application. We are going to statically link our app so we can ship an App Container Image with no external dependencies.

$ CGO_ENABLED=0 go build -ldflags '-extldflags "-static"'

Before proceeding, verify that the produced binary is statically linked:

$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ ldd hello
   not a dynamic executable

Create the image

To create the image, we can use acbuild.

The following commands will create an ACI containing our application and important metadata.

acbuild begin
acbuild set-name example.com/hello
acbuild copy hello /bin/hello
acbuild set-exec /bin/hello
acbuild port add www tcp 5000
acbuild label add version 0.0.1
acbuild label add arch amd64
acbuild label add os linux
acbuild annotation add authors "Carly Container <carly@example.com>"
acbuild write hello-0.0.1-linux-amd64.aci
acbuild end

Run

Launch a local application image

# rkt --insecure-options=image run hello-0.0.1-linux-amd64.aci

Note that --insecure-options=image is required because, by default, rkt expectsour images to be signed.

At this point our hello app is running and ready to handle HTTP requests.

To stop the container, pass three escape characters (^ ]^]^]), which is generated by Ctrl -] on a US keyboard. You can also run rkt as a daemon. By default, rkt will assign the running container an IP address. Use rkt list to discover what it is:

# rkt list
UUID		APP	IMAGE NAME		STATE	NETWORKS
885876b0	hello	example.com/hello:0.0.1	running	default:ip4=172.16.28.2

Then you can curl that IP on port 5000:

$ curl 172.16.28.2:5000
hello

Sources

  1. Rocket (rkt) - Overview // CoreOS . Updated: 15.01.2018. URL: https://coreos.com/rkt (date of the application: 09.11.2018)
  2. Rocket (rkt) - rkt vs Docker // CoreOS . Updated: 23.11.2017. URL: https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-docker (date of the application: 09.11.2018)
  3. Rocket (rkt) - rkt vs runC // CoreOS . Updated: 23.11.2017. URL: https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-runc (date of the application: 09.11.2018)
  4. Rocket (rkt) - rkt vs LXC/LXD // CoreOS . Updated: 23.11.2017. URL: https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-lxclxd (date of the application: 09.11.2018)
  5. Rocket (rkt) - rkt vs OpenVZ // CoreOS . Updated: 23.11.2017. URL: https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-openvz (date of the application: 09.11.2018)
  6. Rocket (rkt) - rkt vs systemd-nspawn // CoreOS . Updated: 23.11.2017. URL: https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-systemd-nspawn (date of the application: 09.11.2018)
  7. Rocket (rkt) - rkt vs machinectl // CoreOS . Updated: 23.11.2017. URL: https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-machinectl (date of the application: 09.11.2018)
  8. Rocket (rkt) - rkt vs qemu-kvm, lkvm // CoreOS . Updated: 23.11.2017. URL: https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html#rkt-vs-qemu-kvm-lkvm (date of the application: 09.11.2018)